Windows Installer – Uninstall custom actions – WARNING!!!

April 18th, 2012 No comments

With uninstall custom actions you have to be really careful.

#1 Rule

When working with uninstall custom actions, always encapsulate the custom action in a try / catch block!

Why?

If you are testing your uninstall process and it throws an exception you will be left with a half uninstalled application.
As the application has not un-installed you cannot install a new version and as the uninstaller is compiled you cannot rebuild the installer to fix the error that is causing the exception.

How do I know this?

I did this exact thing. I was creating an installer that had custom actions for both install and uninstall.
I caused an exception in the uninstall process and I was left with a product that could not be uninstalled!

Can you recover from this?

I found that in this scneario the Microsoft Fix-it tool is your saviour.

Download the fix it program from here, Microsoft Fix-it Uninstaller

Run the program and follow the prompts.

I did a custom uninstall, chose my product that had failed to uninstall and it cleans up all the relevant registry keys so that it has been completely removed from the computer.

Cheers

Categories: c# Tags:

Background Worker Thread Code Sample with event handlers and cross thread invoke

March 30th, 2012 No comments

The Problem

So you want to create a windows form application. It needs to do the following:

  1. Do some work where its processing multiple items
  2. Have a progress bar that updates the progress of the application as it runs.

Seems easy.. well here are the complexities:

  1. You want the main process to run on a background thread, so that the UI thread is available to update and render
  2. The background thread will need to raise events back to the main application to notify the application of the background thread progress.
  3. The progress bar will need to be updated to reflect the progress.
  4. The call to update the UI will crash because it is actually doing a cross-thread call, (the background thread, is trying to update the UI thread and this will crash.

This will walk you through the pattern for implementing this solution.

Background Worker Thread

This as the name suggests is a thread of execution that runs in the background in the application leaving the UI thread to do what it is good at, UI rendering.

If you were to try and have a method that processed 1000 records @ 2 seconds per record, and tried to update the progress bar on processing each record the UI would not render the progress bar as the UI thread is caught up in the process of doing the work.
Doing the work on the background thread leave the UI thread to update the UI whilst the background thread gets on with doing the work.

What is the background thread and how do I create one?

First of all lets create a visual studio solution. I am going to create an empty windows form application called WorkerUtility. I will place the following controls on it.

  1. A button btnGo – labeled Go
  2. A progress bar; and
  3. A label called lblProgress – to show the % complete

The background worker thread can be found in the toolbox under the “Components” section.
Drag the background worker thread onto you form and you will end up with a control called backGroundWorker1.

It should look like this:

Set the following properties on the background worker control

  • WorkerReportsProgress true

Double click on the “Go” Button and setup the following Code


private void btnGo_Click(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}

Performing the Work and Raising Events

I am going to simulate processing a 126 items @ Random number of seconds between 0 and 2 seconds, by looping and pausing the background thread. You could be doing anything in the processing block, for example, read data from the database loop through the rows and perform file system tasks based upon the data?

I will be performing work but each time an item is processed I want to tell the UI thread so that it can update the progress bar. To do this I will need to use events and I am going to create some custom event args.

Create a class called ProgressUpdatedEventArgs like the following:


using System;

namespace WorkerUtility
{
    public class ProgressUpdatedEventArgs : EventArgs
    {
        public ProgressUpdatedEventArgs(int total, int progress)
        {
            this.Total = total;
            this.Processed = progress;
        }

        public int Processed { get; private set; }

        public int Total { get; private set; }
    }
}

I will encapsulate the logic in a class called Processor.cs. Create a class as follows:
This will house the event handler and raise events back to the UI thread

The main point of Interest in the following code is the creation of the event handler on the page with a delegate method declaration and an event handler. The RaiseEvent method is called on each file that is processed.


using System;

namespace WorkerUtility
{
    public static class Processor
    {
        public delegate void ProgressUpdatedEvent(ProgressUpdatedEventArgs progressUpdated);

        public static event ProgressUpdatedEvent ProgressUpdated;

        /// <summary>
        /// Main execution method that does the work
        /// </summary>
        public static void Execute()
        {
            int total = 126 // this creates funny percentages
            Random randomGenerator = new Random();
            for (int i = 0; i < total; i++)
            {
                // Do some processing here

                double delay = (double)randomGenerator.Next(2) + randomGenerator.NextDouble();

                int sleep = (int)delay * 1000;

                System.Threading.Thread.Sleep(sleep);

                RaiseEvent(total, i + 1);
            }
        }

        private static void RaiseEvent(int total, int current)
        {
            if (ProgressUpdated != null)
            {
                ProgressUpdatedEventArgs args = new ProgressUpdatedEventArgs(total, current);
                ProgressUpdated(args);
            }
        }
    }
}

Cross-Thread method invoke, handling the callback

Now we need to set up an event handler in the main form so we can update the UI when the event is raised.

On the Background Worker Switch to the “Events” properties and double-click on “DoWork” to create the “DoWork” event handler.

Go to the _DoWork event handler and change as follows:


private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    Processor.ProgressUpdated += new Processor.ProgressUpdatedEvent(Processor_ProgressUpdated);
    Processor.Execute();
}

void Processor_ProgressUpdated(ProgressUpdatedEventArgs progressUpdated)
{

}

So this is where the tricky bit comes in. We need to implement the _ProgressUpdated callback.
If we were to go directly to update the UI, we would get a cross thread exception and the program would crash.

Cross-thread operation not valid


Cross-thread operation not valid: Control 'progressBar1' accessed from a 
thread other than the thread it was created on.

If you check the InvokeRequired method it will return true in this scenario so we need to perform a cross thread call to get from the background worker thread, that the “ProgressUpdated” event is raised on, to the UI thread to make the changes in the UI.

This is done as follows, firstly you need a delegate for the method invoke method callback and an Update Method to handle performing the UI Update.


public delegate void ProgressUpdatedCallaback(ProgressUpdatedEventArgs progress);

private void Processor_ProgressUpdated(ProgressUpdatedEventArgs progressUpdated)
{
  if (InvokeRequired)
  {
    Invoke(new ProgressUpdatedCallaback(this.UpdateProgress), new object[] { progressUpdated });
  }
  else
  {
    UpdateProgress(progressUpdated);
  }
}

private void UpdateProgress(ProgressUpdatedEventArgs args)
{
  if (progressBar1.Maximum != args.Total)
  {
    // initial setup
    progressBar1.Minimum = 0;
    progressBar1.Maximum = args.Total;
    progressBar1.Style = ProgressBarStyle.Continuous;
  }

  progressBar1.Value = args.Processed;

  if (args.Total > 0)
  {
    double progress = args.Processed / (args.Total * 1.0);
    lblProgress.Text = progress.ToString("P2");
  }

  Application.DoEvents();

}

Here is what it looks like running

Here is the full working code sample in a VS2010 solution.
WorkerUtility

Categories: c#, Windows Forms Tags:

PowerShell get “Return Value” from StoredProcedure ExecuteNonQuery

February 27th, 2012 No comments

The scenario is that from PowerShell you want to do the following:

1. Execute a stored Procedure
2. Check the Return Code from the stored procedure call.
3. Perform conditional logic based upon whether the stored procedure succeeded or failed

The following will show you how to:

    1. Create a PowerShell function to execute a stored procedure.
    2. Call this stored procedure and extract the return code into an integer variable
    3. Apply conditional logic based upon the return code

    I struggled with getting this to work and did not find any exact examples that explained it exactly as I wanted.

    Environment Setup

    1. SQL Server / Express – I am running SQL Sever 2008 R2 Express on the local host
    2. Create an empty Database called “TestDB”
    3. PowerShell configured with Remote-Signed Execution Policy. If you don’t know how to do this go here Set PowerShell Execution Policy

    StoredProcedure

    Create a stored procedure as follows on your TestDB

    
    
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[prcTest]') AND type in (N'P', N'PC'))
    DROP PROCEDURE [dbo].[prcTest]
    GO
    
    Create Procedure prcTest 
      @value int
    as
    begin
      Declare @return float
      
      BEGIN TRY
      
        -- could return divide by 0 error if value = 0 
        set @return = 1 / @value;
      
        Return 0 -- success
      
      END TRY
      BEGIN CATCH
        -- will return 1 when there has been a divide by zero error
        return 1
      END CATCH
    end
    
    

    This procedure will accept a single integer parameter and divide by it. If zero is passed in the procedure will fail with a divide by zero error and return the return code of 1.
    Any other number will succeed.

    0 = Success and 1 = Error

    PowerShellScript

    Create a file called test.ps1 in your c:\Scripts directory.

    You can run this from the PowerShell ISE or you can create a .bat file and past this line in it:

    
    PowerShell.exe -noexit c:\scripts\test.ps1
    

    The Power Shell Script is as follows:

    
    function ConnectionString()
    {
        return "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=TestDB;Data Source=.\SQLExpress";
    }
    
    function executeStoredProcedure($value)
    {
        
        $connection = ConnectionString;
        $query = "prcTest";
        
        $sqlConnection = new-object System.Data.SqlClient.SqlConnection $connection
        $sqlConnection.Open() 
        
        $sqlCmd = new-object System.Data.SqlClient.SqlCommand("$query", $sqlConnection) 
    
        $sqlCmd.CommandType = [System.Data.CommandType]"StoredProcedure" 
        
        $sqlCmd.Parameters.AddWithValue("@value", $value)
    
        $sqlCmd.Parameters.Add("@ReturnValue", [System.Data.SqlDbType]"Int") 
        $sqlCmd.Parameters["@ReturnValue"].Direction = [System.Data.ParameterDirection]"ReturnValue" 
    
        $sqlCmd.ExecuteNonQuery() | out-null
        $sqlConnection.Close() 
    
        [int]$sqlCmd.Parameters["@ReturnValue"].Value
        
    }
    
    # Test 1 - Should fail
    #======================================
    Write-Host "====================="
    Write-Host "TEST 1"
    Write-Host "====================="
    $out = executeStoredProcedure(0)
    Write-Host $out
    $returnValue = $out[2]
    Write-Host $returnValue
    
    if($returnValue -eq $null -or $returnValue -ne 0)
    {
        Write-Host "An Error Occured"
    } 
    else 
    {
        Write-Host "Success"
    }
    
    # Test 2 success
    # ---------------
    # removed the Write-Host lines 
    #======================================
    Write-Host "====================="
    Write-Host "TEST 2"
    Write-Host "====================="
    $out = executeStoredProcedure(1)
    $returnValue = $out[2]
    
    if($returnValue -eq $null -or $returnValue -ne 0)
    {
        Write-Host "An Error Occured"
    } 
    else 
    {
        Write-Host "Success"
    }
    

    I will talk you through a few of the interesting points of above.

    ConnectionString Fuction

    I do this so I can have my connection string centralised in my script and that way if
    I need to change the SQL Server credentials I am using I only need to make the change in one place

    [int]$sqlCmd.Parameters["@ReturnValue"].Value

    This gets the “ReturnValue” from the stored procedure and then casts it to an integer.

    Note: I did try code like;

    
    $rc = [int]$sqlCmd.Parameters["@ReturnValue"].Value
    return $rc
    

    But it made no difference to the output of the function.

    $returnValue = $out[2]

    I will confess I don’t now a great deal about PowerShell but I have worked through this problem to get a working solution.
    If you execute it and look at the output from the “Write-Host $out” you will see it appears to be an array type object and it prints as

    
    @value @ReturnValue 1
    

    I figured this is a zero based array so I just accessed the value in position 3 i.e. $out[2], which is already of type “int” due to the cast in the function.

    Conditional Logic

    So now I have the integer return value in a variable $returnValue I can use it in my conditional logic. If the value was null or <> 0 then it must be in error else success.

    Implementing this means you can execute a stored procedure and if it fails , you can cancel any further processing in the Script.

    Nice ;-)

Categories: Code Tags:

Set PowerShell ExecutionPolicy

February 27th, 2012 No comments

When trying to run a PowerShell script you may get the following error:

“scriptname.ps1 cannot be loaded because the execution of scripts is disabled on this system”

You need to do the following to set the executionPolicy.

1. Run Powershell as Administrator
2. get-exeuctionPolicy
3. set-executionPolicy RemoteSigned
4. Enter Y
5. Check by running get-exeuctionPolicy
 

 

Categories: Code Tags:

Enable Windows PowerShell ISE (Integrated Scripting Environment)

February 27th, 2012 No comments

On a Windows Server 2008 box you may be wondering where the Windows PowerShell ISE is.

To Enable

  1. Bring up the Server Manager (Right-Click on “Computer”, choose manage
  2. Move to the Features Tab
  3. Choose “Add Features”
  4. Click “Windows PowerShell Integrated Scripting Environment”
     

     

     

     

  5. Click Next
  6. Click Install

The IDE is now installed and can be found under:
– All Programs
– Accessories
– Windows PowerShell

Windows Power Shell ISE Menu Location

Categories: Code Tags:

ASUS U3S6 Review – Benchmark SSD on Sata 3 add-on card against Sata II onboard

February 23rd, 2012 5 comments

Part 2 of my SSD SATA III performance tests.

If you are here and haven’t seen part 1 “Sata 3 SSD running on onboard SATA II benchmark” go here >>>

The Question

Is there any reason to buy a SATA III expansion card to run your new SATA III SSD if your MOBO only has SATA II?

So I have a shiny new Corsair Force GT 120GB SATA III drive and an old SATA II motherboard.

Last article I benchmarked the performance to see what kind of experience you get when running on your onboard sata II connectors.

This article is the part 2 where I am going to benchmark the relative performance with a SATA III expansion card to see if there is any point is spending the money on one.

The Test Card – ASUS U3S6

 
Marvell 88SE9123 Chipset

It was a bit hard to track one down in Australia so I had to buy this second-hand off the overclockers australia forums, but I wanted this card for its x4 PCI-e v2.0 connection.

Details of the U3S6 here.

The U3 = USB 3.0 with a NEC chip set; and
The S6 = Sata III 6.0Gb/s Marvel 88SE9123 controller.

 

ASUS U3S6 Sata III PCIe expansion card

ASUS U3S6 Sata III PCIe expansion cardASUS U3S6 Default Firmware Boot Screen Shot

 

 

 

 

 

 

 

 

 

The card has yet to be flashed from its original bios which appears as 1.0.0.1012.

I decided to play it safe and rather than flash the bios and destroy the card I would start from scratch, benchmark it first. Later I will play and see if I can improve on stock performance results, buy flashing to later versions of the firmware.

At on OS software level I tested with 2 driver configurations:

1.0.0.1036 and 1.2.0.1016
Marvell Driver 1.0.0.1036 Screenshot  

with some interesting results..

The latest drivers are best found on station-drivers. It’s french but version numbers can be read easily, go to the bottom for the MV91xx drivers and firmware.

The test rig

Mother Board: Socket 775, Gigabyte EP45-DS3
CPU: Core 2 Duo E8400 3.0Ghz, running overclocked @ 4.0Ghz.
Memory: 4GB (2x2GB) Corsair CM2X2048-8500C5C (1066Mhz)
Video: MSi R6850 Storm II 1G OC (R6850 PM2DIGD5)
SSD: Corsair Force GT 120GB, (1.3.3 firmware on SATA II in AHCI mode)
SATA III Card Asus U3S6 (firware 1012)
OS: Windows 7 SP1 – 64 bit

The U3S6 is a x4 card and will run on PCI-E v2.0. The EP45-DS3 only has 3 x PCI-e 1.0 x1 ports, and has a x16 and x8 PCI-e v2.0 slot.

The x16 slot is currently running my MSi HD 6850, and the x8 slot is free.

The U3S6 is therefore running in the x8 slot.

I was interested in seeing what might happen when running something like crysis whilst having the U3S6 trying to use the same bus.

Synthetic Benchmarks

AS SSD

My original SATA II Benchmark score on SATA II was 480! I did this benchmark on day 1 of a clean Windows 7 install. Since then I have been using the computer for a few months and the drive is about 50% full so I benchmarked with AS SSD again.

I did numerous benchmarks with in multiple different driver and SATA configurations. The Read speed seemed to give consistent results across similar benchmarks but the write performance (particularly the 4K-64-Thrd) was a bit all over the place and seemed to influence heavily the overall score giving results between 395 and 450.

The following results are the best of each run:

SATA II – Rerun

SATA II Benchmark

U3S6 – 1.0.0.1036
ASUS U3S6 1036 Driver AS SSD benchmark

ASUS U3S6 1.0.0.1036 Driver Compression Benchmark

U3S6 – 1.2.0.1016


U3S6 on 1.2.0.1016 driver AS SSD benchmark

The U3S6 seems to have better sequential read of approx 340MB/s. This is only a 75MB/s improvement.

I noted that generally the benchmark results for the earlier 1.0.0.1036 driver were slightly better and more consistent than the later 1.2.0.1016 driver.

Also the Read performance was generally consistent but the 4k and 4k-64Thrd write times were up and down.

Crystal Disk mark

Given the fluctuations I also tried Crystal Disk mark which seemed to give similar results without the randomness.

SATA II – Rerun

Crysal Disk Corsair Force GT 120GB SSD Benchmark on SATA II

U3S6 – 1.0.0.1036
Crystal Disk Corsair Force GT ASUS U3S6 Benchmark Driver 1.0.0.1036

U3S6 – 1.2.0.1016
Crystal Disk Corsair Force GT ASUS U3S6 Benchmark Driver 1.2.0.1016

Again the 1.0.0.1036 driver seemed to out perform its older brother.

Windows Start Up Times

The test

Same as last time, the benchmark recorded the time from when windows started loading after the POST screen, until a working desktop was available. This was identified as the time at which the Gadgets appeared on the desktop. This was split into 3 timing points

  1. time to login screen
  2. time to login
  3. time to see the desktop and the gadgets loaded.

Windows 7 Startup times Benchmark SSD results
The fastest startup time was still SATA II and the 1.2.0.1016 driver made a difference but the 1.0.1036 was consistently a few seconds slower to boot.

Windows Experience

The only score to change when running the U3S6 was the Disk from 7.8 to 7.9. Note: 7.9 is currently the maximum rating.
Windows Experience Score on the SSD SATA III

Crysis Benchmarks

I didn’t bother with the load time tests as I figured they would be comparable.

I did however run the Benchmarks for both Crysis and Crysis 2 in the various configurations, with some interesting results.

Crysis Benchmark

The crysis benchmark was run @ 1920×1080 – 64-bit and DirectX 10
The benchmark was run with the following SSD connections

  1. SATA II
  2. U3S6 1.0.0.1036

Crysis Benchmark

The results were almost identical. No change here.

Crysis 2 Benchmark

The benchmark was run on DirectX 11 on the Times Square Map.

Crysis 2 Benchmark

The most interesting thing here is that when the video card was being pushed by crysis 2, the PCIe channel appears to be compromised by the SSD drive running on the x8 port.

This can be seen in the poor fps on the two higher settings.

USB Performance

Just to see how the USB 3.0 worked I hooked up my Western Digital 1 TB external hard drive and did a 4.14GB and 15.5 GB file copy both up to and down from the External drive.

I found the 15.5GB copy onto the external drive took 10m 1s @ USB 2.0 but only took 3m 52s on USB 3.0. The copy down from the external driver took 9m 11s @ USB 2.0 and 3m 43s @ USB 3.0.
The copy rates were approx 27.1 MB/s combined for USB 2.0 whilst USB 3.0 achieved 67.9 Mb/s or 2.5 times faster. Nice.

Why so slow?

I have gotten around to flashing the Card. At first it felt like “flushing” not “flashing” as the firmwares I tried off “Station-Drivers” broke the card. After a few hours of flashing I finally got the driver working with Firmware revision 1028 “Firmware pour U3S6 Rev 0 (MV-9123) Version:1.0.0.1028) Mod by Daoud333″

So when I start it up I see the following

ASUS U3S6 firmware 1028 Screenshot on startup

PCIe x1 5.0Gbps. x1 why x1, its a x4 card running in a x8 slot?

After some digging I found this spec document on the controller, Marvell 88SE91xx Product Brief. If you read this the spec fo the controller shows this..

Marvell 88SE 9123 x1 PCIe

The controller only supports a single x1 connection.

I feel a bit duped. I specifically got this card for its x4 connection, but given the fact the marvel controller only accepts a x1 connection the SATA will only ever be able to run at this speed. I have read other people suggest that the x4 is used to split the channel in half and use some of the x 4 bandwidth for the USB 3.0 controller, which would make sense but it seems like false advertising to me.

Conclusion

Overall I think if you are out of SATA ports on your PC and need a few more, then the card is OK as long as you are NOT using it for gaming.
The sequential read is slightly better but this is only a benchmark figure as it did not translate in the real world.
The only other nicety is the USB 3.0 which will come in handy in the future.

I think in the next few months The Marvel 92xx controllers
will start to appear and these may allow my SSD to run to its full potential as this supports PCIe x2.

Cheers

Categories: Hardware Review Tags:

Router Logging Software – Free – MyRouter Log

January 31st, 2012 No comments

My router was crashing a bit and I thought I would check the router logs to see if there was any clues in there as to what was going on?

Once my router crashes the log files are lost, so I went in search of some router logging software.

In short I tried a few and they were buggy pieces of rubbish that didn’t work.

It’s just a simple UDP listening program, and so In the immortal words of Jeremy Clarkson (Top Gear, UK), “How hard could it be?”, so I wrote my own.

Its called “MyRouter Log” and it’s a UDP port listener for capturing to a text log file, the contents of your routers UDP broadcast.

Its free and full details can be found here on my site, MyRouter Log

Hope you like it and give me some feedback in case my software is a “buggy piece of rubbish” ;-)

Categories: Free Software Tags:

JetPack Post Statistics Link Plug-in

January 25th, 2012 No comments

You may have noticed that the jetpack plugin provides you with some great statistics on the hits to your website.

It also allows you to drill down on the statistics for each post, with one problem…

If your post does not appear in the top 10 results for the day then you have no way to see the statistics.

That is where the “JetPack Post Statistics Link Plug-in” comes in.

The plug-in provides an extra column on your Posts admin page and provides a link to the statistics for each post.

To download a copy go to my main website.. >> Download Link <<

Categories: WordPress Tags:

Crysis 2 50Hz issue ATI Card on HDMI connection

January 16th, 2012 No comments

I have been running Crysis 2 on my DVI connection no worries, but recently I changed to a HDMI cable to connect my Benq E2420HD to my Msi R6850 video card.

If you see my previous post, Benq Monitor and HDMI not working you will see that I had some issues with getting my monitor to work, but I found the settings and all was good with the world.. until I launched Crysis 2.

Issue

When Crysis 2 runs with DX 11 in full screen mode, it runs @ 50Hz.

My monitor can handle 50Hz, (it is a supported refresh rate), but the game did not fill the full screen. The full screen was black but the edges of the game fell about 1cm short or the edge of my screen.

So WTF was going on?

Catalyst Control Centre.. again..

The issue is the overscan setting. As per the previous post (link above), I had to set the overscan setting to 0%. But when the monitor switches to 50Hz it also switches to a different profile, and this profile has the overscan setting to about the middle of this bar, (approx 7.5% underscan)

The solution is:

  1. Launch Catalyst control centre
  2. Expand “Desktop Management” and click on “Desktop Properties”
  3. Set the monitor to use 50Hz and click apply
    your monitor will switch and wow you suddenly see the black border similar to when you were playing Crysis 2
  4. Switch to the “Scaling Options” and set the Overscan to 0% and click apply

When you play Crysis it will now fill the full screen.

Got to go.. stuff to shoot .. ;-)

Categories: Hardware Issues Tags:

Benq Monitor and HDMI not working – FIXED

January 14th, 2012 No comments

Attaching a monitor to a pc via HDMI should be easy… right.

Well on hooking up a Benq E2420HD monitor to a MSi R6850 (PM2DIGD5), the image looked terrible.

It took a bit of tweaking but these are the steps you will need to follow to get things looking how they should.



Step 1. Catalyst Control Centre Settings

In my case the software was defaulting to set the scaling options to “under scaled”! (about -7.5%)

Turn the scaling off and set it to 0% as shown.

Step 2. Monitor Settings

You need to turn off the overscan feature, in the monitors OSD (on-screen display) settings.

  1. Go to the Picture Advanced page and choose display mode

    On Screen Display 1

  2. Set the Overscan feature to OFF

    On screen display overscan

    Problem solved :-)

Categories: Hardware Issues Tags: