Archive

Archive for May, 2011

Passing parameters collected in dialog to Custom Action in msi C#

May 14th, 2011 Comments off

I was a little lost to why the dialog boxes I was adding to my windows installer msi was not being passed to my custom action.

There is a very simple item that I overlooked, and that is you must specify what values you want sent to your custom action.

On the properties of the custom action, there is a property called CustomActionData.

The format of this properties is:

/ParamName1=”[DIALOGPROPERTY1]” /ParamName2=”[DIALOGPROPERTY2]” …. etc

Custom Action Properties

Custom Action Properties

Then to use the parameters you will use the following code:

string sqlServer = Context.Parameters["ParamName1"];
string username = Context.Parameters["ParamName2"];
string password = Context.Parameters["ParamName3"];

C# Determine if 64bit or 32bit OS Version

May 14th, 2011 1 comment

I have had an issue where I needed to determine if the executing windows os version was either 32bit or 64bit, and as you can execute a 32bit process on a 64bit system this is a little more difficult then first thought to achieve.

The other condition that this class must have is to execute on all versions of windows and not rely on something that will only execute above a certain version.

After some digging around on google, I found this question on StackOverflow, that went into quite some detail about the different methods that work and will not work. I would suggest a read so you understand the implications of different implementations.

I have settled for a class that has been built around what I found on this question, that will:
1. Determine the os version
2. Run on all versions of windows.

using System;
using System.Runtime.InteropServices;

namespace Testing.Helpers
{
    public static class OsVersionHelper
    {

        // Will return result of 64but OS on all versions of windows that support .net
        public static bool Is64BitOperatingSystem()
        {
            if ( IntPtr.Size == 8 ) //64bit will only run on 64bit
            {
                return true;
            }

            bool flag;
            return (DoesWin32MethodExist("kernel32.dll", "IsWow64Process") && IsWow64Process(GetCurrentProcess(), out flag)) && flag;
        }

        private static bool DoesWin32MethodExist(string moduleName, string methodName)
        {
            IntPtr moduleHandle = GetModuleHandle(moduleName);
            if (moduleHandle == IntPtr.Zero)
            {
                return false;
            }

            return GetProcAddress(moduleHandle, methodName) != IntPtr.Zero;
        }

        [DllImport("kernel32.dll")]
        private static extern IntPtr GetCurrentProcess();

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr GetModuleHandle(string moduleName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetProcAddress(IntPtr module, [MarshalAs(UnmanagedType.LPStr)]string procName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool IsWow64Process(IntPtr process, out bool wow64Process);
    }
}

C# Start/Stop/Restart Windows Service Remotely or Locally

May 13th, 2011 5 comments

Below is a very basic implementation of a class that runs within a Windows Form, to Start, Stop and Restart a windows service.

I have not included checking for other service states other than Started and Stopped, this could be extended. If you are using this to control a windows service on a remote PC, you need to ensure that the user account you are executing this from has high enough privileges to Start and Stop a service.

Updated Download of Sourcecode

Edited: 13th May 2011 –> After some imperfections, I have updated the code as shown below and in the download link above.

Fields and Constructors of Class


private const int RestartTimeout = 10000;

private readonly ServiceController service;

public Control(string serviceName, string computerName)
{
    service = new ServiceController(serviceName, computerName);
}

public Control(string serviceName)
{
    service = new ServiceController(serviceName);
}

Start Windows Service:


public bool StartService()
{
    try
    {
        service.Refresh();

        if (service.Status == ServiceControllerStatus.Stopped)
        {
            service.Start();
            return true;
        }

        MessageBox.Show(string.Format("{0} --> already started", service.DisplayName));
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString(), @"Error Starting Service");
    }

    return false;
}

Stop Windows Service:


public bool StopService()
{
    try
    {
        service.Refresh();

        if (service.Status == ServiceControllerStatus.Running)
        {
            service.Stop();
            return true;
        }

        MessageBox.Show(string.Format("{0} --> already stopped", service.DisplayName));
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString(), @"Error Stopping Service");
    }

    return false;
}

Restart Windows Service


public bool RestartService()
{
    try
    {
        service.Refresh();

        if (service.Status != ServiceControllerStatus.Stopped)
        {
            service.Stop();

            int i = 0;
            while (service.Status != ServiceControllerStatus.Stopped)
            {
                service.Refresh();
                Thread.Sleep(100);
                i++;

                if (i >= RestartTimeout / 100)
                {
                    MessageBox.Show(@"Restart Stop Timeout Exceeded");
                    return false;
                }
            }

            service.Start();
            return true;
        }

        service.Start();
        MessageBox.Show(string.Format("{0} --> was stopped, service has been started", service.DisplayName));
        return true;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString(), @"Error Restarting Service");
        return false;
    }
}

C# Update app.config in msi custom action

May 12th, 2011 3 comments

I have been doing quite a lot of googling about updating the app.config file during an installation using an msi custom action. I found this blog by Rob Aquila, however this did not really work for me.

I then came across this question on StackOverflow that almost solved the problem. The key to the solution was to open the app.config and save directly to this file.

The issue I found with the later solution is that for some reason I could not get the Context.Parameters = “targetdir”. When the install was running this was always returning null.

So my solution that worked for me is as follows:

public override void Install(System.Collections.IDictionary savedState)
{
    base.Install(savedState);

    var targetAssembly = Context.Parameters["assemblypath"];

    var path = string.Format("{0}.config", targetAssembly);

    var xmlDoc = new System.Xml.XmlDocument();

    xmlDoc.Load(path);

    var node = xmlDoc.SelectSingleNode("/configuration/userSettings/Application.Properties.Settings/setting[@name='SettingName']/value");
    node.InnerText = "PLACE NEW PARAMATER HERE";

    xDoc.Save(path);
}

Thank you to Khalil Dahab for his response on StackOverflow

Validate IPv4 Address

May 9th, 2011 1 comment

I’ve been looking for a very simple way to validate IPv4 addresses entered into a textbox. There are quite a few options I found, but none that really suited the simple functionality I was after.

This is the code snippet of what I have implemented:

public static bool CheckIpAddress(string addressIp)
{
    try
    {
        string[] splitIp = addressIp.Split('.');

        if (splitIp.Length != 4)
        {
            return false;
        }

        if (splitIp.Select(Int32.Parse).Any(result => result < 0 || 
                                                      result > 255))
        {
            return false;
        }
    }
    catch (Exception)
    {
        return false;
    }
    return true;
}
%d bloggers like this: