Friday, December 7, 2007

Fighting against my own ignorance

Yesterday I started, what seemed like, a little side project. The idea was very straightforward, just write a little GUI to control some installation scripts. Soon after finishing the brainstorm session I eagerly started to code the little thingy.

  • First thing I wanted in place was a little decompression class for the purpose of decompressing a cabinet file. After searching a way to do this from within the code I came across several problems so I thought, what the hack, let’s just make a call from within our code to the external windows program Expand.exe and save some time instead of trying to reinvent the wheel. This eventually did the trick for me! 1 down, a little more to go ;-)


       29         private void StartProcces(string FileName, string Arguments, TextBox OutputTextBox)

       30         {

       31             System.Diagnostics.Process extractCmd = new System.Diagnostics.Process();

       32             extractCmd.EnableRaisingEvents = true;

       33             extractCmd.StartInfo.FileName = FileName;

       34             extractCmd.StartInfo.Arguments = Arguments;

       35             extractCmd.StartInfo.RedirectStandardOutput = true;

       36             extractCmd.StartInfo.RedirectStandardInput = true;

       37             extractCmd.StartInfo.UseShellExecute = false;

       38             extractCmd.StartInfo.CreateNoWindow = true;

       39             extractCmd.Start();

       40             if (OutputTextBox != null)

       41             {

       42                 string StringToWrite = null;

       43                 while (null != (StringToWrite = extractCmd.StandardOutput.ReadLine()))

       44                 {

       45                     AddToProccesViewer(StringToWrite, OutputTextBox);

       46                 }

       47             }

       48             extractCmd.WaitForExit();

       49         }





  • 2nd part of this little adventure was the creation of a class that made it possible to actually run external program’s and that give me the option to redirect it’s output to something like a textbox for instance. The main part of this code I already created for the extraction of the cabinet file. At first a had a little problem writing the output real-time, but after some little tweak’s I had it, a working class to run some simple dos programs.
  • 3rd part would be the easiest of them all, just read the little XML file into the program and iterate through the imported document letting me run the scripted programs. Well, this sounds simpler than it truly is (taking into consideration that the whole XML stuff is quite new to me). First I started off importing the whole XML into a dataset, this didn’t work that well for me. ok, let’s thinks, the problem I had was that I was missing some sort of relation between the imported items. Maybe XSD could help me out of this mess after playing a little with the program XSD.exe I suddenly a whole class that was created from my little XML file. A little overkill if you ask me. So I started it all over. The trick I now use is that I added a little attribute to the program elements called id. Now I’m using only the xml file (no extra schema’s) and iterating thru the file using several XPath expressions instead of relying of the internal relationship of the document, so for now, no usage of the crazy ChildElements.


       79         private void ReadXml()

       80         {

       81             if (System.IO.File.Exists(TMP_PATH + XML_FILENAME))

       82             {

       83                 string myXMLfile = @"" + TMP_PATH + XML_FILENAME;

       84                 string myXMLschema = @"" + TMP_PATH + XSD_FILENAME;

       85                 doc = new System.Xml.XmlDocument();

       86                 doc.Load(TMP_PATH + XML_FILENAME);

       87                 foreach (System.Xml.XmlNode n in doc.SelectNodes("//Program[@id]"))

       88                 {

       89                     AddToProccesViewer("Title: " + n.SelectSingleNode("Title").InnerText, textBox1);

       90                     AddToProccesViewer("Command: " + n.SelectSingleNode("Command").InnerText, textBox1);

       91                     AddToProccesViewer(BuildParameter(n.SelectSingleNode(".").Attributes[0].InnerText), textBox1);

       92 

       93                     string cmd = n.SelectSingleNode("Command").InnerText;

       94                     string param = BuildParameter(n.SelectSingleNode(".").Attributes[0].InnerText);

       95                     string showoutput = n.SelectSingleNode("ShowOutputInWindow").InnerText;

       96                     if (showoutput == "True")

       97                     {

       98                         StartProcces(cmd, param, textBox1);

       99                     }

      100                     else

      101                     {

      102                         StartProcces(cmd, param, null);

      103                     }

      104                 }

      105             }

      106         }






  • 4th part of the project would be putting the whole thing together. This is the currently state of the project. I discovered a little inconvenience, Dos program’s that require user input seem to “hang”, so I have to trigger some sort of event in case this happens and let the user (or the Deploy.xml scripting file) choose the appropriate action. After having resolved this issue I will take on another challenge. I have to build some sort of functionality that makes it possible to editing file’s that are extracted from the cab file based on some sort of user input (Example: The installation program asks a destination directory and has to change several batchfile’s in the cab file to make the necessary changes that will make the batchfile’s copy file’s to this user provided path)

That’s it for now, back to code!

No comments: