woensdag 15 december 2010

C# - create an instance of any non-static class

For testing purposes you may want to create an instance of a type that does not have any public constructors, or an instance of a type that only has complex constructors requiring parameters you'd rather not pollute your test with. If, additionally, you're also not concerned about initialization of the instance (or you're content with taking care of it next) here's a trick that may save you some odd hours trying to get all the parameters for that complex constructor or produce some complex bit of Reflection to call that private constructor. You may want to try the FormatterServices.GetUninitializedObject function:

using System.Runtime.Serialization;
/// <summary>
/// Gets an uninitialized instance of type T
/// </summary>
/// <typeparam name="T">Type of object to create an uninitialized instance from</typeparam>
/// <returns>Uninitialized instance of type T</returns>
/// <remarks>BEWARE: no constructors are called when creating the instance of type T, it will be uninitialized and invalid</remarks>
public static T GetUninitializedObject<T>() where T : class
{
    return FormatterServices.GetUninitializedObject(typeof(T)) as T;
}

nunit - ignore a test at runtime

There are 4 exceptions that nunit uses to tell the result of a test. These are: TimeoutException, AssertException, SuccessException, and IgnoreException. You can use these from within your nunit test functions, but for the IgnoreException there's also an attribute to decorate your test function with. However, you use the attribute to ignore a test function if you knew in advance it was supposed to be ignored. But if you don't happen to know if you want to ignore / skip a test function beforehand you may want to ignore a test at runtime instead. So use the IgnoreException to break off your test if, while running the test, you find out it had better be skipped.

dinsdag 14 december 2010

C# - generate and start a process (EXE) on the fly

The Emit namespace can be used to generate and start processes on the fly (among other things). Here's a short example:


        public static Process GenerateRuntimeProcess(string processName, int aliveDuration, bool throwOnException = true)
        {
            Process result = null;
            try
            {
                AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName() { Name = processName }, AssemblyBuilderAccess.Save);
                ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(processName, processName + ".EXE");
                TypeBuilder typeBuilder = moduleBuilder.DefineType("Program"TypeAttributes.Public);
                MethodBuilder methodBuilder = typeBuilder.DefineMethod("Main"MethodAttributes.Public | MethodAttributes.Static, nullnull);
                ILGenerator il = methodBuilder.GetILGenerator();
                il.UsingNamespace("System.Threading");
                il.EmitWriteLine("Hello World");
                il.Emit(OpCodes.Ldc_I4, aliveDuration);
                il.Emit(OpCodes.Call, typeof(Thread).GetMethod("Sleep"new Type[] { typeof(int) }));
                il.Emit(OpCodes.Ret);
                typeBuilder.CreateType();
                assemblyBuilder.SetEntryPoint(methodBuilder.GetBaseDefinition(), PEFileKinds.ConsoleApplication);
                assemblyBuilder.Save(processName + ".EXE"PortableExecutableKinds.Required32Bit, ImageFileMachine.I386);
                result = Process.Start(new ProcessStartInfo(processName + ".EXE")
                {
                    WindowStyle = ProcessWindowStyle.Hidden
                });
            }
            catch
            {
                if (throwOnException)
                {
                    throw;
                }
                result = null;
            }
            return result;
        }

To view IL code of existing .NET code use ildasm.exe, here is a nice example of how to use ildasm.exe from within Visual Studio.

C# - just 1 PInvoke to see if some window is fullscreen

Here's a quick summary:
1 Find the process (Process.Get...)
2 Get the process window area (PInvoke GetWindowRect)
3 Get the screen the process window is on (Screen.FromHandle)
4 Assert if the screen working area equals the process window area

But beware, toolbars and the taskbar affect the screen working area. The screen working area equals the screen bounds if no toolbars are present and the taskbar is on autohide. To see if the taskbar is on autohide or toggle autohide use the Windows 7 Code Pack.

And here's a short example:
            if (process != null && !process.HasExited)
            {
                RECT rect = new RECT();
                if (GetWindowRect(new HandleRef(process, process.MainWindowHandle), out rect))
                {
                    windowArea = new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
                    screenArea = Screen.FromHandle(process.MainWindowHandle).WorkingArea;
                    result = windowArea.Equals(screenArea);
                    logger.Trace("Window area [" + windowArea + "] " + (result ? "equals" : "does NOT equal") + " screen area [" + screenArea + "]");
                }
                else
                {
                    logger.DebugException("Failed to obtain window area for process with exception",
                        new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()));
                }
            }

vrijdag 10 december 2010

C# - remoting on dual-homed PCs

The following I copied from an old blog somewhere else.

Dual-homed PCs are PCs with 2 NICs (a NIC is a Network Interface Connector
or network card). 1 NIC is configured for the LAN (with one or more private IPs).
The other NIC is configured for the internet (with a public IP).

Remoting works fine for PCs with a single NIC, but for dual-homed PCs there
is a catch: Remoting gets lost when trying to handshake with the source of the
message. It doesn't know which IP and which NIC to use for return communication so
it uses a broadcast IP to no avail.

According to Microsoft documentation remoting can be bound to a specific IP
using the bindTo property. But for TCP remoting this doesn't work, it just generates a socket
exception. Fortunately remoting can also be bound to a machine by name.

But only for HTTP remoting according to Microsoft documentation. Guess again. It does work for TCP remoting too. In fact, make sure your DNS can resolve $hostName and we're as good as
done. Just add machineName="$hostName" to your channel configuration.

Remoting now works on your dual-homed PC. Enjoy.

C# - remoting and serialization

The following I copied from an old blog somewhere else.

Ever thought of using remoting to distribute your objects?
Ever thought of using serialization to persist your objects?
Ever thought of combining the two?

You might want to read this first.

To use your objects for remoting you need to make them inherit from MarshalByRefObject.
That's perfectly serializable as long as your objects are not used accross application domain boundaries.
In other words, that's perfectly serializable as long as you don't use them for remoting (how convenient!).

Because if you ever do, the private MarshalByRefObject.ServerIdentity gets set. And it isn't serializable.

There are articles on this issue all over the internet. In fact, Microsoft acknowledges the issue but refuses to fix it. If you want to read more try reading the article titled "Serialization of MarshalByRefObject fails after a remoting identity has been set" here: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=97623
A lot of articles on this issue focus on bringing a fix for the issue. I feel they might be missing the obvious. Persistence is about preserving an object's state at a certain moment in time. But does it have to be instantaneous?
So persisting an object used for remoting fails. But persisting an object not used for remoting succeeds. That may sound pretty useless, but remember, your object initially hasn't been used for remoting yet. So if you only ever had to persist objects not used for remoting yet you'd be fine.
Let's do that. Add a copy constructor to your class that inherits from MarshalByRefObject and needs persistence. If you need to persist such an object call the copy constructor to create a new one and use that object for serialization. MarshalByRefObject.ServerIdentity hasn't been set on the new object yet because it hasn't been used for remoting yet.
Fixed.

C++ - see if a file exists without opening it

Opening files can have quite an effect on performance. So if you just want to know if a file is there you might not want to open it. Instead you could use the _access method to see if a file exists. More information can be found on MSDN here http://msdn.microsoft.com/en-us/library/1w06ktdy(v=VS.71).aspx
If the method returns a -1 and errno is set to ENOENT then the file does not exist. Set the mode parameter of the _access method to 0 to check for existence only.

C# - easily get the message of a windows error code

I've seen a lot of posts online of people asking how to get the error message associated with a Windows error code. I've also seen a lot of posts online of people proposing some horribly difficult solution. So here's a nice and simple one I happened to stumble upon:
string win32ErrorMessage = new System.ComponentModel.Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error()).Message;