似乎这个属性现在映射到 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 的限制,我会买啤酒!