WinApi – GetLastError vs. Marshal.GetLastWin32Error

You must always use the Marshal.GetLastWin32Error. The main problem is the garbage collector. If it runs between the call of SetVolumeLabel and the call of GetLastError then you will receive the wrong value, because the GC has surely overwritten the last result. Therefore you always need to specify the SetLastError=true in the DllImport-Attribute: [DllImport(“kernel32.dll”, SetLastError=true)] … Read more

What is meant by “managed” vs “unmanaged” resources in .NET?

The term “unmanaged resource” is usually used to describe something not directly under the control of the garbage collector. For example, if you open a connection to a database server this will use resources on the server (for maintaining the connection) and possibly other non-.net resources on the client machine, if the provider isn’t written … Read more

Howto implement callback interface from unmanaged DLL to .net app?

You don’t need to use Marshal.GetFunctionPointerForDelegate(), the P/Invoke marshaller does it automatically. You’ll need to declare a delegate on the C# side whose signature is compatible with the function pointer declaration on the C++ side. For example: using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; class UnManagedInterop { private delegate int Callback(string text); private Callback mInstance; // … Read more

Memory Leak in C#

Event Handlers are a very common source of non-obvious memory leaks. If you subscribe to an event on object1 from object2, then do object2.Dispose() and pretend it doesn’t exist (and drop out all references from your code), there is an implicit reference in object1’s event that will prevent object2 from being garbage collected. MyType object2 … Read more

How to get parent process in .NET in managed way

Here is a solution. It uses p/invoke, but seems to work well, 32 or 64 cpu: /// <summary> /// A utility class to determine a process parent. /// </summary> [StructLayout(LayoutKind.Sequential)] public struct ParentProcessUtilities { // These members must match PROCESS_BASIC_INFORMATION internal IntPtr Reserved1; internal IntPtr PebBaseAddress; internal IntPtr Reserved2_0; internal IntPtr Reserved2_1; internal IntPtr UniqueProcessId; … Read more