Thursday, August 30, 2007

Running the same application as Windows Application and Console Application

Say you have a Windows Application (i.e. with GUI and all), and you want to add to it the option to be executed as a Console Application as well. Here are the two steps necessary:

1. Adding Console Application support

You must create your application as a Windows Application. Then open the Project Properties, and under the Application tab set the "Output type" to "Console Application". Once this is set, you must update your Main function to support dual application types. By default, when you create your application as a Windows application, your Main looks like this:

static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}



To support both Console Application and Windows Application, you must change it. For example, you can decide that if it receives as sole argument the string "OpenForm" it will open as a Windows Application, otherwise as a simple Console Application (in which case you'll probably want to take care of the arguments). So you should change your Main as so:


static void Main(string[] args)
{
if (args.Length == 1 && args[0] == "OpenForm")
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
// TODO: Take care of arguments
Console.WriteLine("This is a console application");
}
}



2. Remove the annoying background console


The above code is nice, but has one annoying side-effect - when you open the application as a Windows Application, you constantly have a console open in the background (closing it will close your form). To work around this you must reopen the application (i.e. creating a new process) with the console hidden. This is done as so:


static void Main(string[] args)
{
if (args.Length == 0)
{
Process current = Process.GetCurrentProcess();
string fileName = current.MainModule.FileName;
ProcessStartInfo si = new ProcessStartInfo(fileName, "OpenForm");

si.CreateNoWindow = true;
si.RedirectStandardError = true;
si.RedirectStandardOutput = true;
si.UseShellExecute = false;
Process.Start(si);
}
else if (args.Length == 1 && args[0] == "OpenForm")
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
// TODO: Take care of arguments
Console.WriteLine("This is a console application");
}
}



Explanation:

The assumption is that if you want the application to run as a Windows Application, it doesn't need any argument (though this could also be done easily if required). So if the application starts with no arguments, it will create a new process of itself (through the MainModule we extract the running process' file name), but this time with no console in the background (all the settings on the ProcessStartInfo object). This time, it is called with an argument that knows to load the form (the "OpenForm" argument).



The result is an application that can be run both as Windows Application and Console Application. When you run it as a Windows Application there is a console that opens and closes immediately in the background, but that's all.


Thanks to Ami Bar for helping me with the second step.

Maintainability

A short while ago Oren Eini stated that in his opinion, the only metric that counts is Maintainability. He even gave an excellent way to measure it.

;-)

Ever since I read these two posts, I've been trying to find ways to concretely prove him wrong. The farthest I got was with Performance, where you may have good reasons to improve performance at the expense of harming maintainability. But in good code, this is done only if the improved performance are part of the requirement. In this case, you've got to measure the code compared to some other alternative that still meets the requirement - leaving you once again to measure maintainability only.

My tiny addition to Oren's statement would be - as long as the requirements are fulfilled.

Sunday, August 26, 2007

The C# ?? operator

I needed the C# ?? operator today. This operator returns the left-hand operand if it's not null or the right-hand operand otherwise. I remembered it had the ? sign in it, but couldn't remember the exact syntax. Anyway - I'm keeping it here in my blog for the next time...

Thursday, August 23, 2007

A possible improvement to my Google Image Search API

I discovered today the following article, which mentions my API. An interesting approach they propose is, if I understand correctly, to use some common .NET class to load the HTML, and somehow extract the images from the HTML. When I wrote the API, some 2-3 years ago, I searched for such a thing but didn't find any - maybe I missed it?

If this works, it can remove completely the API's major liability, which is the dependence on the regular expressions. Right now, the API parses the HTML response returned by Google and when the format of this response is changed - the whole thing breaks. On average, since I initially published the API, the response format changed 1-2 times a year.

The downside, of course, is performance - loading the whole HTML will always be much more CPU and memory intensive than using a regex. Yet, for most applications I guess it's a price that can be paid.

Once I have a few spare hours I'll check it out. Or maybe next time Google change the response format and I need to dig into it again. We'll see.

Each line of code should do one thing

I was writing some code today that looks like this:

int counter = 0;
while (/* some condition */)
{
// Do some formatting
counter++;
FormattingProcessStatus(counter);
}

Now I could have done it differently like so:
int counter = 0;
while (/* some condition */)
{
// Do some formatting
FormattingProcessStatus(++counter);
}

which would have "saved" me one line of code. I hate this - I always have. Ever since I started learning C/C++ (over a decade ago) and while trying to solve an exercise discovered a situation where two different compilers generated different results. But today, for the first time, I understood why I hate it so much - it's against a very basic rule that EACH LINE OF CODE SHOULD DO ONE THING.



This is a very simple rule I don't remember having read anywhere, but it's the basis for readable code. Writing code, and even more so - reading code, requires a lot of brain effort. You need to be able to see the whole architecture, and how that particular object and method fits in. Sometimes you need to keep a whole stack of variables (state) in mind to really understand what's going on, etc. The difference between having to read a line that does one single thing and reading a line that does more - is very big, and complicates the reading of the code exponentially.


So if you want your code to be readable - start by making sure each line does exactly one thing!

Fighting car accidents - my five cents

Recently a family was torn apart when a truck driver smashed into a car, killing the father an daughter and injuring the wife and son. The truck driver had a history of over 190 (!!!)  traffic convictions !!!!!!!

Of course, this made a lot of noise, and many people keep asking how someone like that still drives, where have the judges left their sharp brains while judging his cases, etc.

The thing is that there is no concrete incentive to restrain these mad-men. A thing that could help would be to change the system completely - instead of having the insurance policy made on a per-car basis, make per-driver. That is, if I have a driving insurance, it would be valid no matter whose car I drive (much like already exists for mechanics). In addition, all traffic convictions should be made publicly available. The result would be that companies would avoid hiring people with many convictions - because their insurance policies are more expensive and they are dangerous.

The rules of the market will be such that dangerous drivers will have a really hard time to find jobs (especially when the job involves driving a company vehicle), and that, ladies and gentlemen, is one hell of an incentive!

If course, it's not without flaws, but I think it's worth being investigated further.

Marketing: How to give your clients something valuable without any costs

Yesterday I got a letter from Orange, saying something that reads more or less like this:

"Dear Ilan Assayag,

We are approaching the birthday of your client-ship. On August 21, you will be our client for X years. As such, we would like to give you a present you will appreciate. Therefore, during the whole day of August 21, you can talk to anyone on our network for FREE. That's right, on August 21 you won't pay for any conversation to Orange users!!!

bla, bla, bla..."

The thing is - I got this letter on August 22...

WITH keyword in SQL

A feature I didn't know in SQL 2005: WITH can be used to create ad-hoc table-like entities within a query (they call it CTE for Common Table Expression). Check it out here and here.

Wednesday, August 22, 2007

The most hilarious academic paper ever...

It's pretty old, but I discovered it only a few days ago. Some of Israel's brightest minds (such as Shimon Schocken - former dean of the the Efi Arazi School of Computer Science at the Interdisciplinary Center Hertzlia and Yossi Vardi - one of the most prominent hi-tech entrepreneurs and founder of tens of companies) joined forces to write a technical paper claiming that Snails Are Faster Than ADSL. The title is funny, the content is hilarious - take the time to read it and enjoy yourself!

Sunday, August 05, 2007

Getting the system uptime in Windows

Here's something I often need, especially when I need to find out when/why some server rebooted...

To get the system uptime, type this:

systeminfo | find "System Up Time:"

And in general, looking at the results of systeminfo is pretty interesting as well, showing stuff like product ID, uptime, type of processor(s), system directory, language and regional settings, physical memory and page file settings, installed hotfixes, basic network parameters.