我从一个非常复杂的客户端和服务器系统开始使用COM引用和其他东西,我一直在减少直到我意识到我甚至无法获得Microsoft示例代码来免费注册COM激活用C#编写的托管COM服务器。
服务器代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace ClassLibrary1
{
[Guid("A7AC6D8C-FF17-4D2C-A3B1-2C8690A8EA04")
,ComVisible(true)]
public interface IClass1
{
[DispId(1)]
string DummyFunction(string inputValue);
}
[Guid("81723475-B5E3-4FA0-A3FE-6DE66CEE211C"),
ClassInterface(ClassInterfaceType.None),
ComDefaultInterface(typeof(IClass1)),
ComVisible(true)]
public class Class1 : IClass1
{
public string DummyFunction(string inputValue)
{
return inputValue.Substring(0, 1) + " Inserted " + inputValue.Substring(1);
}
}
}
客户端VB6代码:
Dim c As ClassLibrary1.Class1
Set c = New Class1
MsgBox c.DummyFunction("Ben")
客户端C ++代码:
#include "stdafx.h"
#import <ClassLibrary1.tlb> raw_interfaces_only
using namespace ClassLibrary1;
int _tmain(int argc, _TCHAR* argv[])
{
IClass1Ptr p;
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
hr = CoCreateInstance(__uuidof(Class1), NULL, CLSCTX_INPROC_SERVER, __uuidof(IClass1), (void **)&p);
if (FAILED(hr))
{
_tprintf_s(_T("Error %x\n"), hr);
CoUninitialize();
return 1;
}
_bstr_t b = _T("Bobby");
BSTR b2;
p->DummyFunction(b, &b2);
wprintf_s(L"%s\n", b2);
p->Release();
CoUninitialize();
return 0;
}
当我删除所有Reg-Free COM代码并使用regasm / codebase注册ClassLibrary1.dll时,两个客户端都正常工作。
然后我取消注册ClassLibrary1,并尝试使用文件Project1.exe.manifest为VB6客户端引入Reg-Free COM:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="Project1" version="1.0.0.0" />
<dependency>
<dependentAssembly>
<assemblyIdentity name="ClassLibrary1" version="1.0.0.0" />
</dependentAssembly>
</dependency>
</assembly>
和ClassLibrary1.manifest:
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="ClassLibrary1" />
<clrClass clsid="{81723475-B5E3-4FA0-A3FE-6DE66CEE211C}" name="ClassLibrary1.Class1" tlbid="{F8A2D334-5BBB-4007-8308-A1417052E6D6}"></clrClass>
<file name="ClassLibrary1.dll" ></file>
</assembly>
现在我有时会得到错误429(ActiveX组件无法创建对象),并且(莫名其妙地)有时会出现自动化错误:
运行时错误'-2146234304(80131040)': 自动化错误
现在,当我运行C ++客户端时,输出只是
错误800401f9
答案 0 :(得分:1)
令我感到沮丧的是,BlueMonkMN的解释非常有用,但我遇到了Class not registered
消息。
我有一个.NET 4.6 COM互操作Dll和一个C ++客户端,它通过Windows SxS技术使用免注册COM。程序集清单嵌入在COM Dll中,应用程序清单放在外面,作为单独的.manifest文件。
所有内容都按宣传的方式运行,但在Class not registered
期间发生CreateInstance
消息时,会发生以下任何一种情况。
在这种情况下,为了加重伤害,sxstrace
日志为空,应用程序事件日志(eventvwr
)没有报告任何SideBySide错误和程序集绑定日志查看器({{ 1}})没有显示C ++客户端应用程序中的任何内容。
让我在BlueMonkMN的回答中添加另一个附录。
我从目前为止的实验中了解到,在这种情况下,C ++客户端应用程序的激活上下文未被创建。
在这种情况下,需要自己创建激活上下文。
在调用FUSLOGVW.exe
之后和拨打CoInitialize(0);
之前,将以下代码放入C ++客户端应用程序中。
CreateInstance
作为一种清理措施,在调用ACTCTX context;
memset(&context, 0, sizeof(context));
context.cbSize = sizeof(context);
context.lpSource = L"CPPClient.exe.manifest";
context.lpAssemblyDirectory = L"D:\\code\\vs2017\\CPPClient\\Debug";
context.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
HANDLE hActCtx = CreateActCtx(&context);
ULONG_PTR cookie = 0;
BOOL result = ActivateActCtx(hActCtx, &cookie);
//Rest of the code goes here.
CoUninitialize();
现在听起来不错。 Side by Side工作得非常好。如果出现任何问题,可以在sxstrace或应用程序事件日志或程序集绑定日志查看器中看到它。