BizArk Feature Spotlight – Command-line Parsing

by Brian Brewder February 20, 2010 20:39

Command-line parsing can be a tedious chore when you are building an application that accepts command-line arguments. But what if all you had to do was create a class with the properties that you want to accept? The BizArk framework offers a simple to use command-line parsing utility that allows you to do exactly that.

Command-line parsing in the BizArk framework has these key features:

  • Automatic initialization: Class properties are automatically set based on the command-line arguments.
  • Default properties: Send in a value without specifying the property name.
  • Value conversion: Uses the powerful ConvertEx class also included in BizArk to convert values to the proper type.
  • Boolean flags. Flags can be specified by simply using the argument (ex, /b for true and /b- for false) or by adding the value true/false, yes/no, etc.
  • Argument arrays. Simply add multiple values after the command-line name to set a property that is defined as an array. Ex, /x 1 2 3 will populate x with the array { 1, 2, 3 } (assuming x is defined as an array of integers).
  • Command-line aliases: A property can support multiple command-line aliases for it. For example, Help uses the alias ?.
  • Partial name recognition. You don’t need to spell out the full name or alias, just spell enough for the parser to disambiguate the property/alias from the others.
  • Supports ClickOnce: Can initialize properties even when they are specified as the query string in a URL for ClickOnce deployed applications. The command-line initialization method will detect if it is running as ClickOnce or not so your code doesn’t need to change when using it.
  • Automatically creates /? help: This includes nice formatting that takes into account the width of the console.
  • Load/Save command-line arguments to a file: This is especially useful if you have multiple large, complex sets of command-line arguments that you want to run multiple times.

So how do you use the command-line parsing? Start by creating a class that is derived from CmdLineObject. Add properties with data types that support conversion from a string using the BizArk ConvertEx class. In main, instantiate your class and call Initialize. That’s it.

If you want to validate your command-line or display help, you will need to check a couple of CmdLineObject properties. Other than that, you can just use your object as any other class.

Here’s an example class that uses it (you can also view an example in the RedwerbEntry project, Program.cs):

    static void Main(string[] args)
{
RedwerbCmdLine cmdLine = new RedwerbCmdLine();
cmdLine.Initialize();
// Validate only after checking to see if they requested help
// in order to prevent displaying errors when they request help.
if (cmdLine.Help || !cmdLine.IsValid())
{
DlgMgr.ShowCmdLineHelp(cmdLine);
return;
}
// do your stuff
}
    [CmdLineDefaultArg("SettingsPath")]
public class RedwerbCmdLine
: CmdLineObject
{
public RedwerbCmdLine()
{
SettingsPath = @"C:\Garb\Settings.rdb";
FadeInTime = 2000;
FadeOutTime = 1000;
RunTime = 5000;
}
[CmdLineArg(Alias="S", ShowInUsage=DefaultBoolean.True, Required=true)]
[Description("If false the splash screen is not displayed during startup.")]
public bool ShowSplashScreen { get; set; }
[CmdLineArg(Alias = "I")]
[Description("Determines how long it takes for the splash screen to fade in.")]
public int FadeInTime { get; set; }
[CmdLineArg(Alias = "O")]
[Description("Determines how long it takes for the splash screen to fade out.")]
public int FadeOutTime { get; set; }
[CmdLineArg(Alias = "R")]
[Description("Determines how long Redwerb will run.")]
public int RunTime { get; set; }
[CmdLineArg(Alias = "P", Usage = "Settings Path")]
[Description("Path to the settings file.")]
public string SettingsPath { get; set; }
[CmdLineArg(Alias = "M", Usage = "Message")]
[Description("Message to display.")]
public string Message { get; set; }
}

BizArk is available for download on the CodePlex website, http://bizark.codeplex.com.

Tags: ,

BizArk

BizArk is now on CodePlex

by Brian Brewder December 31, 2009 12:27

I have finally gotten around to putting BizArk on CodePlex. Check it out at http://bizark.codeplex.com. I will be removing the BizArk downloads from Redwerb.

Tags:

BizArk

BizArk Feature Spotlight - WebHelper

by Brian Brewder November 20, 2009 23:43

The WebHelper class is a new feature of the BizArk framework. It’s primary purpose is to replace System.Web.WebClient. The WebClient is a great class that makes it pretty easy to do simple web requests.

Unfortunately WebClient only supports a small set of requests such as simple gets, form value posts, single file uploads, and a few others. If you need to upload multiple files in the same request, you are out of luck. If you have a request that might take more than 100 seconds, you are out of luck. If you need to do anything special at all, you are pretty much out of luck and will have to use the HttpRequest object to perform the request.

HttpRequest allows you to do a lot more, but you are stuck implementing the different protocols for the content body. These are very specific and technical and easy to miss something, not to mention that it doesn’t support progress reporting (you have to build that yourself).

The Redwerb.BizArk.Core.Web.WebHelper class is intended to provide you full access to making requests without bothering you with all the mundane details. It includes the following features:

  • Supports no content type, multipart/form-data, and application/x-www-form-urlencoded. Will automatically pick the correct content type based on the properties you set. It can also support custom content types. Just inherit from Redwerb.BizArk.Core.Web.ContentType and implement the two required methods.
  • Can set the timeout for the request.
  • Simple multiple file upload with form values. WebClient makes you send values in the query string.
  • Supports in-memory file uploads. The file doesn’t actually have to exist on disk.
  • Handles compressed responses with a simple property set.
  • Supports progress. You can set an estimated response length to get an approximate total progress before a response is received. If not set, the request/response will be 50/50.
  • Supports asynchronous requests.
  • Event to modify the request before it is sent to the server. Provides you with full control over the request that is sent.
  • Event to process the response instead of having the WebHelper handle it.
  • The response is returned as a WebHelperResponse object. This object provides access to the result as well as status of the response. It also allows you to convert the response to another type other than a byte[] (such as string, image, etc).

To use the WebHelper, just set the url and call MakeRequest.

    var helper = new WebHelper();
helper.Url = "http://localhost:57492/Test/SimpleTest";
var response = helper.MakeRequest();
var result = response.ConvertResult<bool>();
If you want to upload a file and some form variables, that’s easy too!
    var helper = new WebHelper();
helper.Url = "http://localhost:57492/Test/UploadFileTest";
helper.FormValues.Add("test", "Hello");
helper.Files.Add(new UploadFile("file1", @"text\plain", "file1.txt", Encoding.UTF8.GetBytes("Hello World")));
helper.Files.Add(new UploadFile("file2", @"text\plain", "file2.txt", Encoding.UTF8.GetBytes("Goodbye World")));
var response = helper.MakeRequest();
var result = response.ResultToString();  

I’m sure there is still a lot of work to do on this component. Let me know if you find any problems!

I would like to give a special thanks to aspnetupload.com. WebHelper essentially started out as a copy of UploadHelper from this site (though I don’t think there is too much in common with it anymore).

BizArk is available for download on the CodePlex website, http://bizark.codeplex.com.

Tags: ,

BizArk

BizArk Feature Spotlight – Data Type Conversions

by Brian Brewder September 08, 2009 00:15

The System.Convert class in .Net is a great way to convert basic values to new and wonderful types. Unfortunately it only works on a very limited set of data types. To be precise, it only works if the type implements IConvertible and you can see what types are supported in the listing below.

public interface IConvertible
{
TypeCode GetTypeCode();
bool ToBoolean(IFormatProvider provider);
byte ToByte(IFormatProvider provider);
char ToChar(IFormatProvider provider);
DateTime ToDateTime(IFormatProvider provider);
decimal ToDecimal(IFormatProvider provider);
double ToDouble(IFormatProvider provider);
short ToInt16(IFormatProvider provider);
int ToInt32(IFormatProvider provider);
long ToInt64(IFormatProvider provider);
sbyte ToSByte(IFormatProvider provider);
float ToSingle(IFormatProvider provider);
string ToString(IFormatProvider provider);
object ToType(Type conversionType, IFormatProvider provider);
ushort ToUInt16(IFormatProvider provider);
uint ToUInt32(IFormatProvider provider);
ulong ToUInt64(IFormatProvider provider);
}

If you are looking to convert to other values or the type you are converting from does not implement IConvertible, you are out of luck.

The BizArk framework provides the Redwerb.BizArk.Core.ConvertEx class which extends the conversion capabilities of the .Net framework. ConvertEx can convert types based on the following conversion strategies:

  • TypeConverter: This is a class that you can implement to support conversions between any data types you wish to support. You can get a TypeConverter by calling TypeDescriptor.GetConverter(Type). TypeConverters are used in the binding support in WinForms as well as a few other places in the .Net framework.
  • ToXxx methods: This is a common naming convention for converting an object into another type. The most common of these is the System.Object.ToString() method.
  • Parameterized constructors:  This is a convention where a constructor for a class takes a typed parameter.
  • Parse static methods. This is a common convention for converting strings to a particular type. See Int32.Parse for an example.
  • Image to byte array and vice versa: This is a specific type of conversion to convert an image to a byte array for storage or sending to a stream.
  • To/from null: Reference types can be set to null, but value types cannot. In those cases ConvertEx supports the concept of empty values. An empty value is determined based the following criteria:
    • Reference type: null
    • Char: 0 (that is \0)
    • Static [Type].Empty property (if defined)
    • Static [Type].MinValue property (if defined)
    • Custom empty value. Register the empty value by calling ConvertEx.RegisterEmptyValue.

To use ConvertEx, simply call one of the ConvertEx methods. There are a number of helper methods to convert values to basic types such as integer, string, boolean, etc. However, you can also call the ConvertEx.ChangeType method to convert between any two types (as long as one of the types supports conversions from the other type).

The following example shows how to use the generic version of ConvertEx.ChangeType. As you can see, it is pretty straight forward.

var pt = new Point(5, 10);
var myPt = ConvertEx.ChangeType<MyPoint>(pt);

ConvertEx also provides a plugin architecture if you want to extend the types that it can convert to/from. To use it, just create a class that implements the Redwerb.BizArk.Core.Convert.IConvertStrategy interface and register it by calling Redwerb.BizArk.Core.Convert.ConvertStrategyMgr.SetStrategy (you must register it for each to/from type you want it to support).

BizArk is available for download on the CodePlex website, http://bizark.codeplex.com.

Tags: ,

BizArk

BizArk Feature Spotlight – Splash Screen

by Brian Brewder August 30, 2009 11:47

The splash screen is a common feature in many desktop applications. A splash screen is used to provide feedback to the user as the application initializes. If your application does not have a long initialization process, it does not need a splash screen, and should not have one (the splash screen can become annoying after a while, especially if it is not necessary).

If you are in need of a splash screen, the BizArk framework provides the capability to show the splash screen on a thread while you initialize your application in Main (the starting point in Windows applications). You do not need to worry about any of the threading issues, BizArk takes care of all that for you. If you are interested in learning how to display a form on a separate thread, check out the source code in SplashScreen.cs, BizArkWinForms project.

The BizArk SplashScreen class provides the following capabilities:

  • Displays a custom splash screen on a separate thread to allow for initialization on the main thread.
  • Provides a mechanism to send progress to the splash screen.
  • Can fade in and out to give a more finished, polished look.
  • Set a minimum time to show the splash screen.

The splash screen is easy to use. Just create your splash screen as a standard Form. In your programs Main method (usually in Program.cs), create a new instance of Redwerb.BizArk.WinForms.SplashScreen and send in the type for your custom splash screen. When you are ready to show your splash screen call ShowSplash and when you are done with it call HideSplash.

If you want to send status updates to the splash screen, your form will need to implement the ISplashScreen interface. The BizArk SplashScreen object will route the status to the correct thread so that you don’t need to worry about cross threading issues (problematic with WinForms).

Below is an example of calling the splash screen from the RedwerbEntry project (a test project available in the BizArk Framework download):

    SplashScreen splash = new SplashScreen(typeof(Splash));
splash.FadeInTime = 500;
splash.FadeOutTime = 500;
splash.MinShowTime = 3000;
splash.ShowSplash();
//todo: remove sleep (used for testing purposes).
splash.Status = "Sleeping";
System.Threading.Thread.Sleep(cmdLine.RunTime);
//todo: initialize the application including creating an instance of the main form.
//var frm = new MyForm();
//var frm.Initialize(); // or whatever you need to do to prepare the form before display.
splash.Status = "Hiding";
splash.HideSplash(true);
//Application.Run(frm);

BizArk is available for download on the CodePlex website, http://bizark.codeplex.com.

Tags: ,

BizArk

BizArk Feature Spotlight – String Templates

by Brian Brewder August 06, 2009 22:45

I’ve never liked that String.Format requires you to provide indexed arguments. I’m a bit anal and like my arguments to increase from left to right so that if I add a new argument to the beginning of the string I end up renumbering all the subsequent arguments (hey DevEx, perhaps you can add this to Refactor!?). 

This isn’t too big of a deal for small strings, but it can make it difficult to work with large strings with a lot of arguments, especially when the text and arguments change frequently. To get around this, I often times resort to using named parameters and String.Replace (see the example below).

var str = "{greeting} {name}!";
str = str.Replace("{greeting}", "Hello");
str = str.Replace("{name}", "World");
Debug.WriteLine(str);

Surprisingly performance doesn’t seem to be a major problem with this approach. Iterating 1,000,000 times using string.Format("Hello {0}: {1,2}", "World", i) took ~650 milliseconds vs string.Replace which took about ~900 milliseconds. This might add up to a significant difference in extreme situations, but in most cases it is negligible.

However one major drawback to string.Replace is that you lose the ability to specify formatting in the string which can be very handy, especially when you are dealing with regional formatting issues.

So in order to help with this, I added the StringTemplate class to BizArk which allows you to create a format string that combines the best of both worlds, named arguments along with specifying formatting in the string (see example below).

var template = new StringTemplate("{greeting} {name} on {date:dddd, MMMM dd, yyyy}!");
template["greeting"] = "Hello";
template["name"] = "World";
template["date"] = DateTime.Now;
Debug.WriteLine(template.ToString());

This will print out “Hello World on Thursday, August 06, 2009!”.

StringTemplate actually uses String.Format to format the string so any formatting that you can use in a String.Format argument you can use in a StringTemplate argument. The names are not case sensitive, but they must conform to the same standard as identifiers in C# (upper/lower case letters, numbers, and underscore).

I also created a generic version of StringTemplate. The generic version exposes a property that you can use to set the parameters. If the type has a default constructor, StringTemplate<T> will instantiate it for you (you can also set it if you prefer).  The name of the arguments should match with the name of the properties. It uses the TypeDescriptor class to get the properties, so you can implement ICustomTypeDescriptor if you want. This should make it fairly easy and painless to do mail-merge type functionality.

BizArk is available for download on the CodePlex website, http://bizark.codeplex.com.

Tags: ,

BizArk

BizArk is Back!

by Brian Brewder April 04, 2009 15:44

I lost the BizArk framework when I changed web hosts, but it is back now. Check out the full list of features on the BizArk page.

There are a few updates since the last release, but unfortunately I don't remember what they are (I made the updates a long time ago, but haven't gotten around to posting them). I believe that I've fixed some problems with the ConvertEx class as well as added some new functionality to it. I've also added some useful extension classes and fixed some problems with the splash screen not working quite right under certain circumstances.

Tags: ,

BizArk

BizArk updated to 1.0.1

by Brian Brewder July 07, 2008 02:35

I've made a number of updates to the BizArk framework for another project that I'm also releasing today (stay tuned).

New features:

  • New API for SharpZipLib. I didn't like how you had to work with streams and how the zip directory structure was built, so I created an API that hopefully makes it easier.
  • Email API. I created a simple API for sending email using the MAPI32 MAPISendMail function (no need to allocate/deallocate memory!). Supports To, CC, BCC, attachments, subject, body, and either direct send using the users email client or display the users email client.

Updated components:

  • You can now save and restore a CmdLineObject from an xml file.
  • CmdLineObject can be displayed in a PropertyGrid. Base properties are not browsable.
  • Added ConvertEx.IsEmpty. This method determines if a value is empty. A value is empty if it is null, DBNull, or matches a MinValue, MaxValue, or Empty static field on the class (except for char which checks for '\0'. You can register empty values for any type by calling ConvertEx.RegisterEmptyValue.
  • Added ArrayExt.RemoveEmpties. This method removes empty elements in an array based on ConvertEx.IsEmpty.
  • Many other changes as well...

Tags:

BizArk

Introducing the BizArk Framework

by Brian Brewder June 16, 2008 01:31

For a hobby, some people watch or play sports, others collect or build things. Not me. I code. I spend a large amount of my personal time (time when I'm not at work or with my family) either reading about, playing with, or writing software (it's one of the reasons I continue to write this blog even though I have few actual readers).

Because of this, I have decided to create a framework that I will share with anybody that wants to use it. I am calling this framework the BizArk framework (if you didn't get it, BizArk is short for business architecture). You can read a full description on the BizArk Framework page.

This initial release only includes a few things, such as command-line argument parsing, splash screen management, and some extension methods and is really more of a library than a framework. I do plan on adding to this framework, but I don't have any kind of road map or even goals for it.

I am licensing it under the WTFPL software license. This license allows you to do Whatever The F*** you want with it. I don't really care how people use it, I'm just doing it for fun. Some day I might make it an open source project, but no real plans of that for now.

Tags:

BizArk

Powered by BlogEngine.NET 1.6.0.0

About the author

I've been a software developer since 1999 and have been working with .Net since 2002. I love creating software, playing with productivity tools, and improving the process of software development. I hope you enjoy my blog. Please feel free to leave comments or contact me, I would love to hear from you.