Well I can't find any C# code on this but I did find C++ code on it which works. I tried converting to C# but it doesn't work. It writes the dlls data into memory fine but createremotethread is where I think it is having a problem.

here is the C++ code.

Code:
#include <windows.h>
BOOL InjectLibrary(HWND wnd, DWORD dwProcessId, char * szInjectDll )
{
	LPVOID 	lpRemoteAddress 	= 0;
	HANDLE 	hProcess 			= 0;
	HANDLE 	hRemoteThread		= 0;
	HMODULE hKernel32 			= 0;
	DWORD	dwSize				= strlen(szInjectDll);
	DWORD	dwSizeWritten		= 0; 
	BOOL	bInjected			= 0;
	
	if(IsWindow(wnd))
	{
		GetWindowThreadProcessId(wnd, &dwProcessId);//we need the processid
	}
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);//so we can open it
	lpRemoteAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);//allocate a buffer in the remote process
	bInjected = WriteProcessMemory(hProcess, lpRemoteAddress, (LPVOID)szInjectDll, dwSize, &dwSizeWritten);//write the dll name in it
	if(bInjected)
	{
		hKernel32 = GetModuleHandle("KERNEL32.DLL");//get handle to this module
		if(!hKernel32)
		{
			hKernel32 = GetModuleHandle("kernel32.dll");
		}											//cause we want the function "LoadLibrary"..now create remote thread, that loads our dll, and starts its thread
		hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryA"), lpRemoteAddress, 0, NULL);
	}
	return bInjected;//exit and return true if we could load it
}
And my attempt at converting it.

Code:
        [DllImport("user32")]
        public static extern int GetWindowThreadProcessId(int hwnd, ref int lpdwProcessId);
        [DllImport("kernel32.dll")]
        private static extern int OpenProcess(int dwDesiredAccess, int bInheritHandle, int dwProcessId);
        [DllImport("kernel32.dll")]
        private static extern int VirtualAllocEx(int hProcess, int lpAddress, int dwSize, int flAllocationType, int flProtect);
        [DllImport("kernel32.dll")]
        public static extern Int32 WriteProcessMemory(
            IntPtr hProcess,
            IntPtr lpBaseAddress,
            [In, Out] byte[] buffer,
            UInt32 size,
            out IntPtr lpNumberOfBytesWritten);  
        [DllImport("kernel32.dll", EntryPoint = "GetModuleHandleA")]
        private static extern int GetModuleHandle(string lpModuleName);
        [DllImport("kernel32")]
        public static extern IntPtr CreateRemoteThread(
          IntPtr hProcess,
          IntPtr lpThreadAttributes,
          uint dwStackSize,
          IntPtr lpStartAddress, // raw Pointer into remote process
          IntPtr lpParameter,
          uint dwCreationFlags,
          out uint lpThreadId
        );
        [DllImport("kernel32.dll")]
        private static extern int GetProcAddress(int hModule, string lpProcName);
        static bool InjectDll(int ID, string dllpath)
        {
            IntPtr written;
            int size = (int)(new FileInfo(dllpath).Length);
            byte[] dllbytes = File.ReadAllBytes(dllpath);
            int hprocess = OpenProcess(PROCESS_ALL_ACCESS, 0, ID);
            int lpRemoteAddress = VirtualAllocEx(hprocess, 0, size, 0x1000, 4);
            WriteProcessMemory((IntPtr)hprocess, (IntPtr)lpRemoteAddress, dllbytes, (uint)size, out written);
            if (dllbytes.Length == (int)written)
            {
                uint temp;
                IntPtr hRemoteThread = CreateRemoteThread((IntPtr)hprocess, IntPtr.Zero, 0, (IntPtr)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"), (IntPtr)lpRemoteAddress, 0, out temp);
            }
            else
            {
                return false;
            }
            return true;
        }
When I go through debugging it it seems like everything is working but it just isn't loading the dll with the remote thread.