May 2003 - Posts

Random Color from Known Color List

Some one in an asp.net forum asked how to select a random color from the list of known colors so I wrote a little code to do this. I wrote a GetRandomColor and GetRandomNumber method which uses the RandomNumberGenerator from the System.Security.Cryptography namespace. As far as I know this is the best random number generator built into the .Net Framework.

using System.Drawing;
using System.Security.Cryptography;

...
public static Color GetRandomColor() {   KnownColor[] colors = (KnownColor[])Enum.GetValues(typeof(KnownColor));      return Color.FromKnownColor(colors[GetRandomNumber(colors.Length)]);   }
public static int GetRandomNumber(int maxValue) {   RandomNumberGenerator rng = RNGCryptoServiceProvider.Create();
  byte[] bytes = new byte[4];
  rng.GetBytes(bytes);
  int ranNum = BitConverter.ToInt32(bytes, 0);
  return Math.Abs(ranNum % maxValue); }

Official CodeProject RSS Feed

Chris Maunder has released an official RSS feed for CodeProject.  This means that I'm going to slowly discontinue my Un-Official RSS feeds for CodeProject.(http://www.puzzleware.net/codeproject/rss20.aspx, http://wes.www4.dotnetplayground.com/codeprojectrss.aspx)

So update your Aggregators. The new official feed is at: http://www.codeproject.com/webservices/articlerss.aspx

Note so far I have been unable to get this feed to work in newsgator.  I'm not exactly sure what the problem is but I'm sure it will be fixed.

Update: I was able to get the feed to work through newsgator now.

Retrieve the current Framework Directory

I needed the ablity to get the directory of the most current version of the framework on them machine, but there were no built in functions in the framework to do this (at least none that I could find). So I did a little hunting around and found where the framework installation path is stored in the registry and combined that with the Environment.Version to get the framework directory. Here is a sample function to retrieve the framework directory:

using System;
using Microsoft.Win32;

...
///  /// This method will retrieve the directory of the framework that this /// program is executing under.  It accomplishes this by getting the /// install root directory from the registry and then getting the framework /// version by using Environment.Version. ///  /// path of the framework executing this program public static string GetFrameworkDirectory() {   // This is the location of the .Net Framework Registry Key   string framworkRegPath = @"Software\Microsoft\.NetFramework";
  // Get a non-writable key from the registry   RegistryKey netFramework = Registry.LocalMachine.OpenSubKey(framworkRegPath, false);
  // Retrieve the install root path for the framework   string installRoot = netFramework.GetValue("InstallRoot").ToString();
  // Retrieve the version of the framework executing this program   string version = string.Format(@"v{0}.{1}.{2}\",     Environment.Version.Major,      Environment.Version.Minor,     Environment.Version.Build); 
  // Return the path of the framework   return System.IO.Path.Combine(installRoot, version);      }

Example of how to make sure only one instance of your program is running.

I needed a way to ensure that only one instance of my program was running at any given time. So after a little googling this is what I came up with:

Here is some sample code that can be used to ensure that only one instance of a program is running.
public static void Main(string[] args)
{
  // bool used to determine if we created a new mutex
  bool createdNew;
 
  // give a unique name for the mutex,
  // prefix it with Local\ to ensure that it's created in the per-session namespace, not the global namespace.

  string mutexName = @"Local\" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;     // Create a new mutex object with given name   Mutex m = new Mutex(false, mutexName, out createdNew);     // If the mutex already exists then don't start program becase   // another instance is already running.   if(!createdNew)     return;     //   // Do work like Application.Run(new MainForm());   //     // Release the mutex resources   m.ReleaseMutex(); }

This little trick seems to work for my needs.

Update: Added "Local\" to the mutex name per Shawn's suggestion

Email and Weblogs - Newsgator 1.2

 If you use outlook and you blog or read RSS feeds and you don’t have Newsgator then you are missing out.

With most news aggregators available today, you can read weblog posts.

NewsGator 1.1 offers excellent integration with Outlook; and given a weblog post, you can forward it via email.

Tomorrow, May 20, 2003, everything changes.

NewsGator 1.2. Available Tuesday.


[Greg Reinacker's Weblog]

Posted by puzzlehacker | with no comments

SourceForge.Net RSS Feeds

I know that there has been some talk recently about the RSS feeds for projects hosted at SourceForge.Net but I also just discovered that there are some site wide RSS feeds as well.  Things like Site-wide news, Newly Registered Projects, Top Projects By Download and Top Projects By Activity to name a few.  You can find out about all their RSS here.  I need to stay up to date with projects going on there.  I always seem to forget about them, I guess because they don’t show up very much in google searches.

Posted by puzzlehacker | with no comments

Minimize to SysTray

I was checking out some of the links on Roy’s weblog and I noticed something called minimize magic so I checked it out.  I really like the idea of being able to minimize my active windows to the systray.  I felt that the particular program minimize magic was a bit sloppy.  So I googled for some other possible programs and I ran across AllToTray and I think it is a lot cleaner.  It does cost $10 but I think it is well worth it.  I actually don’t know how I have lived without a program like this.  It’s great.

Enlightenment

I must be the last person to be "Enlightened" about using NedStat for webstats.  What stat collector do other people use?  Is there a webservice (free) that can collect webstats?  Is there something that can collect stats for rss feeds?

If your blog doesn't have a page views counter yet, I suggest getting one.  At least until we get page view statistics from Scott(hopefully, RSS feed statistics as well).

It's a masochistic an addictively enlightening experience.

[ISerializable]

ps: If this works this post is from newsgator.

Update: Cool newsgator did work!

Parsing Web Command Line Args Example

Recently I needed to pass parameters to a smart client exe, so with some assistance from some people on the Develop Mentor lists and some pure hammering of my head against the wall I came up with the following example. I hope this proves useful to others.

The key to getting the web command line arguments is to use the Environment.GetCommandLineArgs() method for an exe started through a web browser this function will return a string array of arguments that looks something like:

string[] args = {
  "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\IEExec", 
  "http://localhost/WebCommandLine/WebCommandLine.exe?param1&param2", 
  "3", "1",  "86474707A3C6F63616C686F6374710000000"};

As you can see the second argument is the url of the smart client, which can be parsed to get the parameters after the ‘?’ for the command line arguments for the exe. Remember to give the exe EnvironmentPermission: You must have Read permission to access the "Path" environment variable for the Environment.GetCommandLineArgs() to work.

One problem that is caused by passing parameters to the exe is that the AppDomain that is loaded by the IEExec for the exe sets the config file incorrectly. For the example above it would set the config file to “WebCommandLine.exe?param1&param2.config”. Which if loaded would throw an “ConfigurationException: can’t load xml file WebCommandLine.exe?param1&param2.config”. So the one work around that I found is to set the config file for that AppDomain to the empty string. Like this:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "");

Instead of passing the empty string you could pass the file name of the correct config file. Although remember that by default IIS will not serve a “.config” file. You can get around this by renaming your config file to something like “app.exe.xml”. You could also get around it by removing the “.config” application mapping from the virtual directory serving the config file, so that it will serve config files.

using System;
using System.IO;
using System.Reflection;
public class MainClass
{
  public const string APP_CONFIG_FILE = "APP_CONFIG_FILE";
  /// <summary>
  /// The main entry point for the application.
  /// </summary>
  [STAThread]
  public static void Main(string[] args)
  {
    // Get Command Line Args
    args = CommandLineArgs(args);
    // Print out the command line parameters
    int parmNumber = 1;        
    foreach(string arg in args)
      Console.WriteLine("Parameter {0}: {1}", parmNumber++, arg);
    Console.ReadLine();
  }
  /// <summary>
  /// This will determine if this exe was executed locally or through a web browser. 
  /// </summary>
  public static bool IsSmartClient
  {
    get
    {
      try
      {         
        new DirectoryInfo(AppDomain.CurrentDomain.SetupInformation.ApplicationBase);
        return false;
      }
      catch 
      {
        return true;
      }
    }
  }
  /// <summary>
  /// This method will parse the command line arguments for a .Net exe's start through
  /// a web browser(Smart Clients).  It will simple split the string after the '?' by the '&'.
  /// </summary>
  /// <remarks>EnvironmentPermission: You must have Read permission to access the "Path" environment 
  /// variable for the Environment.GetCommandLineArgs() 
  /// Command line args passed into main </remarks>
  /// <returns>list of command line args from main or from web command line</returns>
  public static string[] CommandLineArgs(string[] args)
  {
    // If this is not a smart client then return the passed in args
    if(!IsSmartClient)
      return args;
    // If you don't set the config file correctly then you will receive exception like:
    // ConfigurationException: can't file xml file app.exe?param1&param2.config     
    // Correct the location of the config file, I'm setting it to the empty string because
    // I'm not using a config file for this app, but you can set the file to what you want,
    // but remember that by default IIS will not serve a .config file.
    AppDomain.CurrentDomain.SetData(APP_CONFIG_FILE, "");
    // Get the command line args from the environment 
    args = Environment.GetCommandLineArgs();
    // args should look something like: 
    // C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\IEExec
    //  http://localhost/WebCommandLine/WebCommandLine.exe?param1&param2
    //  3 1 86474707A3C6F63616C686F6374710000000
    
    // Second parameter should be the url
    string url = args[1];
    int startParams = url.IndexOf("?") + 1;
    // If there is no '?' then return  
    if(startParams <= 0)
      return new string[] {};
    // Return the list of parameters split by '&'
    return url.Substring(startParams).Split('&');
  }
}
More Posts