1

似乎这个属性现在映射到 CoCreateInstanceFromApp 过滤掉你可以创建的 COM(基本上没用 - 没有第三方等)。

所以我想问你是否知道一些简单的方法来实例化已经存在并使用 GUID 在系统上注册的 COM?

我只设法做了这样的破解(但这非常麻烦,只是为了防止微软阻止我做我一直做的事情并且没有问题):

[ComVisible(true), ComImport,
 Guid("00000001-0000-0000-C000-000000000046"),
 InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IClassFactory
{
    [PreserveSig]
    int CreateInstance([In, MarshalAs(UnmanagedType.Interface)] object pUnkOuter,
                       ref Guid riid,
                       [Out, MarshalAs(UnmanagedType.Interface)] out object obj);

    [PreserveSig]
    int LockServer([In] bool fLock);
}

[DllImport("kernel32.dll")]
internal static extern IntPtr LoadLibrary(String dllname);
[DllImport("kernel32.dll")]
internal static extern IntPtr GetProcAddress(IntPtr hModule, String procname);

internal delegate int DllGetClassObjectDelegate([MarshalAs(UnmanagedType.LPStruct)] Guid clsid,[MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

void LoadItDamnit() {
    IntPtr dll = LoadLibrary(path);
    IntPtr proc = GetProcAddress(dll, "DllGetClassObject");

    var getClassObject = (DllGetClassObjectDelegate)Marshal.GetDelegateForFunctionPointer(proc, typeof(DllGetClassObjectDelegate));

    int hr = getClassObject(IMYLIB_GUID, IUNKNOWN_GUID, out oFactory);

    IClassFactory factory = oFactory as IClassFactory;

    if (factory == null)
    {
           if (oFactory != null) Marshal.ReleaseComObject(oFactory);
           throw new Exception("Could not QueryInterface for the IClassFactory interface");
    }

    Guid myGUID = typeof(IMyInterface).GetGUID();
    hr = factory.CreateInstance(null, ref myGUID, out oMyObj);

    _obj = oMyObj as IMyInterface;
 }

正如您所看到的,这需要在路径中包含 dll(或使用其他 API 来更改当前路径)以加载库,并且为了实现本来应该可用的东西有点太多的篡改......

如果有人知道一种更好的方法来实例化任何 COM 对象并更轻松地克服 Metro 的限制,我会买啤酒!

4

0 回答 0