Verifying Chilean RUT code (tax number) in C#

In one of the projects at my work, I got task to verify some data (in migration process from old system to new one); one of the fields was Chilean RUT (Rol Único Tributario) or Tax Identification Number.

The RUT has 8 digits plus a validation number or letter (xx.xxx.xxx-z) and algorithm for verification (as per my knowledge) is as follows:

  1. Remove all characters except digits and last char which can be digit or letter “K”
  2. Pad with zeros (“0”) string until it is exactly 9 symbols long
  3. Multiply, from left to right, first 8 digits with following factors: 3, 2, 7, 6, 5, 4, 3, 2 and sum those results (let’s call it total)
  4. Find difference: 11 – (total % 11) (let’s call it rest)
  5. Determine control char by:
      5.1 If rest = 11, than control char “0” (zero)
      5.2 If rest = 10, than control char “K”
      5.3 Otherwise, rest is control char
  6. If the original control char (9th char) is equal to calculated control char, RUT is valid.

C# code for this could be like this:

/// <summary>
/// Routine for checking of RUT correctness
/// </summary>
/// <param name="rut">RUT to check</param>
/// <returns>true if RUT is valid</returns>
/// <remarks>Only numbers and optional "K" at the end of string are expected
/// </remarks>
public static bool IsRutOk(string rut)
{
    const string RutRegex = "[0-9]+K?";
    Regex RegExRut = new Regex(RutRegex, RegexOptions.Compiled | 
    RegexOptions.IgnoreCase);
    int[] coefs = {3, 2, 7, 6, 5, 4, 3, 2};

    // In case that rut is padded with spaces
    rut = rut.Trim().ToUpperInvariant();

    if (!RegExRut.IsMatch(rut)) { return false; }

    if (rut.Length > 9) { return false; }

    // If shorter than 9 characters (8 + control char) ...
    while (rut.Length < 9) { rut = "0" + rut; }

    int total = 0;

    for (int index = 0; index < rut.Length - 1; index++)
    {
         char curr = rut.Substring(index, 1).ToCharArray()[0];
         total += coefs[index]*(curr - '0');
    }

    int rest = 11 - (total%11);

    if (rest == 11) rest = 0;

    if ((rest == 10) && rut.EndsWith("K")) { return true; }

    if (rut.Substring(rut.Length - 1, 1).ToCharArray()[0] == ('0' + rest))
    { 
        return true; 
    }

    return false;
}

Web.Config and Assembly Binding problems

asp.net - Web.Config and Assembly Binding problemsIn a recent ASP.NET project, we had to replace NLog (excellent logging .Net library, by the way) assembly with newer one.

However, due to complexity of project, recompiling of all dependent assemblies was not an option. Suggested solution was simple – use assembly redirection:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="NLog"
        publicKeyToken="5120e14c03d0593c" culture="neutral" />
      <bindingRedirect oldVersion="1.0.0.0" newVersion="1.0.0.505" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

(all of this under <configuration> tag)

In a first attempt, it did not work 🙁 – assembly redirection did not happen. Even Fusion Viewer could not find anything strange – it looked like whole redirection part was simply ignored.

I looked (very simple) web.config again, carefully inspecting it; one line, at very top of the file, looked suspitious:

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

After removing name space, and leaving usual:

<configuration>

all worked as a charm.

It turns out, that due bug in Visual Studio 2005, if you used in some point the built-in web administration tool (launched via the WebSite->ASP.NET Configuration menu item) it will add this name space to root configuration element. This will cause not just to stop Intellisense working for Web.Config but also will ignore any Assembly Binding redirection instructions.

So, if you have problem with Assembly Binding redirection in your ASP.NET application, check web.config once more 🙂

Problems with Microsoft Jet OLEDB on 64bit Windows?

If you have scenario like this:

  • In your C# / VB.NET application you are using Microsoft Access database (MDF file)
  • Target machines are 64 bit machines (Vista 64 or some of the Windows Operating System flavors
  • On target machines, where you plan to deploy solution, you installed Microsoft 2007 Office System Driver: Data Connectivity Components
  • And still, you are experiencing error like this:
System.InvalidOperationException: The 'Microsoft.Jet.OLEDB.4.0' provider is 
not registered on the local machine.

Check if your application is setup for any CPU (Properties / Build / Platform target) which is default. If that is the case, change it to x86 – at the moment, there are no 64bit drivers for Microsoft Office, so only 32bit applications will work as expected.

Transliteration easy way – Microsoft Transliteration Utility

If you are lucky enough 🙂 to have not one, but two alphabets in daily use, your regular task in programming will be transliteration – transformation of text from one script (alphabet) to another.

In Serbia, we are using Latin as well as Cyrillic alphabet (and that is not same Cyrillic as Russian one) and common task is conversion from one to another and vice-versa.

This is not too complicated request; you can easily create necessary procedures; however, there is a better way:

Microsoft Transliteration Utility (MTU) is not widely known, but very useful tool for just that purpose: transliteration. It can easily transliterate text either typed in a text box or from one file to another.

There is set of predefined translations:

  • Serbian Cyrillic to Latin / Serbian Latin to Cyrillic
  • Bosnian Cyrillic to Latin / Bosnian Latin to Cyrillic
  • Hangul to Romanization
  • Inuktitut to Romanization / Romanization to Inuktitut
  • Malayalam to Romanization / Romanization to Malayalam

You are not limited to above set; you can easily create your own translations, using Module Development Console:

Microsoft Transliteration Utility - Module Development Console
(click on image for larger version)

Creating simple textual file, you can use full power of MTU’s parsing engine: definitions of input and output characters, rules for transliteration including definitions of new states for translation state machine.

This is not the end – you can even use MTU programmatically (although please check EULA for commercial usage):

  • Add reference to MSTranslitTools.DLL (it can be found in %programfiles%Microsoft Transliteration Utility)
  • Add using System.NaturalLanguage.Tools;
  • Current translation files (.tms) can be found in %CommonProgramFiles%TransliterationModulesMicrosoft
  • Here is simple code fragment to demonstrate:
TransliteratorSpecification specification =
   TransliteratorSpecification.FromSpecificationFile("Serbian Latin to Cyrillic.tms");

Transliterator transliterator = Transliterator.FromSpecification(specification);
string rezultat = transliterator.Transliterate("Vesic.Org");

Console.WriteLine(rezultat);

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 🙂 )

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.

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!

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

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
		  );
}            

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.