Tuesday, December 22, 2009

C# parsing Command Line arguments the easy way

Every console application I write needs some kind of command line arguments from user, and once the number of argument is larger than one the code to handle it becomes complex and built out of the same logical components (for each of my option find the command line argument, parse it and assign it.

If the arguments are not valid, write to console the allowed values

I decided to search for a good framework for it and i found NDesk.Options it suppose out of the box

  • String & Boolean parameters
  • Aliases for same parameter
  • Automatic string that describe allowed values (including your description)

example of code to parse command line:

public class ProgramArguments {
public string PlatformXMLFileLocation { get; set; }
public string XMLOutputFileLocation { get; set; }
public bool Silent { get; set; }
public string[] ArgsToParse { get; set; }
private OptionSet Options = null;
public ProgramArguments() { }
public ProgramArguments(string[] args) : this() {
ArgsToParse = (string[])args.Clone();
ParseArgs();
}
public void ParseArgs() {
Options = new OptionSet() {
{ "i|input=", "Path of the input platform XML file", v => PlatformXMLFileLocation = v },
{ "o|output=", "Path of the output XML to represet errors", v => XMLOutputFileLocation = v },
{ "s|silent", "Run as silent", v => Silent = v!=null }
};
Options.Parse(ArgsToParse);
}
public void WriteOptionDescriptions(TextWriter o) {
Options.WriteOptionDescriptions(o);
}
public bool IsValid() {
return !string.IsNullOrEmpty(PlatformXMLFileLocation);
}
}



I am accepting:



-i, --input=VALUE  - Path of the input platform XML file

-o, --output=VALUE  -  Path of the output XML to represent errors

-s, –silent  - Run as silent



Above was generated by running WriteOptionDescriptions provided by NDesk <Smile />



Enjoy

Friday, December 18, 2009

Workbook.SaveAsXMLData Method return XlXmlExportResult.xlXmlExportValidationFailed

As part of our daily work we have an excel sheet that contains the entire layout of out deployment (for installation) and we use an automatic mechanism to create the installation package, the process of using excel is only for simplicity of viewing for our end users and the data is being exported to XML for usage of the process.

Yesterday i wasted almost 30 min trying to understand WHY the following code was failing

Excel.XlXmlExportResult result = oExcel.ActiveWorkbook.XmlMaps["Map1"].Export("export.xml", true);
if (result != Excel.XlXmlExportResult.xlXmlExportSuccess)
{
throw new ApplicationException("failed writing file");
}


meaning why the hell did the method return xlXmlExportValidationFailed?, while the file was exported and looks “right”.



Well apparently one of our developers checked-in update version of the excel and one of the columns that was mapped to a numeric field was empty –> violation of the XSD! and that was the reason that the file was created and the method returned error (validation failed)



To mitigate the issue you can use the IsExportable method to validate XSD



Hope that helps you

Tuesday, December 15, 2009

Reading 64 bit registry from 32 bit application and the other way around

Our bootstrapper installation is 32 bit while we install several 64 bit installation like SQL 2008.

We had a requirement to support installing SQL to different port , and apparently this is not supported as a command line / update INI for the installation of SQL.

The only solution is to update the registry (64 bit) of SQL with the new port number and restart services.

We decided to write the code in VBS (or PS) and the way to do it was to use the following (example):

dim objCtx, objLocator, Inparams, Outparams

Const HKLM = &h80000002
Set objCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
objCtx.Add "__ProviderArchitecture", 64 ' Could be 32
Set objLocator = CreateObject("Wbemscripting.SWbemLocator")
Set objServices = objLocator.ConnectServer("","root\default","","",,,,objCtx)
Set objStdRegProv = objServices.Get("StdRegProv")

Set Inparams = objStdRegProv.Methods_("GetStringValue").Inparameters
Inparams.Hdefkey = HKLM
Inparams.Ssubkeyname = "Software\SomeKey"
Inparams.Svaluename = "SomeNodename"
set Outparams = objStdRegProv.ExecMethod_("GetStringValue", Inparams,,objCtx)

'show output parameters object and the registry value HKLM\SOFTWARE\
WScript.Echo "Value = " & Outparams.SValue



If you try simple approach of load the registry you will automatically get redirected to the 32 but registry! so beware and aware for this.

Sunday, December 13, 2009

How to elevate without prompting

What are you going to do if you want to run an application without prompting for user to elevate (when UAC is on)?

Well apparently the answer is very simple, you can create a scheduled task that is marked as requires highest privileges and there you go.

I found this solution here

in our solution we use it as a replacer of the “Run” section in the registry (on VISTA+) because our application must be running under token of administrator (we scheduled the task, set highest privileges, and mark the trigger of logon)

Looks as a good supported solution

Saturday, December 05, 2009

mRemote has stopped working – solution found

Few days ago my mRemote stopped working by crashing with “mRemote has stopped working”.

I tried uninstalling, and reinstalling and nothing worked, so I left it like it for few days while using MSTSC !

Today i decided to see if i can understand what went wrong, so i ran PROCMON and followed the endless lines from bottom to up (to reduce my work), i saw that just after reading private config file under my user it failed

I edited the file user.config and saw that it was zero length (how come) and decided to delete it (maybe the issue related to failure on deserialization)

Luckily that did the job!

Wednesday, December 02, 2009

Project 2010 Beta CRITICAL BUG in allocation algorithm

I decided to go ahead and download Project 2010 Beta and give it a test run an start taking advantage of the team planner feature.

By having a single view of the team i save a lot of time by not being required to jump back and forth, great feature.

while working in this version i saw a very strange behavior that i am sure is a critical bug related to bug in the algorithm of leveling, The scenario is built out of the following tasks:

Tasks

  • Stabilization is dependent on bug fixes finish.
  • first and third tasks are being done by the same resource
  • the priority of the stabilization is higher than all
  • Stabilization has a constrain of “Start no earlier than” 1/Dec/09 (which is before Bug fixing finishes)

When leveling the allocation with Priority, Standard and hour by hour you get In Office 2010:

AllocationProblem_2010

While in Office 2007 you get:

AllocationProblem_2007

So why is there a different in level result, In office 2010 the outcome is bug , as it seem project is not taking into account the predecessor constrain (Tests CANNOT start before bugs are fixed)

Am i missing anything here?!

The solution (for now) is to remove the constrain of Start no earlier than from the task and move it to the summery task

[UPDATE 12/Dec/09] I got response from Microsoft:

We are sorry this issue is causing you problems but with any beta, you have to be aware that there will be issues since you are using pre-released software. As I said below, there are two ways to work around this issue. You can re-install Project 2007 on the same machine you have Project 2010 on. This way you can use Project 2007 for your real project management work, and then the 2010 beta more for testing out the software. Alternatively, you can directly link the subtasks instead of the summary task and you will not hit this issue.

I am considering to remove the application now as i feel too much like QA person, rather than end customer (even if this is beta), I would expect the CORE of the allocation mechanism to be as stable as possible (and be under automatic test – which i understand its not)