December 17, 2009

WPF Timer (DispatcherTimer )

Comparison of different timers in .NET is found here. Unfortuneately this does not mention the DispatchTimer which is more appropriate for WPF usage (but not only)
using System.Windows.Threading;
...
private DispatcherTimer timer;    
...
const int MILLISECOND = 10000L;
timer = new DispatcherTimer();  
// Disable (stop) it 
timer.IsEnabled = false;
// Set timer event interval
timer.Interval = new TimeSpan(3000L * MILLISECOND);
// Timer events
timer.Tick += new EventHandler(timer_Tick);
...
timer.Start(); // at some point start the timer
...
void timer_Tick(object sender, EventArgs e)
{
  if (...)
  {
    timer.Stop();
  }
}

December 16, 2009

Sample Custom Method Attribute.

An example of a custom attribute on a method:
[AttributeUsage(AttributeTargets.Method)] 
public class ProjectReloadRequiredAfterTestAttribute
 : System.Attribute
{
}

public void Discover(MethodBase mb)
{
  if (mb.GetCustomAttributes(typeof(
      ProjectReloadRequiredAfterTestAttribute), 
      false).Length > 0)
  {
    reloadProjectRequired = true;
  }
}  
 
[Test]
[ProjectReloadRequiredAfterTestAttribute]
public void TestCreateAndDeletePart()
{
  Discover(System.Reflection.MethodBase.GetCurrentMethod());
  ...
}

Adjusting Privileges

This code is untested but may be required to shut down a PC using the exit windows API (see here
#region Adjust Priveleges

//This snippet is tested on WinXP and Vista
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
               ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);

[DllImport("kernel32.dll", ExactSpelling = true)]
internal static extern IntPtr GetCurrentProcess();

[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, 
                                             ref IntPtr phtok);

[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name,
                                                 ref long pluid);

[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
    public int Count;
    public long Luid;
    public int Attr;
}

internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
//http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
internal const string SE_TIME_ZONE_NAMETEXT = "SeTimeZonePrivilege"; 
internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";

private bool AddShutDownPrivilegeToApp()
{
    try
    {
        bool retVal;
        TokPriv1Luid tp;
        IntPtr hproc = GetCurrentProcess();
        IntPtr htok = IntPtr.Zero;
        retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES |
                                   TOKEN_QUERY, ref htok);
        tp.Count = 1;
        tp.Luid = 0;
        tp.Attr = SE_PRIVILEGE_ENABLED;
        retVal = LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid);
        retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, 
                                      IntPtr.Zero, IntPtr.Zero);
        return retVal;
    }
    catch (Exception ex)
    {
        //throw;
        return false;
    }

}

#endregion


Visual Studio Plug-In Build Properties

Lets say your writing a plug-in for an application "SomeApp.exe" at the following directory:
"D:\Projects\Smed\win32_vs90\Debug\SomeApp.exe"

Under "Build" tab set
"Output path:" by using the "Browse" button browse to "D:\Projects\Smed\win32_vs90\Debug\"

Under "Debug" tab set
"Start external program:" to "D:\Projects\Smed\win32_vs90\Debug\SomeApp.exe"
"Working directory" to "D:\Projects\Smed\win32_vs90\Debug\"

Under "Reference Paths" tab
Add "D:\Projects\Smed\win32_vs90\Debug\" to the reference paths

December 15, 2009

GetRelativePath Helper

public static class FileSystemInfoExtender
{
    public static string GetPathRelativeTo(this FileSystemInfo file, string path)
    {
        string fullPath = Path.GetFullPath(path);
        string res = string.Empty;
        if (file.FullName.StartsWith(fullPath))
        {
            res = file.FullName.Substring(fullPath.Length);
        }
        res = res.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
        string sep = Path.DirectorySeparatorChar.ToString();
        if (res.StartsWith(sep))
        {
            res = res.Substring(1);
        }
        return res;
    }
}
and some tests
FileInfo file = new FileInfo(@"D:\Projects\smeg\src\blah\xxxx\whistle\stop\Carbuncle.cs");
string relPath = file.GetPathRelativeTo(@"D:\Projects\smeg\src");
Debug.Assert(relPath.Equals(@"blah\xxxx\whistle\stop\Carbuncle.cs", 
StringComparison.OrdinalIgnoreCase));
relPath = file.GetPathRelativeTo(@"D:/Projects/smeg/src");
Debug.Assert(relPath.Equals(@"blah\xxxx\whistle\stop\Carbuncle.cs", 
StringComparison.OrdinalIgnoreCase));
relPath = file.GetPathRelativeTo(@"D:\Projects\smeg\src\");
Debug.Assert(relPath.Equals(@"blah\xxxx\whistle\stop\Carbuncle.cs", 
StringComparison.OrdinalIgnoreCase));