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¶m2", "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¶m2.config”. Which if loaded would throw an “ConfigurationException: can’t load xml file WebCommandLine.exe?param1¶m2.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¶m2.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¶m2 // 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('&'); } }