I have a need to register some COM DLLs from a C# program. Every example I found on the web used regsvr32 to perform the registration. This didn't make much sense to me as all regsvr32 does is call DllRegisterServer() exported in the DLL. So I worked out how to do the same from C# using P/Inovke and System.Runtime.InteropServices.
And here it is for you to use. This is a small sample but it compiles and registers the DLLs that are listed on the command line. Be sure to compile with the /unsafe switch. Also, I have more error checking and reporting in my application which I removed from this sample. Enjoy!
1: using System;
2: using System.Runtime.InteropServices;
3:
4: public class RegisterDll
5: {
6: unsafe internal delegate UInt32 DllRegisterServer();
7:
8: public static void Main(string[] args)
9: {
10: foreach (string file in args)
11: {
12: Console.WriteLine("Registering {0}", file);
13: RegisterCOMDll(file);
14: }
15:
16: Console.WriteLine("Done!");
17: }
18:
19: private static void RegisterCOMDll(string file)
20: {
21: IntPtr library = LoadLibraryEx(file, IntPtr.Zero, 0);
22: if (library == IntPtr.Zero)
23: {
24: string msg = "Unable to load '" + file + "' error is " + Marshal.GetLastWin32Error().ToString();
25: throw new ApplicationException(msg);
26: }
27:
28: IntPtr proc = GetProcAddress(library, "DllRegisterServer");
29: if (proc == IntPtr.Zero)
30: {
31: int err = Marshal.GetLastWin32Error();
32: string msg = "Unable to load 'DllRegisterServer' from '" + file + "' error is " + err.ToString();
33: throw new ApplicationException(msg);
34: }
35:
36: DllRegisterServer drs = (DllRegisterServer)Marshal.GetDelegateForFunctionPointer(proc, typeof(DllRegisterServer));
37: UInt32 result = drs();
38: if (result != 0)
39: {
40: string msg = "Error " + result.ToString() + " returned from DllRegisterServer in " + file;
41: throw new ApplicationException(msg);
42: }
43:
44: FreeLibrary(library);
45: }
46:
47: [Flags]
48: public enum LoadLibraryFlags : uint
49: {
50: DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
51: LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
52: LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
53: LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008,
54: }
55:
56: [DllImport("kernel32.dll", EntryPoint = "FreeLibrary", SetLastError = true)]
57: public static extern bool FreeLibrary(IntPtr hModule);
58:
59: [DllImport("kernel32.dll", EntryPoint = "LoadLibraryExW", CharSet = CharSet.Unicode, SetLastError = true)]
60: public static extern IntPtr LoadLibraryEx(
61: [MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
62: IntPtr hFile,
63: [MarshalAs(UnmanagedType.U4)] LoadLibraryFlags dwFlags);
64:
65: [DllImport("kernel32.dll", CharSet = CharSet.Ansi, EntryPoint = "GetProcAddress", ExactSpelling = true, SetLastError = true)]
66: public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
67: }

0 comments:
Post a Comment