November 26, 2013

Working with SandCastle Problems

I created a project using the "SHFB v1.9.7.0 with Visual Studio Package". This was used to convert an old help project to the latest format. However after the conversion I had make 2 fixes to get the project to build. SandcastleHelpBuilder post conversion fixes:
  1. Ensure that in the "Project Properties" tab 'Build' option that the 'Framework Version' field is set to '.NET Framework 2.0', the framework version of the compiled source code.
  2. Ensure that in the "Project Properties" tab 'Paths' option that the 'Working files path' field is set to 'Working\'.

November 6, 2013

Path Extension Class

This helper creates a temporary file with the given extension.
public static class PathExtensions
{
 // Create a temporary file with a specific file extension
 public static string GetTempFileName(string extension)
 {
  string tempFileName = Path.GetTempFileName();
  string newtempFileName = tempFileName.Replace(".tmp", extension);
  File.Move(tempFileName, newtempFileName);
  return newtempFileName;
 }
}

November 5, 2013

Guid String Formats

Most concise form is
 string guid = Guid.NewGuid().ToString("N");
There are other formats as well The ToString(string format) method can format a guid in one of several ways:
"N" - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (32 digits)
"D" - xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (32 digits separated by hyphens)
"B" - {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} (same as "D" with addition of braces)
"P" - (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) (same as "D" with addition of parentheses)
"X" - {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
The Guid can be shortened as a string by using Base64 encoding:
//Compress the given Guid as a base64 string that is 22 characters long.
private static string ToShortString(Guid guid)
{
  string encoded = Convert.ToBase64String(guid.ToByteArray());
  return encoded.Substring(0, 22); // Last 2 characters are always ==
}

September 23, 2013

Using the Windows 7 shell Taskbar Item to show that a WPF application is busy/idle

Add the following to the Main window XAML:
    <Window.TaskbarItemInfo>
        <TaskbarItemInfo />
    </Window.TaskbarItemInfo>
In code: To make the task bar icon pulse green to show that it is busy but when the application cannot determine how far through the proceesing the app is:
this.TaskbarItemInfo.ProgressState = TaskbarItemProgressState.Indeterminate;
To stop the task bar icon pulsating green/return it to normal:
this.TaskbarItemInfo.ProgressState = TaskbarItemProgressState.None;
To show progress through the task bar icon:
this.TaskbarItemInfo.ProgressState = TaskbarItemProgressState.Normal;
// ProgressValue must be a value between 0.0 and 1.0
this.TaskbarItemInfo.ProgressValue = progressPercentage/100.0d; 

August 28, 2013

LINQPad Command-Line and Scripting

LINQPad Command-Line and Scripting
Sample usage:
CALL C:\...\LinqPad\lprun.exe "C:\...\Queries\AttachDatabases.linq" DEV
This runs the given linq query. The sample is a "C# Program" and has a "Main" method taking "string[] args" as a paremeter. In this way the "DEV" string at the end of the line is passed as a parameter to the linq program.
Here is the sample linq script:
<Query Kind="Program" />

void Main(string[] args)
{
  string attachFolder = @"C:\Databases\";
  if ((args != null) && (args.Length == 1))
  {
  attachFolder = Path.Combine(attachFolder, args[0]);
  }
  Console.WriteLine("Attaching to databases in \'" + attachFolder + "\'"); 
  Console.WriteLine("");
  var server = @".\";
  var databaseNames = new[] { "XXX", "YYY", "ZZZ", "AAA" };

    using(var connection = new SqlConnection(
   string.Format("Server={0};Database=master;Trusted_Connection=True;", server)))
    {
    connection.Open();
  
    // attach the databases
    foreach(var database in databaseNames)
    {
      var dataFile = Path.Combine(attachFolder, database + "_Data.MDF");
      if (File.Exists(dataFile))
      {
        Console.WriteLine("Attaching {0}", database);
        var attachCommand = connection.CreateCommand();
        attachCommand.CommandText = "sp_attach_db  @dbName, @dataFileName, @logFileName";
        attachCommand.Parameters.AddWithValue("dbName", database);
        attachCommand.Parameters.AddWithValue("dataFileName", dataFile);
        attachCommand.Parameters.AddWithValue("logFileName", 
            Path.Combine(attachFolder, database + "_Log.LDF"));    
        attachCommand.ExecuteNonQuery();
      }
      else
      {
        Console.WriteLine("No data file for {0}", database);
      }
    }
      }
  
    Console.WriteLine("");
    Console.WriteLine("Press any key to continue ...");
    Console.ReadKey(false);
}
If you want the script to hang around a bit so that you can read the error messages then you can add the the following lines to the end
Console.WriteLine("");
Console.WriteLine("Press any key to continue ...");
Console.ReadKey(false);
This keeps the script alive until a key is pressed.

August 16, 2013

An Animated WPF Gif

The Image control in WPF does not support animated GIF files by default. However, there is a library on codeplex, here, that can be used to do this.
Here is my usage of this library for an animated busy indicator.
In the XAML, first of all create an XML namespace for the library:
xmlns:gif="http://wpfanimatedgif.codeplex.com"
then use it with an image control:
<Image Name="imgBusy" 
       Stretch="UniformToFill" VerticalAlignment="Top" Width="20"  
    gif:ImageBehavior.AnimatedSource="/ScriptRunnerWPF;component/Resources/busyIndicator.gif" 
    gif:ImageBehavior.AutoStart="False" />
In code the animation of the GIF can be controlled:
Start the animation
   
this.imgBusy.Visibility = System.Windows.Visibility.Visible;
ImageAnimationController iac = ImageBehavior.GetAnimationController(this.imgBusy);
if (iac != null)
    iac.Play();
Resume the animation
// Resume the animation (or restart it if it was completed)
ImageAnimationController iac = ImageBehavior.GetAnimationController(this.imgBusy);
if (iac != null)
 iac.Pause();
this.imgBusy.Visibility = System.Windows.Visibility.Hidden;

Using StackTrace

Using StackTrace to show the first 3 lines of a stack trace in the debugger:
StackTrace st = new StackTrace(false);
st.Dump("UpdateScriptRunning Stack Trace", 3);
and the accompanying extension method:
public static class StackTraceExtender
{
  public static void Dump(this StackTrace st, string context, int numFrames)
  {
    Debug.WriteLine(context ?? "");
    string stk = st.ToString();
    string[] wanted = stk.Split(new string[] { "\r\n" }, 
                             StringSplitOptions.RemoveEmptyEntries);
    foreach (string line in wanted.Take(numFrames))
    {
        Debug.WriteLine(line ?? "");
    }
  }
}