Category Archives: Windows

Symlinks/Junctions in Windows

I’m not sure which version of Windows these became available in, but a useful feature (as per *nix) is the capability of creating a link from one folder to another.

So for example, I have source code which relies on a set of libraries which are supplied in a zip (i.e. no NuGet or other packaging/versioning). So I tend to create a folder with the version number in it to make it easy to immediately see what version I’m using.

Great, but the problem with this approach is I also have tooling which automatically deploys these files and post build events which do similar things. Updating these every time I get a new version is repetitive and easy to make a mistake. Plus, I’m basically lazy, if I do something once I don’t want to do it again.

So it would be far better if we created a symbolic link to the newly downloaded zips/files with a name that all the tooling can expect, for example I’ll instead create a symlink named Latest which points to the actual version (this also means I could switch version if I want easily).

To create such a link we simply use

mklink /J Latest MyLibsv1.234

this command will create a junction (or symlink) named Latest and the folder it links to is MyLibsv1.234

Now we might use nant a batch file or some other means to do this for us, but when the link’s created you cannot update it (or so it seems), instead you need to delete it using

rd Latest

So now our post build events and/or other tooling can just refer to the folder Latest and everything works smoothly.

When it’s time to deploy MyLibsv2.0 we just delete the junction and create it again.

Is my application’s UI still responsive ?

We might, on occasion, need to check whether an application we’ve spawned has a responsive UI or ofcourse we might wish to check our own application, for example within a timer polling the following code to check the application is still responsive.

Firstly, we could use the property Responding on the Process class which allows us to check whether a process’s UI is responsive.

Process p = Process.Start("SomeApplication.exe");

if(!p.Responding)
{
   // the application's ui is not responding
}

// on the currently running application we might use 

if(!Process.GetCurrentProcess().Responding)
{
   // the application's ui is not responding
}

Alternatively we could use the following code, which allows us to set a timeout value

public static class Responsive
{
   /// <summary>
   /// Tests whether the object (passed via the ISynchronizeInvoke interface) 
   /// is responding in a predetermined timescale (the timeout). 
   /// </summary>
   /// <param name="si">An object that supports ISynchronizeInvoke such 
   /// as a control or form</param>
   /// <param name="timeout">The timeout in milliseconds to wait for a response 
   /// from the UI</param>
   /// <returns>True if the UI is responding within the timeout else false.</returns>
   public static bool Test(ISynchronizeInvoke si, int timeout)
   {
      if (si == null)
      {
         return false;
      }
      ManualResetEvent ev = new ManualResetEvent(false);
      si.BeginInvoke((Action)(() => ev.Set()), null);
      return ev.WaitOne(timeout,false);
   }
}

In usage we might write the following

if (IsHandleCreated)
{
   if (!Responsive.Test(this, reponseTestDelay))
   {
       // the application's ui is not responding
   }
}

Where are the folders I’ve shared ?

In Windows, I all too often share a folder for somebody to get the latest build of some code or I’ve got data they need access to etc. and forget where the folder actually is.

So to locate the folder related to a share name, simply type

net share

at the command line prompt.

You’ll get a list containing the share name and the physical location of the share, i.e. the folder you’ve shared.

This setup requires Administrator privileges for configuring IIS Virtual Roots.

Came across this error “This setup requires Administrator privileges for configuring IIS Virtual Roots.” when attempting to install some software on a work development machine. Although I had admin rights and all permissions to install this app it failed with the above error.

To save on time getting support to sort it all out (and obviously should not be done if you don’t have the permission to do this) found that I could alter a registry setting the DisableUserInstalls value to 0 in HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer.

Memory limits for a 32-bit .NET application

I’m currently working on an application which is deployed to Windows XP (yes some corporates are still on XP), so whilst I hope this post will be useless soon, I still currently need to worry about memory usage on a 32-bit machine.

Whilst Windows XP has a 4GB memory limit, not all of this is available to your application. An application/process on a 32-bit version of windows has 2GB of available memory to use (if using the /3G switch on Windows Server 2003 then you can get 3GB). You may start to see Out of Memory exceptions (obviously depending upon what you’re trying to allocate and garbage collection etc.) at around 1.2GB.

Whilst this application is currently running on a 32-bit version of Windows it may move to a 64-bit version soon. If it has to remain as a 32-bit application it will have double the amount of memory available. So a 32-bit application on a 64-bit version of Windows will have 4GB available and Out of memory exceptions may occur in the region of 2.8GB memory usage.

Here’s a little bit of code that allows us to get the memory usage for a process

public class MemoryInformation
{
[DllImport(“KERNEL32.DLL”)]
private static extern int OpenProcess(uint dwDesiredAccess,
int bInheritHandle, uint dwProcessId);
[DllImport(“KERNEL32.DLL”)]
private static extern int CloseHandle(int handle);

[StructLayout(LayoutKind.Sequential)]
private class PROCESS_MEMORY_COUNTERS
{
public int cb;
public int PageFaultCount;
public int PeakWorkingSetSize;
public int WorkingSetSize;
public int QuotaPeakPagedPoolUsage;
public int QuotaPagedPoolUsage;
public int QuotaPeakNonPagedPoolUsage;
public int QuotaNonPagedPoolUsage;
public int PagefileUsage;
public int PeakPagefileUsage;
}

[DllImport(“psapi.dll”)]
private static extern int GetProcessMemoryInfo(int hProcess,
[Out] PROCESS_MEMORY_COUNTERS counters, int size);

public static long GetMemoryUsageForProcess(long pid)
{
long mem = 0;
int pHandle = OpenProcess(0x0400 | 0x0010, 0, (uint)pid);
try
{
PROCESS_MEMORY_COUNTERS pmc = new PROCESS_MEMORY_COUNTERS();
if (GetProcessMemoryInfo(pHandle, pmc, 40) != 0)
mem = pmc.WorkingSetSize;
}
finally
{
CloseHandle(pHandle);
}
return mem;
}

public static string ToString(long numOfBytes)
{
double bytes = numOfBytes;
if (bytes < 1024) return bytes.ToString(); bytes /= 1024; if (bytes < 1024) { return bytes.ToString("#.# KB"); } else { bytes /= 1024; if (bytes < 1024) { return bytes.ToString("#.# MB"); } else { bytes /= 1024; return bytes.ToString("#.# GB"); } } } public static string GetFormattedMemoryUsageForProcess(long pid) { return ToString(GetMemoryUsageForProcess(pid)); } } [/code]