Stopwatch is more efficient than DateTime.Now

While DateTime is fine for getting the current value of the date and time, it is not exactly precise or lightweight.  Thus, when timing a process, a better way to go about this is to use the Stopwatch class from the System.Diagnostics namespace.

There’s two reasons not to do this, though. First of all, the Stopwatch is generally more precise, and secondly, it’s more lightweight.

For example, running the same code using Stopwatch vs DateTime.Now math, the differences in computational speed for 1 million iterations are:

   1: DateTime math took: 1534 ms, 0.001534 ms/iteration.
   2: Stopwatch took: 70 ms, 7E-05 ms/iteration.

That’s a huge difference between the two!  So when you want to measure elapsed time of a process running on a machine, strongly consider the Stopwatch.

There’s actually a few properties we can use to see how much time has passed between Start()or StartNew()and Stop():

  • Elapsed – Returns a TimeSpan with the elapsed time.
  • ElapsedMilliseconds – Returns a long with the number of elapsed milliseconds.
  • ElapsedTicks – Returns a long with the number of Stopwatch elapsed ticks.

The first two are self explanatory, the last needs a bit more explanation as it can be a source of confusion.

The thing to remember with ElapsedTicks is that the ticks represented in Stopwatch are based on a combination of the hardware of the machine and the operating system.  Contrast this to DateTime and TimeSpan whereTicks are defined as 100 nanosecond intervals — which is obviously machine/OS independent.

And, remember that the ticks in Stopwatch are machine/OS dependent, thus you should never count on the ration of Stopwatch ticks to seconds to be the same between two systems, and possibly even on the same system after a reboot.  Thus, you can never count on Stopwatch ticks to be the same interval as DateTime/TimeSpan ticks.

To get system-independent time, make sure to use the Stopwatch’s Elapsed or ElapsedMilliseconds properties, which already take the Stopwatch.Frequency (ticks per second) into account.

Executing C# console application on remote machine

If you want to execute a console application on a remote machine, you would need to copy few other files apart from executable. Let me explain what are the other things you need.

Normally, In your Debug/Release folder you will see the following files. Let’s say, I have a project called SampleApplication.

  • SampleApplication.exe – Executable of your application. Obviously you need this.
  • SampleApplication.exe.config – XML configuration file of your application. This file may be important. File is created by copying and renaming app.config file to build target directory.
  • SampleApplication.pdb – Debug symbols. They store information needed for debugging of the application, like line numbers and similar. Application will run correctly without them, but they are not bad to have when deployed. For example, if your application throws an exception and crashes, line numbers in stack trace will be displayed if you have debug symbols present.
  • SampleApplication.vshost.exe – This is temporary executable that is used by Visual Studio, and which hosts your application temporarily while in debug mode
  • SampleApplication.vshost.exe.config – Same as for first .config file, but for Visual Studio temporary executable
  • SampleApplication.vshost.exe.manifest – You will not need this either, unless you have dependencies on assemblies of which you have many versions installed in .NET search locations (application folder, GAC, etc.)

So, of the files mentioned above, you only need SampleApplication.exe, and maybe SampleApplication.exe.config (if you are using configuration stored in it).

Comma key is detected as PrintScreen

I have written about disabling print screen here. Strangely, Comma( , ) key was detected as Print-screen. I was surprised and I couldn’t find out the reason even after so many hair-pulling sessions. Seriously, I was trying to debug and see the key-code of both keys(Print-screen & Comma). Unfortunately, key codes were same. So I was digging further to find the difference between those two key presses. And I have come up with the following PreFilterMessage() function to handle this problem.

In the below code, kCode will be equal to Keys.Snapshot or Keys.PrintScreen for both keys(Print-screen & Comma). So, I used WM.Msg to differentiate them.

 public bool PreFilterMessage(ref Message WM)
 {
     const int WM_KEYDOWN = 0x100;
     const int WM_KEYUP = 0x101;
     const int WM_CHAR = 0x102;
     const int WM_SYSKEYDOWN = 0x104;
     const int WM_SYSKEYUP = 0x105;
     const int WM_SYSCHAR = 0x106;

     Keys kCode = (Keys)(int)WM.WParam & Keys.KeyCode;

     if (WM.Msg == WM_KEYUP || WM.Msg == WM_SYSKEYUP)
     {
         if (kCode == Keys.PrintScreen)
         {
             //PrintScreen is detected; Do something
             return true;
         }
     }
     else if (WM.Msg == WM_KEYDOWN || WM.Msg == WM_SYSKEYDOWN)
     {
         if (Control.ModifierKeys == Keys.Control && kCode == Keys.C)
         {
             //Ctrl+C is detected; Do something
             return true;
         }
     }
     else if (WM.Msg == WM_CHAR)
     {
         //Added this to catch the print screen when ',' is pressed
         if (kCode == Keys.PrintScreen)
         {
             //Comma is detected; Do something
             return false; //If this is 'true' comma cannot be typed; it's always filtered/cleared
         }
     }
     return false;
 }

But, I’m still puzzled about this; How on earth a comma key can be detected as PrintScreen????? But if you come across the same problem; you can use this approach to differentiate the keys.

Detect if an application runs on a remote desktop

If you want to find out whether an application runs on a remote desktop or not, you can find it easily in C#. This is how you can find it:

if (SystemInformation.TerminalServerSession)
{
    // Application runs on remote desktop
    // Do something
}

System.Windows.Forms.SystemInformation.TerminalServerSession will be true for a remote desktop session. Use case would be, For example; If you want to block user from running an application on remote desktop.

Chromeless Windows Form

What is ‘Chromeless Window‘?

A window with no title bar, no border, etc… Mainly a window with none of the windows dressing; just the window itself!

A typical windows form will be with border, title bar, etc. So you can minimize, maximize the window if you want. But, let’s say you don’t want to do these things; you just want the window without the dressing. It’s very simple; And just single line of code would do!

this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

Add the above code inside the form’s constructor. Build & Run to see the chromeless window!

Get Internet Explorer version using NSIS script

When you create installers, you may want to support some versions of some softwares. For example; internet explorer. In that case; how do you get the IE version when the installation starts.

It’s possible using NSIS. There are 2 functions already there on the NSIS sourceforge.net. One is GetIEVersion and other one is GetIEFullVersion. But unfortunately both of them have problems.

First let’s talk about GetIEFullVersion. it’s supposed to give us the full version number; For example: 11.0.9600.16521. But it is giving wrong information. To be more specific, I wanted to get a version number of IE 11. It gives something like 6.1.7601.18222. So It’s supposed to be the value we should get from the function, when I went through the function. Because they get the version of ‘shdocvw.dll‘. So I browser about the relationship between IE and shdocvw.dll and giving a small excerpt here:

Determine the version of Internet Explorer by using the Shdocvw.dll file:
For Internet Explorer 3.0 through 6, the browser is implemented in the Shdocvw.dll (Shell Document Object and Control Library) file. You can use the version of the Shdocvw.dll file to determine the version of Internet Explorer 3.0 through 6 that is installed on your computer. To determine the version number of Internet Explorer 7, you must determine the version number of Iexplore.exe. To do this, follow these steps:

  1. Click Start, point to Find, and then click Files Or Folders.
  2. In the Named box, type shdocvw.dll, and then click Find Now.
  3. In the list of files, right-click the Shdocvw.dll file, and then click Properties.
  4. Click the Version tab.
  5. Repeat steps 2 through 4, but in step 2, instead type iexplore.exe. If the version of Iexplore.exe is 7.x, Internet Explorer 7 is installed. Use the table of Internet Explorer versions earlier in this article to compare the version number to release versions of Internet Explorer 7.

So from the above description, we shouldn’t get the version of ‘shdocvw.dll’ for IE 7 and above! But there are other ways to get the version like from the IE->properties. However NSIS function is failing as it’s using ‘shdocvw.dll

Then I was trying to use other function: GetIEVersion. I thought it’s working in the perfect way. But it’s not. Reason is, it gives you the correct version number for IE Version 9 or below. Not for Newer versions. When I checked the function I found out the problem. To get the version number they read the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Version. But ‘version’ is not the actual version number for latest IEs. There comes the problem. ‘svcVersion’ will have the actual version. Check the screenshots of IE and Registry values here.

IE

IERegistry

So if I want to get a version of a IE11 from registry, I should not read the value of ‘Version‘. I should read the value of ‘svcVersion‘ instead. When i checked the IE forum, I saw the following excerpt:

The version vector key in the registry was used by earlier versions of IE for conditional comments but conditional comments are no longer recognized by IE10 as they are non-standards. The version vector key is not used by applications to determine the IE build. The user-agent string differs from vector version and is the version that web servers will see when they request a page.

Now in the version key you will see 9.10.9200.16384 for IE10 and the svcVersion string value as 10.0.9200.16384.
This is by design and should not affect which version of IE that other applications detect. If you are experiencing problems, please post what your entire version number is in the registry plus upload IEDIAG and provide detailed repro steps of the behavior.

So, Keep in mind that you shouldn’t take the IE version from ‘Version‘ in the registry. Take it from ‘svcVersion‘ instead.

Read about IE versions here