Execute VBScript from C#

This can be done using, CScript.exe

Process scriptProc = new Process();
scriptProc.StartInfo.FileName = @"cscript"; 
scriptProc.StartInfo.WorkingDirectory = @"c:\scripts\";
scriptProc.StartInfo.Arguments ="//B //Nologo vbscript.vbs";
scriptProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //prevents console window from popping out
scriptProc.Start();
scriptProc.WaitForExit(); //(Optional)
scriptProc.Close();

C# The calling thread cannot access this object because a different thread owns it.

One of the common problems encountered during multi-threading is when you try to set a Windows Control value from a different thread. I also faced this issue while implementing the following code:

private async void TestAsyncMethodVoid()
{
    System.Net.Http.HttpClient hClient = new System.Net.Http.HttpClient();
    string content = String.Empty;
    try
    {
        content = await hClient.GetStringAsync("http://www.microsoft.com").ConfigureAwait(false);
    }
    catch (Exception ex)
    {
        content = ex.Message;
    }
    btn00.Content = content;
}

btn00 is a button control whose value I was trying to set here using async/await as the value was coming over a network call. You may have some other case scenarios also where you’d want to set a control’s property directly from the thread. So to do that we’re gonna use, Dispatcher.Invoke method.

It executes the specified delegate synchronously on the thread the Dispatcher is associated with. Look at the following code with correction:

private async void TestAsyncMethodVoid()
{
	System.Net.Http.HttpClient hClient = new System.Net.Http.HttpClient();
	string content = String.Empty;
	try    
	{
		content = await hClient.GetStringAsync("http://www.microsoft.com").ConfigureAwait(false);
	}
	catch (Exception ex)
	{
		content = ex.Message;
	}
	this.Dispatcher.Invoke(() =>
	{
		btn00.Content = content;
	});
}

This code now works without any glitches.

Extract all the Guids from a string C#

This is one of the rare requirement where I had to extract all the Guid from a string and then do the further processing. Now, to do that, I have used Regex.Matches. It will return a MatchCollection containing each Guid. For a string with no Guid, it will return a MatchCollection of length 0.

string strGuid = "5102d73a-1b0b-4461-93cd-0c024738c19e;#5102d73a-1b0b-4461-93cd-0c024733d52d";
string strNoGuid = "someTextButNoGuid";

string pattern = @"([a-z0-9]{8}[-][a-z0-9]{4}[-][a-z0-9]{4}[-][a-z0-9]{4}[-][a-z0-9]{12})";

MatchCollection mc;

//MatchCollection of length 2
mc = Regex.Matches(strGuid, pattern);

//MatchCollection of length 0
mc = Regex.Matches(strNoGuid, pattern); 

Get the Nth Minimum or Nth Maximum number from a collection C#

For a collection of integers/decimals, we can use the .Max() and .Min() to get the maximum and minimum value of the collection respectively.
However, there are two more case scenarios, that I have faced, which I am going to discuss next. Following is the definition of a class Item that I am going to use here:

class Item: IComparable<Item>
{
    public string itemName { get; set; }
    public int itemPrice { get; set; }

    int IComparable<Item>.CompareTo(Item other)
    {
        if (other.itemPrice > this.itemPrice)
            return -1;
        else if (other.itemPrice == this.itemPrice)
            return 0;
        else 
            return 1;
    }

 
	//Operator overloading 

	public static bool operator >(Item X, Item Y)
	{
		if (X == null && Y == null)
		{
			return false;
		}
		if (X == null)
		{
			return false; //true?
		}
		if (Y == null)
		{
			return true; //false? 

		}

		return X.itemPrice > Y.itemPrice;
	}

	public static bool operator <(Item X, Item Y)
	{
		if (X == null && Y == null)
		{
			return false;
		}
		if (X == null)
		{
			return true; //false?
		}
		if (Y == null)
		{
			return false; //true? 

		}

		return X.itemPrice < Y.itemPrice;
	} 
}

 

Populate some value to the collection


Item[] items = { new Item { itemName="Item1", itemPrice=10 },
                 new Item { itemName="Item2", itemPrice=20 },
                 new Item { itemName="Item3", itemPrice=30 }, 
                 new Item { itemName="Item4", itemPrice=40 } };

Get the Minimum number greater than a certain value OR Maximum number lesser than a certain value


//get the minimum valued item = Item1
int min = items.Min().itemPrice;//get the min valued item greater than the 2nd item = Item3
int min = items.Where(p => p > items[1]).DefaultIfEmpty().Min().itemPrice);
//get the maximum valued item = Item4
int min = items.Max().itemPrice;

//get the max valued item less than the 3rd item = Item2
int min = items.Where(p => p < items[2]).DefaultIfEmpty().Max().itemPrice);

 

Similarly, we can also get the element at each index


Item secondLowest = numbers.OrderBy(num => num).ElementAt(1);
Item secondHighest = numbers.OrderBy(num => num).Reverse().ElementAt(1);

Validate a String to be in Guid Format in .net C#

Initially, I was using a wrong mechanism to validate a string to be in GUID format. I was doing the following:

string wrongString = String.Empty;
bool IsCorrectGuid = false;
try
{
    Guid guid = new Guid(wrongString);
    IsCorrectGuid = true;
}
catch(FormatException){}

However, try-catch is an expensive process so, if you have huge no. strings to validate and most of them will not be a Guid then, this is a very bad way of validation.

The correct way is to use Regex, and if you are working on .Net 4.0 or higher then, you can also use the Guid.TryParse method to achieve the same goal. Following I have demonstrated to validate the string in both ways.

Guid.TryParse

string correctString = Guid.NewGuid().ToString();
Guid guid;
bool guidResTrue = Guid.TryParse(correctString, out guid);

Regex

string correctString = Guid.NewGuid().ToString();

//returns true for correct format, case in-sensitive
Regex isGuid = new Regex(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$", RegexOptions.Compiled);
bool guidResTrue = isGuid.IsMatch(correctString.ToUpper());

Of course, Guid.TryParse should be the preferred way of doing it if, you’re using .Net 4.0 or higher.

Split a String to Array of Strings and Include the Delimiters using .NET C#

To also get the delimiter of the string after the split we’ll have to use Regex.Split. Look at the following code:
string input = "SomeText,SomeText,SomeText,SomeText,SomeText,SomeText"; 
string pattern = "(,)";
string[] substrings = Regex.Split(input, pattern);

OUTPUT
SomeText
,
SomeText
,
SomeText
,
SomeText
,
SomeText
,
SomeText

NOTE: If you remove the parentheses from the pattern, using just “,”, the delimiters will not be preserved.

You can get more info about Regex.Split here

Associate Tooltip with WinForm Controls C#

There’s no direct property like ToolTip is available in WinForm, so you have to create an instance of the ToolTip class and assign captions to the various controls of the form using the same object.

private void Form1_Load(object sender, EventArgs e)
{
         // Create the ToolTip and associate with the Form container.
         ToolTip toolTip = new ToolTip();

         // Set up the delays for the ToolTip.
         toolTip.AutoPopDelay = 5000;
         toolTip.InitialDelay = 1000;
         toolTip.ReshowDelay = 500;
         // Force the ToolTip text to be displayed whether or not the form is active.
         toolTip.ShowAlways = true;

         // Set up the ToolTip text for the Button and Checkbox.
         toolTip.SetToolTip(this.button1, "My button1");
         toolTip.SetToolTip(this.checkBox1, "My checkBox1");
}

Get the Current Screen Size for WinForms C#

We’re gonna use the .net Screen class here. There are two aspects here.

Full Screen Size

int screenWidth = Screen.PrimaryScreen.Bounds.Width;
int screenHeight = Screen.PrimaryScreen.Bounds.Height;

Available Screen Size

int screenWidth = Screen.PrimaryScreen.WorkingArea.Width;
int screenHeight = Screen.PrimaryScreen.WorkingArea.Height; 

Stop/Prevent Browser from Caching the current Page

protected void StopPageCaching()
{
    HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
    HttpContext.Current.Response.Cache.SetValidUntilExpires(false);
    HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    HttpContext.Current.Response.Cache.SetNoStore();
}