Registering an ActiveX DLL or OCX
-
Does anyone know how I can Register an ActiveX DLL or OCX using .NET Code? I don't care if it's Managed or UnManaged. Thanks!
You could try:
System.Diagnostics.Process.Start("regsvr32.exe",
string.Format("/s \"{0}\"", Path To Dll or OCX))You can't always guarantee that the user will have
regsvr32.exe
on their machine, though. If you know the file you want to register at compile time, you could use:[System.Runtime.InteropServices.DllImport("Dll or OCX name", EntryPoint="DllRegisterServer")]
static extern int RegisterMyDll();
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
You could try:
System.Diagnostics.Process.Start("regsvr32.exe",
string.Format("/s \"{0}\"", Path To Dll or OCX))You can't always guarantee that the user will have
regsvr32.exe
on their machine, though. If you know the file you want to register at compile time, you could use:[System.Runtime.InteropServices.DllImport("Dll or OCX name", EntryPoint="DllRegisterServer")]
static extern int RegisterMyDll();
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
This is what I ended up doing but I had hoped someone could tell me why the following Code will not work!? I had code to do this and it works great in VB6! However, for some reason, .NET cannot get the "Address" of the Entry point for "DllRegisterServer" in my DLL (even though I know it is there)...it ALWAYS Returns "0". I will not know the name of the DLL ahead of time, so although I like your idea, it won't work in this situation. Below is my code, taken from the API Guide example. The MSDN Help shows a different example (do a Search on "Register") of the Source Code of "Regsvr32.exe" but that does not work either, instead it just GPFs on me. However, even that code works in VB6. Sorry for the VB references but it is what I had before and I am trying to convert it to C#. 'Declarations Private Declare Auto Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Integer) As Integer Private Declare Ansi Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Integer Private Declare Auto Function GetProcAddress Lib "kernel32" (ByVal hModule As Integer, ByVal lpProcName As String) As IntPtr Private Declare Ansi Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal PrevWndFunc As IntPtr, ByVal hWnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer Public Sub RegisterFile(ByVal File As String) Dim hLib, hResult As Integer Dim hAddress As IntPtr hLib = Me.LoadLibrary(_Path) hAddress = Me.GetProcAddress(hLib, "DllRegisterServer") hResult = Me.CallWindowProc(hAddress, 0, 0, 0, 0) hResult = Me.FreeLibrary(hLib) End Sub
-
This is what I ended up doing but I had hoped someone could tell me why the following Code will not work!? I had code to do this and it works great in VB6! However, for some reason, .NET cannot get the "Address" of the Entry point for "DllRegisterServer" in my DLL (even though I know it is there)...it ALWAYS Returns "0". I will not know the name of the DLL ahead of time, so although I like your idea, it won't work in this situation. Below is my code, taken from the API Guide example. The MSDN Help shows a different example (do a Search on "Register") of the Source Code of "Regsvr32.exe" but that does not work either, instead it just GPFs on me. However, even that code works in VB6. Sorry for the VB references but it is what I had before and I am trying to convert it to C#. 'Declarations Private Declare Auto Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Integer) As Integer Private Declare Ansi Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Integer Private Declare Auto Function GetProcAddress Lib "kernel32" (ByVal hModule As Integer, ByVal lpProcName As String) As IntPtr Private Declare Ansi Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal PrevWndFunc As IntPtr, ByVal hWnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer Public Sub RegisterFile(ByVal File As String) Dim hLib, hResult As Integer Dim hAddress As IntPtr hLib = Me.LoadLibrary(_Path) hAddress = Me.GetProcAddress(hLib, "DllRegisterServer") hResult = Me.CallWindowProc(hAddress, 0, 0, 0, 0) hResult = Me.FreeLibrary(hLib) End Sub
I think we're looking at the same sample! :) This code seems to work for me:
using System;
using System.Runtime.InteropServices;class ComUtils
{
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string fileName);\[DllImport("kernel32.dll")\] private static extern int FreeLibrary(IntPtr hModule); \[DllImport("kernel32.dll")\] private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); \[DllImport("user32.dll")\] private static extern int CallWindowProc( IntPtr lpPrevWndFunction, int hWnd, int msg, int wParam, int lParam); public static bool RegisterServer(string path) { IntPtr hModule = LoadLibrary(path); if (IntPtr.Zero == hModule) { // Failed to load return false; } try { IntPtr register = GetProcAddress(hModule, "DllRegisterServer"); if (IntPtr.Zero == register) { // Failed to find entry-point return false; } else { int ret = CallWindowProc(register, 0, 0, 0, 0); if (0 == ret) return true; else return false; } } finally { FreeLibrary(hModule); } }
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
This is what I ended up doing but I had hoped someone could tell me why the following Code will not work!? I had code to do this and it works great in VB6! However, for some reason, .NET cannot get the "Address" of the Entry point for "DllRegisterServer" in my DLL (even though I know it is there)...it ALWAYS Returns "0". I will not know the name of the DLL ahead of time, so although I like your idea, it won't work in this situation. Below is my code, taken from the API Guide example. The MSDN Help shows a different example (do a Search on "Register") of the Source Code of "Regsvr32.exe" but that does not work either, instead it just GPFs on me. However, even that code works in VB6. Sorry for the VB references but it is what I had before and I am trying to convert it to C#. 'Declarations Private Declare Auto Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Integer) As Integer Private Declare Ansi Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Integer Private Declare Auto Function GetProcAddress Lib "kernel32" (ByVal hModule As Integer, ByVal lpProcName As String) As IntPtr Private Declare Ansi Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal PrevWndFunc As IntPtr, ByVal hWnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer Public Sub RegisterFile(ByVal File As String) Dim hLib, hResult As Integer Dim hAddress As IntPtr hLib = Me.LoadLibrary(_Path) hAddress = Me.GetProcAddress(hLib, "DllRegisterServer") hResult = Me.CallWindowProc(hAddress, 0, 0, 0, 0) hResult = Me.FreeLibrary(hLib) End Sub
Add
CharSet=CharSet.Auto
and/orCallingConvention=CallingConvention.CDecl
to the DllImport attribute to make sure the unmangled DllRegisterServer vtable function is accessible from the outside. -
Add
CharSet=CharSet.Auto
and/orCallingConvention=CallingConvention.CDecl
to the DllImport attribute to make sure the unmangled DllRegisterServer vtable function is accessible from the outside. -
I think we're looking at the same sample! :) This code seems to work for me:
using System;
using System.Runtime.InteropServices;class ComUtils
{
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string fileName);\[DllImport("kernel32.dll")\] private static extern int FreeLibrary(IntPtr hModule); \[DllImport("kernel32.dll")\] private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); \[DllImport("user32.dll")\] private static extern int CallWindowProc( IntPtr lpPrevWndFunction, int hWnd, int msg, int wParam, int lParam); public static bool RegisterServer(string path) { IntPtr hModule = LoadLibrary(path); if (IntPtr.Zero == hModule) { // Failed to load return false; } try { IntPtr register = GetProcAddress(hModule, "DllRegisterServer"); if (IntPtr.Zero == register) { // Failed to find entry-point return false; } else { int ret = CallWindowProc(register, 0, 0, 0, 0); if (0 == ret) return true; else return false; } } finally { FreeLibrary(hModule); } }
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
Add
CharSet=CharSet.Auto
and/orCallingConvention=CallingConvention.CDecl
to the DllImport attribute to make sure the unmangled DllRegisterServer vtable function is accessible from the outside.Well, I've tried it all and it still doesn't work! The "GetProcAddress" still returns "0" as if it's not even recognizing that there is a function called "DllRegisterServer" which is impossible because if I open the DLL using WordPad I can find that exact text in there. Here's what I've got so far: 'API Declarations Private Declare Auto Function FreeLibrary Lib "kernel32.dll" (ByVal hLibModule As IntPtr) As Integer Private Declare Ansi Function LoadLibrary Lib "kernel32.dll" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As IntPtr _ Private Function GetProcAddress2(ByVal hModule As IntPtr, ByVal lpProcName As String) As IntPtr End Function Private Declare Auto Function GetProcAddress Lib "kernel32.dll" (ByVal hModule As IntPtr, ByVal lpProcName As String) As IntPtr Private Declare Ansi Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal PrevWndFunc As IntPtr, ByVal hWnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer Public Function Register() As Boolean Dim hResult As Integer Dim hLib, hAddress As IntPtr hLib = Me.LoadLibrary(_Path) If (hLib.Equals(IntPtr.Zero)) Then Return False 'Failed to Load the Library Try 'Get the Address of the DllRegisterServer Function hAddress = Me.GetProcAddress2(hLib, "DllRegisterServer") If (hAddress.Equals(IntPtr.Zero)) Then Exit Try 'Execute the Function hResult = CallWindowProc(hAddress, 0, 0, 0, 0) Catch Finally 'Free the Library hResult = FreeLibrary(hLib) End Try End Function Any ideas?