2011

You are browsing the site archives for 2011.

Have you ever wondered whether it is possible to create your own collection initializers just like for the List<T>?

var list = new List { 12, 42, 256, 1024 };

Well… doing that is actually extremely simple. All your custom object needs is a public Add method that takes whatever arguments you might want. Don’t try to analyze the code, I know that it doesn’t make any sense at all – it’s just an example

public class MyCollection : IEnumerable
{
	private List _list = new List();

	public void Add(Predicate predicate, T trueValue, T falseValue)
	{
		_list.Add(new MyIfThen { Predicate = predicate, TrueValue = trueValue, FalseValue = falseValue });
	}

	public struct MyIfThen
	{
		public Predicate Predicate;
		public T TrueValue;
		public T FalseValue;
	}

	#region IEnumerable Members

	public IEnumerator GetEnumerator()
	{
		return _list.Select(ifthen => ifthen.TrueValue).GetEnumerator();
	}

	#endregion

	#region IEnumerable Members

	System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
	{
		GetEnumerator();
	}

	#endregion
}

...

var mine = new MyCollection
		   {
			   {i => i%2 == 0, 12, 42},
			   {i => i%3 == 0, 33, 66},
		   };

We started using the Razor View Engine from Microsoft in preparation to switch to MVC 4 sooner or later.

Here are some introductory links:
Introduction to Razor Syntax
Quick Syntax Reference

There is an small OpenSource Engine which uses the Razor Parsing from the MVC Framework. This Engine is called RazorEngine.
It is available from two sources, development continues on GitHub but the version there is currently very unstable.
Here are the links:
http://razorengine.codeplex.com (2.x, stable)
https://github.com/Antaris/RazorEngine (3+, early version)

While using the Version 2.1, I got an

Predefined type ‘Microsoft.CSharp.RuntimeBinder.Binder’ is not defined or imported

Exception.
This seems to be a bug with Version 2.1, here’s the Discussion about it.

Actually there’s a really small workaround for it:
Just call

bool loaded = typeof(Microsoft.CSharp.RuntimeBinder.Binder).Assembly != null;

before using

Razor.Parse

and you should be ready to go.

I spent some more Time improving the App.
It now injects a DLL which listens for the Window Activated Event and then closes it. It also listens for Skype Started Event and tries to close the Window and injects the DLL.

Since DLLs which should be injected can’t be in Managed Code, I had to go back to my C++ knowledge.

Here are the most important parts described:

The DLL
Well, instead of writing too much I’ll just post the complete code for the DLL:

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
#include <stdio.h>

HINSTANCE dllInstance;
HHOOK hookHandle;

// Search for the Window and Close it
void CloseWindow() {
	HWND hWnd = FindWindow("THomeForm", "Skype Home");
	if (hWnd != NULL) {
		SendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
	}
}

// Callback for the Timer
VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) {
	CloseWindow();
	KillTimer(NULL, 1);
}

// Callback for the Hook
LRESULT CALLBACK WindowHookProc(int code, WPARAM wParam, LPARAM lParam)
{
	if (code >= 0) {
		switch(code) {
			//case HCBT_ACTIVATE:
			//case HCBT_CREATEWND:
			//case HSHELL_WINDOWCREATED:
			case HSHELL_WINDOWACTIVATED:
				// Get the Class and the Title
				TCHAR className[255];
				TCHAR title[255];
				memset(className, 0, sizeof(className));
				memset(title, 0, sizeof(title));
				HWND window = (HWND)wParam;
				int ret = GetClassName(window, className, sizeof(className));
				ret = GetWindowText(window, title, sizeof(title));
				// Compare the Class and the Title
				if (strcmp(className, "THomeForm") == 0 && strcmp(title, "Skype Home") == 0) {
					// Success, Create a Timer to close the Window
					int m_LoadTimesTimerID = SetTimer(NULL, 1, 1000, TimerProc);
				}
			break;
		}
	}
	return CallNextHookEx(hookHandle, code, wParam, lParam);
}

extern "C" __declspec(dllexport) void InstallHook(int threadID) {
	int hookID = WH_CBT;
	hookID = WH_SHELL;
	if (threadID > 0) {
		hookHandle = SetWindowsHookEx(hookID, WindowHookProc, dllInstance, threadID);
	} else {
		hookHandle = SetWindowsHookEx(hookID, WindowHookProc, dllInstance, NULL);
	}
}

extern "C" __declspec(dllexport) void UninstallHook() {
	UnhookWindowsHookEx(hookHandle); 
}

BOOL WINAPI DllMain(__in  HINSTANCE hinstDLL, __in  DWORD fdwReason, __in  LPVOID lpvReserved) {
	dllInstance = hinstDLL;
	return TRUE;
}

Calling the unmanaged Code in the Managed C# App
As you see, there are two exported Functions in the DLL:
InstallHook and UninstallHook
To be able to call them, there are some Win32 Stuff and some delegates needed:

[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void InstallHook(int threadID);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void UninstallHook();

Here’s the Code to call the InstallHook:

public static void Install()
{
	IntPtr pDll = LoadLibrary(@"SkypeHomeCloserNativeHelper.dll");
	if (pDll == IntPtr.Zero)
	{
		MessageBox.Show("DLL not found");
	}
	else
	{
		IntPtr procAddress = GetProcAddress(pDll, "InstallHook");
		if (procAddress == IntPtr.Zero)
		{
			MessageBox.Show("Proc not found");
		}
		else
		{
			InstallHook install = (InstallHook)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(InstallHook));
			Process[] procList = Process.GetProcessesByName("Skype");
			if (procList.Length > 0)
			{
				int threadID = procList[0].Threads[0].Id;
				install(threadID);
			}
			bool result = FreeLibrary(pDll);
		}
	}
}

Here’s the Code to uninstall it:

public static void Remove()
{
	IntPtr pDll = LoadLibrary(@"SkypeHomeCloserNativeHelper.dll");
	if (pDll == IntPtr.Zero)
	{
		MessageBox.Show("DLL not found");
	}
	else
	{
		IntPtr procAddress = GetProcAddress(pDll, "UninstallHook");
		if (procAddress == IntPtr.Zero)
		{
			MessageBox.Show("Proc not found");
		}
		else
		{
			UninstallHook uninstall = (UninstallHook)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(UninstallHook));
			uninstall();
			bool result = FreeLibrary(pDll);
		}
	}
}

And here’s the compiled Tool:
SkypeHomeCloser_2.0

Sometimes you might want to listen for a Process Start and do some Actions.

To start listening, just run the following code:

public void StartProcessMonitoring()
{
	// Create event query to be notified within 1 second of a change in a service
	WqlEventQuery query = new WqlEventQuery("__InstanceCreationEvent", new TimeSpan(0, 0, 1), "TargetInstance isa \"Win32_Process\"");

	// Create the Watcher
	watcher = new ManagementEventWatcher();
	watcher.Query = query;
	watcher.EventArrived += new EventArrivedEventHandler(ProcessStartEvent);
	watcher.Start();
}

The callback could then look like this:

public static void ProcessStartEvent(object sender, EventArrivedEventArgs e)
{
	ManagementBaseObject targetInstance = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;
	string processName = targetInstance.Properties["Name"].Value.ToString();
	if (processName == "myprocess.exe")
	{
		// Do whatever you want
	}
}

I created a member for the watcher Object

ManagementEventWatcher watcher;

and closed it when the App closes, otherwise I got a COM Error or something.
Here’s the cleanup Code:

watcher.Stop();
watcher.Dispose();

I hate that Home Screen which pops up on every Skype start. I really do…
So I created a small Tray Icon app which looks for this Window and closes it immediately.

As usual, there is some Win32 API needed to do this. Here’s the Code which searches and closes the Window:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string strClassName, string strWindowName);
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

public const Int32 WM_SYSCOMMAND = 0x0112;
public const Int32 SC_CLOSE = 0xF060;

public static void Close()
{
	IntPtr hWnd = FindWindow("THomeForm", "Skype Home");
	if (hWnd.ToInt32() > 0)
	{
		SendMessage(hWnd, WM_SYSCOMMAND, new IntPtr(SC_CLOSE), IntPtr.Zero);
	}
}

Here’s the programm: SkypeHomeCloser_1.0

Code printed in Visual Studio 2010 is not colored.
To enable this “feature”, you have to install this Extension.
Be aware that you can’t collapse regions for printing with this Extension.
Furthermore, if you wan’t line numbers, you have to enable them via Tools->Options.

I have recently run into a very peculiar problem: After the switch to .NET 4, our company website started reporting strange errors. The exception message reads as follows

The page is performing an async postback but the ScriptManager.SupportsPartialRendering property is set to false. Ensure that the property is set to true during an async postback.

And even weirder is that after some investigation and adding some debug information to the exception log it became clear that all those exceptions were “caused” by Safari UserAgent strings (iPhone, iPad, …) that according to the ASP.NET browser capabilities were “recognized” as “Mozilla 0.0” Browsers with basically no capabilities whatsoever. Continue reading ASP.NET 4 BrowserCaps (or: what were they thinking?)