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 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)
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
"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));
November 26, 2009
Accessing Command Line Arguments In WPF
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs sea)
{
CommandLine.Instance.SetArguments(sea.Args);
base.OnStartup(sea);
}
}
public class CommandLine
{
private CommandLine()
{}
private static readonly CommandLine instance = new CommandLine();
public static CommandLine Instance
{
get { return instance; }
}
public IEnumerable Arguments
{
get { return args; }
}
public void SetArguments(string[] args)
{
this.args = args ?? new string[0];
}
private string[] args = new string[0];
}
then to use private void Window_Loaded(object sender, RoutedEventArgs e)
{
foreach (string arg in CommandLine.Instance.Arguments)
{
if (arg.ToUpper() == "/C")
{
if (System.Windows.Forms.Clipboard.ContainsText())
{
tbCode.Text = System.Windows.Forms.Clipboard.GetText();
}
}
}
}
Doh!Even easier:
string[] arguments = Environment.GetCommandLineArgs();When processing command line args using Environment.CommandLineArgs(), found that the system automatically matches " in an argument. So if you have a path that contains a spaces, as long as that path is wrapped with " marks, the path will not be parsed into multiple arguments but rather appear as a single argument. eg.:
-myArg:C:\Program Files\MyProgram\Something.exe
will get parsed as multiple arguments:
- -myArg:C:\Program
- Files\MyProgram\Something.exe
-myArg:"C:\Program Files\MyProgram\Something.exe"
will get parsed as a single argument:
- -myArg:C:\Program Files\MyProgram\Something.exe
Have also noticed that carriage return line feeds can get sucked into a command line argument. Perhaps a "Trim()" should be applied to each argument string before it is processed to be sure this whitespace is removed. Here is a sample command line parser:
internal class CommandLineParser
{
public string Drive { get; set; }
public string TrueCryptFile { get; set; }
public string KeyFile { get; set; }
const string DrivePrefix = "-D";
const string TrueCryptFilePrefix = "-T";
const string KeyFilePrefix = "-K";
public void CommandLineArgs(string[] args)
{
//string[] args = Environment.GetCommandLineArgs();
Debug.WriteLine("Args:" + string.Join(",", args));
int ix = 0;
foreach (string arg in args)
{
Debug.WriteLine("arg[" + ix++.ToString() + "]=\'" + arg + "\'");
}
foreach (string rawArg in args)
{
// Get rid of whitespace chars at the beginning and end
string arg = rawArg.Trim();
if (arg.Length < 2)
continue;
string argument = (arg[0] == '/') ? "-" + arg.Substring(1) : arg;
int end = argument.IndexOf(':');
if ((end == -1) && ((end + 1) >= argument.Length))
continue;
if (argument.ToUpper().StartsWith(DrivePrefix))
{
Drive = argument.Substring(end + 1).Substring(0, 1) + ":";
}
else if (argument.ToUpper().StartsWith(TrueCryptFilePrefix))
{
TrueCryptFile = argument.Substring(end + 1);
}
else if (argument.ToUpper().StartsWith(KeyFilePrefix))
{
KeyFile = argument.Substring(end + 1);
}
}
Debug.WriteLine("Processed command line args:");
Debug.WriteLine("Drive=\"" + Drive + "\"");
Debug.WriteLine("TrueCryptFile=\"" + TrueCryptFile + "\"");
Debug.WriteLine("KeyFile=\"" + KeyFile + "\"");
}
}
// and tester (not really finished)
class CommandLineParserTester
{
public void TestCommandLineParser()
{
CommandLineParser clp = new CommandLineParser();
clp.CommandLineArgs(new string[] {
@"-D:M",
@"-T:F:/Temp/truecrypt.tc",
@"-K:F:/Temp/truecrypt.keyfile" });
Assert(clp.Drive == "M:");
Assert(clp.TrueCryptFile == @"F:/Temp/truecrypt.tc");
Assert(clp.KeyFile == @"F:/Temp/truecrypt.keyfile");
}
}
Labels:
Command Line Arguments,
Program Arguments
November 19, 2009
Debugger/Editor Attributes
DebuggerDisplay - Use it to specify how a class or struct should be displayed in the debugger when the cursor hover over the item
EditorBrowsable - Use this 'EditorBrowsable' property to restrict intellisense/visual studio visibility of a property
DefaultValue - Then there is the 'DefaultValue' property that sets the default value of a C# class property. Used by visual designers, etc
[DebuggerDisplay("Count = {count}")]
class blahblahblah ...
DebuggerStepThrough - Instructs the debugger to step through that marked property or attribute, and not into it: [DebuggerStepThrough]
public int Key
{
[System.Diagnostics.DebuggerStepThrough]
get { return key; }
[System.Diagnostics.DebuggerStepThrough]
set { key = value; }
}
DebuggerBrowsable - Determines if and how a field or property is displayed in the debugger variable windows. [DebuggerBrowsable(DebuggerBrowsableState.Never)] private int key;see also DebuggerDisplay and DebuggerBrowsable – Two Debugger Attributes you should know
EditorBrowsable - Use this 'EditorBrowsable' property to restrict intellisense/visual studio visibility of a property
[EditorBrowsable(EditorBrowsableState.Never)] int MyProperty ...
DefaultValue - Then there is the 'DefaultValue' property that sets the default value of a C# class property. Used by visual designers, etc
[DefaultValue(42)]
public int MyProperty { get; set; }
Subscribe to:
Posts (Atom)