Freecom Network Drive Pro 500 Gb – a sad story

Freecom Network Drive Pro 500 Gb - good idea, terrible software and supportFor purposes of my home network, I needed small, decent file server which would be on all the time and serve as a central point for rest of the machines.

After researching (and checking availability here in Serbia), Freecom Network Drive Pro 500 Gb looked as a more than correct solution: it is not just a file server, it is also web server, ftp server, and basically mini Linux machine – it has even torrent client.

I could not wait to get unit – as all geeks, I adore good piece of hardware :-)

It looked as promised – nice, compact aluminum unit, with web administration interface; it stated that current firmware is 4.2.7

Unit was connected to network via LinkSys WAG325N and I start experimenting. At first, all seemed ok (apart from unit freezing once). Than I started with more serious tasks – created couple of network shares and started copying files from/to ND Pro 500 from Windows based (XP, Vista) stations, via Explorer, Total Commander and couple of file/backup oriented applications.

Than it happened: file on ND Pro 500 was different (!!!) than source file on local PC in a “special” case:

  • Copy file from PC to ND Pro 500; note size
  • Make file on PC shorter (for example, if text is in question, remove couple of characters or lines)
  • Copy new version of file from PC to ND Pro 500

File on ND Pro 500 will retain old size and content of file will be: new version content + rest of the bytes from old file version; or, in other words, unusable, which you usualy do not expect from (not-so-cheap) consumer unit to do; at least, file server should protect my data instead of corrupting them.

I started usual route; wrote to Freecom support (30th November) as well as posted message in OpenFSG forum – forum which appears on administrative pages of Network Drive Pro 500. I was not happy seeing that load of users have similar problems.

What is often case these days, it seems that need for quality drivers/firmwares in neglected in favor of “sell, sell, sell and majority of byers won’t even notice that this does not do what is promised”.

I got no response from support. Call them on phone; they stated that they never heard for this (well, for what is OpenFGS forum than?) and that I should write them again. Did that. Forwarded mail and just get “forwarded to R&D, awaiting their response”.

Nothing.

Then they asked for my phone (06th December), I gave my mobile.

Nothing. Zilch. Nada.

After a couple of days (10th December) I decided that this is enough – just returned whole unit and took full refund back. To be honest: I do not expect that someone make firmware correction in two days; I know software production very well – make change, build, test, correct problems, build, test … But I did expect that someone:

  • Contact me
  • Confirm findings
  • Give decent estimate when new firmware will be out

My advice: do not buy units from Freecom; maybe their idea is great, but realization is not and support is close to none; and those products should take care of most important stuff in electronic world – your data.

Or, if you are brave enough :-) check forums first and firmware version second – you can save a lot of frustrations.

(Note: all above goes for Windows clients; apparently, there are no such problems if your client is Mac or Linux)

10.12.2007

Hardware

Dejan VesićComments (16)

How to read .ai (Adobe Illustrator) file w/o Illustrator

Read .ai files with Ghostscript and XnViewIf you ran to .ai file which is Adobe Illustrator file, and you do not have Illustrator installed anywhere near, try this:

  1. Download and install latest Ghostscript package
  2. Download and install latest XnView
  3. Use XnView to open .ai file and to save it as other (more common) image format

That should do the trick (it did for me).

5.12.2007

Programs

Dejan VesićComments (1)

VPN, Remote Desktop, Vista and MTU

LinkSys WAG325NMy home network is rather small: two desktop machines and one laptop. Access to outside world is done via usual ADSL connection. Bridge between two worlds was some unknown ADSL router connected to (good old) LinkSys WRT54G with custom DD WRT firmware; all work was done here: firewall, port forwarding, dhcp …

This combination was good, but not the best – main obstacles were having two devices instead of one (WRT54G has no ADSL port) and no VPN directly to offices where I work.

Recently, I replaced WRT54G with newer model: LinkSys WAG325N: ADSL port, 4 LAN ports, 802.11 a/b/g wireless and experimental (draft) implementation of 802.11n wireless protocol. Best of all, up to 5 VPN channels directly from router, so all machines can use VPN tunnel w/o problems.

After seting up VPN, access to business machines was just fine from desktop machines. However, that was not the case for laptop, which is using wireless connection.

Using Remote Desktop from laptop, I would see initial black or blue screen of remote computer (w/o login box) and after couple of minutes, Remote Desktop session would die.

After considerable time spend on Google (and with great help of our system administrator Nemanja), I found possible problem: size of MTU or Maximum Transmition Unit – size of the largest packed allowed on particular network.

Default size set by Windows Vista was 1500 and that was enought not to establish Remote Desktop connection over VPN. In Vista, you can check settings by going in Command Prompt and typing:

netsh interface ipv4 show subinterfaces

and you will get something like:


  MTU  MediaSenseState   Bytes In  Bytes Out  Interface
------  ---------------  ---------  ---------  -------------
4294967295          1          0       7127  Loopback Pseudo-Interface 1
1500                1     145661      51022  Wireless Network Connection
1500                5          0          0  Local Area Connection
1500                5          0          0  Bluetooth Network Connection

Now, you can change MTU for particular interface:

netsh interface ipv4 set subinterface "Wireless Network Connection" mtu=1440 store=persistent

(make sure that you are doing this from elevated Command Prompt, i.e. CMD started using right-click and option “Run as Administrator“) and that will sort out any Remote Desktop connection problems.

15.11.2007

Networking,Vista

Dejan VesićComments (4)

Upgrade of Application/User Settings between application versions

One of the polished areas of .Net Framework 2.0 is manipulation with Application/User settings in WinForms applications. You can store almost anything in appropriate app.config or user.config file, and to manipulate with those settings with ease – wrapper class created around Settings allows you to use settings as just another field in your code.

But, what about of upgrade existing settings once when you create new version of the application?

That is supported via Upgrade() method:


	 Settings.Default.Upgrade();
	 Settings.Default.Save();

You can add one user bool setting (for example UpgradeSettings) with default value True, which will be a flag if upgrade is carried out; code can be:


	if (Settings.Default.UpgradeSettings)
	{
		 Settings.Default.Upgrade();
		 Settings.Default.UpgradeSettings = false;
		 Settings.Default.Save();
	}

Suppose that your application is simple little application, not a Click-Once or even distributed with installer – just archive which users can download, unpack and start using.

If you new version picks user settings folder from previous one, all is fine – Upgrade() method will find previous version and upgrade them:

Application versions - as expected

Suppose that this is true:

  • both versions are either signed or not (if you do signing of assembly between versions, Upgrade will fail)
  • both versions are either Click-Once applications or not (for the same reasons)

In theory, all is fine and Upgrade should do the job. But, what if all above is fulfilled and that you still have different user settings folder:

Application versions - mismatch

What can be reason that same application creates completely different user settings folder? This situation happened to me. After couple of hours, I could not determine reason, so I pulled out heavy tools – Reflector.

If you start tracking .Upgrade(), it goes to: ApplicationSettingsBase.Upgrade which simply calls IApplicationSettingsProvider.Upgrade for each provider present. For simple WinForms application, appropriate provider is LocalFileSettingsProvider. After some more thorough analysis, internal method for determining folder of settings store is:

System.Configuration.ClientConfigPaths

One of elements in determining local store for user settings was hashed value derived from Evidences for given assembly.

It turns out that one of Evidence elements for non-signed assemblies is path from where assembly/application is launched!.

To summarize: in order for Upgrade() of settings succeed, your new version of application should be deployed in the exact same folder where previous version is found; otherwise, Upgrade() will fail (or at least, it won’t do what you expected :-) )

31.7.2007

.Net,C#,WinForms

Dejan VesićComments (1)

Breaking changes for language codes in KB928365, KB928366

.Net FrameworkSome security updates are not just security updates.

If you installed (or you have Automatic Update turned on) yesterday’s updates:

  • KB928365 – Security update for the .NET Framework 2.0 for Windows Server 2003, Windows XP, and Windows 2000
  • KB928366 – Security update for the .NET Framework 1.1 for Windows XP and Windows 2000

you will get security update (nice) and breaking changes (not so nice) regarding some of the languages in the framework. More precise, some of specific cultures changed their codes:

LCID Old code New code Old / New description
2074 sr-SP-Latn sr-Latn-CS Serbian (Latin, Serbia and Montenegro) /
Serbian (Latin, Serbia)
3098 sr-SP-Cyrl sr-Cyrl-CS Serbian (Cyrillic, Serbia and Montenegro) /
Serbian (Cyrillic, Serbia)
1068 az-AZ-Latn az-Latn-AZ Azeri (Latin, Azerbaijan)
1091 uz-UZ-Latn uz-Latn-UZ Uzbek (Latin, Uzbekistan)
1025 div-MV dv-MV Divehi (Maldives)
2092 az-AZ-Cyrl az-Cyrl-AZ Azeri (Cyrillic, Azerbaijan)
2115 uz-UZ-Cyrl uz-Cyrl-UZ Uzbek (Cyrillic, Uzbekistan)
7194 sr-BA-Cyrl sr-Cyrl-BA Serbian (Cyrillic) (Bosnia and Herzegovina)
5146 bs-BA-Latn bs-Latn-BA Bosnian (Bosnia and Herzegovina)
6170 sr-BA-Latn sr-Latn-BA Serbian (Latin) (Bosnia and Herzegovina)
9225 en-CB en-029 English (Caribbean)

(this Caribbean change looks very suspicious, but code says so)

Those changes will cause you problems if you have satellite assemblies for given languages in your application – after client installs update(s), those translations will simply cease to work – recompile and distribution of new ones is mandatory.

I appreciate updates but some sort of warning or information on official patch pages would be, at least, nice.

11.7.2007

.Net,i18n

Dejan VesićComments (0)

How to render Html content into JPG/JPEG image in best quality (WinForms)

How to save Html to JPG/JPEG Image and how to save it in best quality?

On recent project, I had a tasks to:

  1. Save result of Html page to JPG image
  2. To do that in best possible quality

Both tasks sounds trivial, but I did not find quite satisfying solutions, so, I came up with one bellow.

First, you need WebBrowser control – it is basicaly wrapper around ActiveX Internet Explorer interface.

Once when Html content is ready (local or remote), ask control to call your procedure upon completion:

webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);

and start render your content:

webBrowser1.Navigate( UriToRender )

In DocumentCompletedEventHandler, call your routine for rendering content to image:

void webBrowser1_DocumentCompleted(object sender,
WebBrowserDocumentCompletedEventArgs e)
{
  if( GetImageFromHtml(currentFile, webBrowser1) )
  {
     toolStripStatusLabel1.Text = "Image saved.";
  }
  else
  {
     toolStripStatusLabel1.Text = "Sorry, there was problem with saving.";
  }
}

And here is code for rendering Html to image:

/// <summary>
/// Method for saving Html content into image
/// </summary>
/// <param name="imageName">File name of image</param>
/// <param name="webBrowser">Target WebBrowser control to query for content</param>
/// <returns>True if save was succesfull</returns>
/// <seealso cref="System.Windows.Forms.WebBrowser" />

public bool GetImageFromHtml(string imageName, WebBrowser webBrowser)
{
  if (webBrowser.Document == null)
  {
     return false;
  }

  Cursor current = Cursor;
  Cursor = Cursors.WaitCursor;

  // Give time to WebBrowser control to finish rendering of document
  Thread.Sleep(200);

  try
  {

     // save old width / height
     Size originalSize = new Size(webBrowser1.Width, webBrowser1.Height);

     // Change to full scroll size
     int scrollHeight = webBrowser.Document.Body.ScrollRectangle.Height;
     int scrollWidth = webBrowser.Document.Body.ScrollRectangle.Width;

     Bitmap image = new Bitmap(scrollWidth, scrollHeight);
     webBrowser.Size = new Size(scrollWidth, scrollHeight);

     // Draw to image
     webBrowser.DrawToBitmap(image, webBrowser.ClientRectangle);
     webBrowser.Size = originalSize;

     // Old one with bad quality:
     // image.Save(imageName, ImageFormat.Jpeg);

     // Save in full quality
     SaveJPG(image, imageName, 100);

     return true;
  }

  catch { return false; }

  finally {  Cursor = current; }
}

Usual Image.Save method saves image in number of formats; however, quality is some default (bad) quality; and I needed more control over it. So, here are methods which allow that kind of control:

/// <summary>
/// Gets codec info by given mimeType
/// </summary>
/// <param name="mimeType">mimeType to lookup for</param>
/// <returns>ImageCodecInfo if all ok or null</returns>

public static ImageCodecInfo GetCodecInfo(String mimeType)
{
  ImageCodecInfo[] encoders;
  encoders = ImageCodecInfo.GetImageEncoders();
  for (int iterator = 0; iterator < encoders.Length; ++iterator)
  {
     if (encoders[iterator].MimeType == mimeType)
        return encoders[iterator];
  }
  return null;
}

/// <summary>
/// Save an Image to JPEG with given compression quality
/// </summary>
/// <param name="image">Image to save</param>
/// <param name="imageName">File name to store image</param>
/// <param name="quality">Quality parameter: 0 - lowest quality, smallest size,
/// 100 - max quality and size</param>
/// <returns>True if save was succesfull</returns>

public static bool SaveJPG(Image image, string imageName, long qual)
{
  EncoderParameters eps = new EncoderParameters(1);
  eps.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qual);
  ImageCodecInfo ici = GetCodecInfo("image/jpeg");

  if(ici == null) { return false; }

  image.Save(imageName, ici, eps);
  return true;
}

Now you can select jpeg image quality and render html the way you like.

Digg!

28.2.2007

.Net,Drawing,WinForms

Dejan VesićComments (3)

VS 2005 SP1 Installation Nightmare :-( … and how to wake up

Visual Studio 2005 SP1As you probably know, long awaited Visual Studio 2005 SP1 is out.

However, installation of this giant (400+ Mb) update is far from easy, and it is not guaranteed to succeed, at least at first run.

  1. You need to have a LOT free space on your system drive: at least 3 Gb
  2. Make sure that you have enough patience – it can take between 10 minutes and 1,5 hour
  3. If you do not use C++ portion of Visual Studio, deinstall it before installation of SP1 – it can save a lot of installation time.
  4. Deinstall Web Application Project if you have it installed.
  5. Deinstall Visual Studio 2005 Web Deployment Projects if you have it installed.
  6. Deinstall Visual Studio 2005 SP1 beta

Finally, you can speed up installation process by:

Disabling Patch Cache

Create CMD file with following content:
reg export HKLM\Software\Policies\Microsoft\Windows\Installer installer.reg
reg add HKLM\Software\Policies\Microsoft\Windows\Installer /v MaxPatchCacheSize /t REG_DWORD /d 0 /f
net stop msiserver
start /wait VS80sp1-KB926601-X86-ENU.exe
reg delete HKLM\Software\Policies\Microsoft\Windows\Installer /v MaxPatchCacheSize /f
reg import installer.reg
net stop msiserver
del /q installer.reg 2>nul

and save it in folder where SP1 is. Run it – it should cut down installation time significantly.

Ok, you succeeded to do all above, and installation is failing. What next?

Error 1718

Let assume that your operating system is XP SP2. If you got during installation this error:

Error 1718. File was rejected by digital signature policy

try recipe from this location:

http://support.microsoft.com/kb/925336 – this helped with installation on two locations where it failed previously.

I have Windows Server 2003 SP1 and unfortunately, neither of solutions (disable patch cache or KB925336) helped :-(

I though that memory upgrade will help, so I added 1Gb to total of 2Gb – no luck.

You can also try to:

Disable SAFER check for local administrators

- Note (if exist) previous value of PolicyScope at:

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\windows\safer\codeidentifiers

- Set this value (or create it as DWORD if does not exist) to 1

- Run net stop msiserver

- Try SP1 install

- Revert PolicyScope to previous value / delete it after installation.

(this helped on two other Windows 2003 SP1 machines; again, not on mine)

Finally, I decided to:

Slipstream SP1 into Visual Studio 2005 and reinstall it

There are couple steps here:

Make Network Installation

Create network administrative installation from your VS 2005 DVD (assuming that E: is DVD and location where you want installation \\dvesic\public\VisualStudio2005SP1):

msiexec.exe /a E:\vs\vs_setup.msi TARGETDIR=\\dvesic\public\VisualStudio2005SP1 /L*vx install.log

I did this all on same machine, using mounted ISO image on a virtual drive and unpacking it at network location on same machine – it took over 2 hours to create network install

Unpack the Patch

Original EXE file is just wrapper around MS Patch file. You can unpack it using some unzip utility (or Total Commander) or by executing:

VS80sp1-KB926601-X86-ENU.exe /extract .

Patch Network Install

Finally, do the patching of installation:

msiexec.exe /a \\dvesic\public\VisualStudio2005SP1\vs_setup.msi /p VS80sp1-KB926601-X86-ENU.msp /L*vx patch.log

Reinstall Visual Studio 2005 SP1

I hope that at least some of this will help you too.

Reference links:

http://weblogs.asp.net/jgalloway/…/things-i-wish-i-d-known-before-i-installed-vs-2005-service-pack-1.aspx

http://blogs.msdn.com/heaths/…/save-time-and-space-for-vs-2005-sp1-by-disabling-the-patch-cache.aspx

http://blogs.msdn.com/heaths/…/slipstreaming-visual-studio-2005-service-pack-1.aspx

http://blogs.msdn.com/heaths/…/Enabling-Large-Patches-to-Install.aspx

Update 12th May 2007

There is update availabile which will hopefully sort this problems out on easy way.

Digg!

26.12.2006

Installation,Visual Studio 2005

Dejan VesićComments (4)

Visual Studio 2005 SP1 is out!

Visual Studio 2005 SP1
Visual Studio 2005 SP1 is finally released.

Apart from bugfixes and corrections, Service Pack 1 also provides over 70 improvements for common development scenarios including:

  • New processor support (e.g., Core Duo) for code generation and profiling
  • Performance and scale improvements in Team Foundation Server
  • Team Foundation Server integration with Excel 2007 and Project 2007
  • Tool support for occasionally connected devices and SQL Server Compact Edition
  • Additional support for project file based Web applications
  • Windows Embedded 6.0 platform and tools support

However, this is not final solutions for developers working on Vista operating system :-(

More info here: http://msdn.microsoft.com/vstudio/support/vs2005sp1/

Download (of hefty 432 MB) is here:
http://www.microsoft.com/downloads/details.aspx?familyid=BB4A75AB-E2D4-4C96-B39D-37BAF6B5B1DC

15.12.2006

Visual Studio 2005

Dejan VesićComments (1)

When SQL Express 2005 SP1 Upgrade does not succeed …

I was trying to do upgrade of SQL Express 2005 to SP1 version on one of development machines.

Each time, attempt failed with not-so-helpful-message:

SQL Server Setup did not have the administrator permissions required to rename a file: C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Template Data\mssqlsystemresource1.ldf. To continue, verify that the file exists, and either grant administrator permissions to the account currently running Setup or log in with an administrator account. Then run SQL Server Setup again.

Quick Google did the trick: solution was described in KB 918693 (to be precise: workaround).

However, at first glance, I failed to execute workaround – there are couple of errors in mentioned article:

1. If typing SQLCMD do not connect to local instance of SQL 2005 Express, try with full name of instance:

SQLCMD COMPUTER_NAME\SQLEXPRESS

2. “beautified” quotes in article’s code won’t exactly help; so, if you want quick copy / paste, use code from here:

EXEC sp_configure 'user instances enabled',0
GO
RECONFIGURE
GO

3. Step three, apart from quotes, has one column name wrong, so again, use this code:

SELECT owning_principal_name, instance_pipe_name
FROM sys.dm_os_child_instances WHERE heart_beat = 'alive'
GO

4. And here is script for final step, after reinstallation:

EXEC sp_configure 'user instances enabled',1
GO
RECONFIGURE
GO

BTW, how can I report errors spotted in KB article to Microsoft? Anyone?

6.12.2006

Database,Installation

Dejan VesićComments (0)

How to make Windows Form app truly Full Screen (and to hide Taskbar) in C#?

One of sound-like-simple questions is “how to make your application truly Full Screen” i.e. not showing Taskbar or anything like that.

Initial approach is obvious:


    targetForm.WindowState = FormWindowState.Maximized;
    targetForm.FormBorderStyle = FormBorderStyle.None;
    targetForm.TopMost = true;

Does it work? Well, sort of. If your Taskbar have default setting unchecked for “Keep the taskbar on top of other windows”, this will present your application in all it’s glory all over screen estate.

However, if the Taskbar is set to appear on top of all others, this won’t help – your application won’t cover it.

Let’s go further – next step is to use P/Invoke and to engage Win32 API services. There is easy way to hide particular window. So, find the Taskbar and hide it:


    private const int SW_HIDE = 0;
    private const int SW_SHOW = 1;

    [DllImport("user32.dll")]
    private static extern int FindWindow(string className, string windowText);
    [DllImport("user32.dll")]
    private static extern int ShowWindow(int hwnd, int command);

    int hWnd = FindWindow("Shell_TrayWnd", "");
    ShowWindow(hWnd, SW_HIDE);

    targetForm.WindowState = FormWindowState.Maximized;
    targetForm.FormBorderStyle = FormBorderStyle.None;
    targetForm.TopMost = true;

(you need to add using System.Runtime.InteropServices;)

Is this better? In theory yes – Taskbar is hidden, but your application still does not occupy whole screen – place where Taskbar was is not used.

Real and proven solution is to make request to WinAPI that your form take whole screen estate – Taskbar will hide itself in that case. Full information about that can be found in KB Article Q179363: How To Cover the Task Bar with a Window and here is the code:


/// <summary>
/// Selected Win AI Function Calls
/// </summary>

public class WinApi
{
    [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
    public static extern int GetSystemMetrics(int which);

    [DllImport("user32.dll")]
    public static extern void
        SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter,
                     int X, int Y, int width, int height, uint flags);        

    private const int SM_CXSCREEN = 0;
    private const int SM_CYSCREEN = 1;
    private static IntPtr HWND_TOP = IntPtr.Zero;
    private const int SWP_SHOWWINDOW = 64; // 0x0040

    public static int ScreenX
    {
        get { return GetSystemMetrics(SM_CXSCREEN);}
    }

    public static int ScreenY
    {
        get { return GetSystemMetrics(SM_CYSCREEN);}
    }

    public static void SetWinFullScreen(IntPtr hwnd)
    {
        SetWindowPos(hwnd, HWND_TOP, 0, 0, ScreenX, ScreenY, SWP_SHOWWINDOW);
    }
}

/// <summary>
/// Class used to preserve / restore state of the form
/// </summary>
public class FormState
{
    private FormWindowState winState;
    private FormBorderStyle brdStyle;
    private bool topMost;
    private Rectangle bounds;

    private bool IsMaximized = false;

    public void Maximize(Form targetForm)
    {
        if (!IsMaximized)
        {
            IsMaximized = true;
            Save(targetForm);
            targetForm.WindowState = FormWindowState.Maximized;
            targetForm.FormBorderStyle = FormBorderStyle.None;
            targetForm.TopMost = true;
            WinApi.SetWinFullScreen(targetForm.Handle);
        }
    }

    public void Save(Form targetForm)
    {
        winState = targetForm.WindowState;
        brdStyle = targetForm.FormBorderStyle;
        topMost = targetForm.TopMost;
        bounds = targetForm.Bounds;
    }

    public void Restore(Form targetForm)
    {
        targetForm.WindowState = winState;
        targetForm.FormBorderStyle = brdStyle;
        targetForm.TopMost = topMost;
        targetForm.Bounds = bounds;
        IsMaximized = false;
    }
}

Code for example application is here: MaxWinForm.zip

3.12.2006

.Net,C#,WinForms

Dejan VesićComments (45)

Error when executing .MSI (Installer) package

MSI Error due to insufficient read rightsWhen you are starting installation of some package via MSI, and if you ran into error like this:

Error reading from file _full_path_to_msi_package. Verify that the file exists and that you can access it.

check that Local System account has read access over containing folder and .msi file itself.

First phase of installation starts under your account, so it will start as expected, but in some moment, one phase is executed via Windows Installer service, which in turn works under Local System account.

29.11.2006

Installation

Dejan VesićComments (2)

How to find out Volume Serial Number / CPU info

One of the techniques used when you plan to protect your valuable intellectual property :) (your code) is reading some kind of hardware signature of machine where program is installed.

Usual initial approach is to read Volume serial number (bear in mind that this number can be easily changed) or similar hardware information. Here is where WMI – Windows Management Instrumentation comes in play – you can find enormous amount of information using WMI.

Let’s give small example – find out Volume Serial Number:

- add reference to System.Management.dll
- here is the code:


using System;
using System.Collections.Generic;
using System.Text;
using System.Management;

namespace Org.Vesic.WMI.Example
{
    class Program
    {
        static void Main(string[] args)
        {
            string targetVolume = "C";

            if((args != null) && args.Length > 0)
            {
                targetVolume = args[0];
            }

            string mngObject = String.Format("Win32_LogicalDisk.DeviceID=\"{0}:\"",
                                             targetVolume);
            try
            {
                ManagementObject myDisk = new ManagementObject(mngObject);
                PropertyData myDiskProp = myDisk.Properties["VolumeSerialNumber"];

                Console.WriteLine("HDD Serial for Volume {0}: is {1}",
                                  targetVolume, myDiskProp.Value);
            }

            catch(ManagementException ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}

Simple and very effective. Of course, you can read load of other data types, NIC info, even CPU info:


ManagementObjectSearcher mos = new ManagementObjectSearcher
	 ("SELECT Name, L2CacheSize, L2CacheSpeed FROM  Win32_Processor");

ManagementObjectCollection moc = mos.Get();

int procCount = -1;

foreach (ManagementObject mob in moc)
{
	 procCount++;
	 Console.WriteLine("Processor No. {0}: {1}, L2 Cache size/speed: {2} / {3}",
		  procCount,
		  mob.Properties["Name"].Value,
		  mob.Properties["L2CacheSize"].Value,
		  mob.Properties["L2CacheSpeed"].Value
		  );
}

23.11.2006

.Net,C#,WMI

Dejan VesićComments (0)

Scripting Man’s best friend – PowerShell

In the world of GUI, at the heart, I am still scripting / command line / shell man.

No matter how GUI application is built, there can be no efficiency and repeatability like in a powerful, versatile script.

In the beginning, there was DOS. Than simple Command processor of Windows 95/98 (I resisted of installing Windows ME, thank God for that). Than, enlightenment – JP‘s 4Dos (retired) and 4NT – the way CMD should be from start. 4NT was breakthrough in my productivity – backup, maintenance, monitor scripts; processing of folders and files; automating each and every boring repeatable action. Add on top of that AWK for really complicated stuff and there was no problem without solution.

Microsoft was aware about all of shortcomings of CMD shell and tried to overcome them introducing Windows Scripting Shell; however, that approach simply was not successful.

Than MS started to work on Microsoft Shell or MSH (codenamed Monad), and first public beta was in September 2005. Finally, they renamed it to Windows PowerShell and build one of the most powerful scripting system for all kinds of tasks – from simple file operations to management of domains and networks. With PowerShell you can manage files, folders, remote locations, registry items, COM objects …

Let’s see how dir command does both in PS and CMD:

PowerShell dir command

What is the difference? (apart from obvious: colors and different way of displaying information) Real difference is that result of the CMD dir command are lines of text and result of PS dir command are objects; objects which you can query for attributes and to decide what to do next based on attribute values.

  • Commands are not text-based – they deal with objects
  • Command family is extensible – native binary commands, cmdlets (pronounced command-lets) can be augmented by cmdlets that you create

For example, to find out all properties of objects returned with dir, execute:
dir | get-member

By the way, dir is not real name for cmdlet – it is just an alias:

PowerShell Get-Alias dir

You can create your own aliases using the Set-Alias cmdlet.

Just one important thing if you plan to dive into PowerShell scripts world:

In order to create and use scripts, instead of just inline commands, you need to deal with security. More info can be obtained with
* get-help about_signing | more
* get-help Set-AuthenticodeSignature -detailed | more

(or redirect this to file and read afterwards)

(basic help can be obtained for any cmdlet with “-?“; detailed help can be obtained with “get-help cmdlet-name“)

Almost forgot – real reason for this post was that PowerShell reached version 1.0 and it is availabile for download.

16.11.2006

.Net,PowerShell,Scripting

Dejan VesićComments (1)

Validation of input elements and Form Closing

One of very often questions ask by WinForms developers is “How to make sure that if Form is Closing, no validation occurs in contained controls”?

For reference, validating input is rather straightforward:

1. Add ErrorProvider to Form
2. For control in question, add handlers for Validating and Validated events:


        private void tbFixPath_Validating(object sender, CancelEventArgs e)
        {
            if (!ControlValidated(tbFixPath.Text))
            {
                // Cancel the event and select the text to be corrected by the user.
                e.Cancel = true;
                tbFixPath.Select(0, tbFixPath.Text.Length);

                // Set the ErrorProvider error with the text to display.
                this.errorProvider1.SetError(tbFixPath,
                   "Sorry, something went wrong during validation. Please check.");
            }
        }

        private void tbFixPath_Validated(object sender, EventArgs e)
        {
                // After successful validation, clear error message.
                errorProvider1.SetError(tbFixPath, "");
        }

3. Everything is fine, until user tries to close form where some input elements are not validated – closing will fail. In order to prevent this, if you are absolutely sure that you want to close such form, just add:


        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
                e.Cancel = false;
        }

so that no cancellation of closing event will occur.

I know that this is basic :-) but after I was ask for 10th time in 6 months, I figured that is better to note this somewhere :-)

15.11.2006

.Net,C#,WinForms

Dejan VesićComments (3)

Firebird reaches 2.0 milestone

Firebird 2.0

Databases are very important in my area of work; as a simple storage (but rarely), as a smart relational actor in the game or even as replacement for application server, holding mass of business logic rules.

There are more and more very free and very powerful databases on database market. Some are completely free, and some are “entry” models for big guys. Whatever reasons are, they make developer life much, much easier.

One of my favorite free databases is Firebird – and it reached very important milestone: version 2.0. There is long list of enhancements, but to mention just some:

  • Table size is no longer limited to 30 Gb
  • Password encryption now uses a more secure password hash calculation algorithm (SHA-1), encryption becomes entirely server-based and password login is now required from any remote client
  • new interface for plugging in international character sets, including enhanced Unicode support, along with a number of new and corrected collations

Download link: http://www.firebirdsql.org/index.php?op=files&id=engine_200

Let me mention other favorites:

Microsoft

MS SQL Server Express 2005 along with free management tool: SQL Server Management Studio Express – fast and sleek combination for rapid development under .Net 2.0 environment. There are of course limitations, but for most small and middle project this will work just fine.

Also, if you are using older version of SQL 2000 or lite version called MSDE please consider migrating to sQL 2005 – SQL 2000 family won’t be supported on Vista.

Oracle

Oracle Database 10g Express Edition – lite version of “big” Oracle 10g. Perfect companion is Quests’s TOAD Free.

Database

Dejan VesićComments (0)

« Previous PageNext Page »