public
Last active

COM without registering

  • Download Gist
ComWithoutRegistering.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
 
namespace ComWithoutRegisteringExample
{
internal static class ComHelper
{
private delegate int DllGetClassObject(ref Guid clsid, ref Guid iid, [Out, MarshalAs(UnmanagedType.Interface)] out IClassFactory classFactory);
 
internal static object CreateInstance(LibraryModule libraryModule, Guid clsid)
{
var classFactory = GetClassFactory(libraryModule, clsid);
var iid = new Guid("00000000-0000-0000-C000-000000000046"); // IUnknown
object obj;
classFactory.CreateInstance(null, ref iid, out obj);
return obj;
}
 
internal static IClassFactory GetClassFactory(LibraryModule libraryModule, Guid clsid)
{
IntPtr ptr = libraryModule.GetProcAddress("DllGetClassObject");
var callback = (DllGetClassObject) Marshal.GetDelegateForFunctionPointer(ptr, typeof (DllGetClassObject));
 
var classFactoryIid = new Guid("00000001-0000-0000-c000-000000000046");
IClassFactory classFactory;
var hresult = callback(ref clsid, ref classFactoryIid, out classFactory);
 
if (hresult != 0)
{
throw new Win32Exception(hresult, "Cannot create class factory");
}
return classFactory;
}
}
 
 
[Guid("00000001-0000-0000-c000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
internal interface IClassFactory
{
void CreateInstance([MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppvObject);
void LockServer(bool fLock);
}
 
internal class LibraryModule : IDisposable
{
private readonly IntPtr _handle;
private readonly string _filePath;
 
private static class Win32
{
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
 
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
 
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadLibrary(string lpFileName);
}
 
 
public static LibraryModule LoadModule(string filePath)
{
var libraryModule = new LibraryModule(Win32.LoadLibrary(filePath), filePath);
if (libraryModule._handle == IntPtr.Zero)
{
int error = Marshal.GetLastWin32Error();
throw new Win32Exception(error, "Cannot load library: " + filePath);
}
 
return libraryModule;
}
 
private LibraryModule(IntPtr handle, string filePath)
{
_filePath = filePath;
_handle = handle;
}
 
~LibraryModule()
{
if (_handle != IntPtr.Zero)
{
Win32.FreeLibrary(_handle);
}
}
 
public void Dispose()
{
if (_handle != IntPtr.Zero)
{
Win32.FreeLibrary(_handle);
}
GC.SuppressFinalize(this);
}
 
public IntPtr GetProcAddress(string name)
{
IntPtr ptr = Win32.GetProcAddress(_handle, "DllGetClassObject");
if (ptr == IntPtr.Zero)
{
int error = Marshal.GetLastWin32Error();
string message = string.Format("Cannot find proc {0} in {1}", name, _filePath);
throw new Win32Exception(error, message);
}
return ptr;
}
 
public string FilePath
{
get { return _filePath; }
}
}
}

Does not works for me.

Run this after installing AutoItX

            var clsid = new Guid("{1A671297-FA74-4422-80FA-6C5D8CE4DE04}");
            var module = ComWithoutRegisteringExample.LibraryModule.LoadModule(Path.Combine(Environment.CurrentDirectory,"AutoItX3.dll"));
            var rg = ComWithoutRegisteringExample.ComHelper.CreateInstance(module, clsid);
            rg.GetType().InvokeMember("Run", BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, (Binder)null, rg, new object[] { "Notepad" });

Will launch notepad.

Run

regsvr32 AutoItX3.dll /u

Will create object but will fail to invoke with (on last line):
Library not registered. (Exception from HRESULT: 0x8002801D (TYPE_E_LIBNOTREGISTERED))

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.