[COM] COM服务器多次启动 [英] [COM] COM-server starting multiple times

查看:133
本文介绍了[COM] COM服务器多次启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好

我的进程外COM服务器有问题.我将DLL注入到外部进程中,并且该DLL将某些类注册为本地服务器.这是通过以下方式完成的:
1.对于每个对象,将创建以下注册表项:
HKLM\SOFTWARE\Classes\CLSID\{GUID OF CLASS}\LocalServer32及其默认值设置为外部进程的可执行文件的路径.

2.对于每个对象,CoRegisterClassObject的调用方式如下:
CoRegisterClassObject(riid, static_cast<IUnknown*>(factory), CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &token);到目前为止,此调用始终返回S_OK.

3.在注册所有对象之后,调用CoResumeClassObjects并进入消息循环.

现在,使用中的应用程序要创建这样的对象,并使用CLSCTX_LOCAL_SERVER调用CoCreateInstance.即使外来进程正在运行并且已经注册了其对象,该过程也会再次启动(至少这意味着该对象已正确放入注册表中),并且该请求不会发送到已经运行的对象.但是,这种行为的原因是什么呢?我是否忘记了告诉操作系统我的对象可用的信息?

在旁注中还有另一件事.如果我删除消息循环并按以下方式用WaitForSingleObject替换它:

Hello guys

I have a problem with an out of process COM-server. I inject a DLL into a foreign process and this DLL registers some Classes as local servers. This is done in the following way:
1. For each object the following registry entries are created:
HKLM\SOFTWARE\Classes\CLSID\{GUID OF CLASS}\LocalServer32 and its default value is set to the path of the executable of the foreign process.

2. For each object CoRegisterClassObject is called like that:
CoRegisterClassObject(riid, static_cast<IUnknown*>(factory), CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &token); So far this call always returned S_OK.

3. After all objects are registered CoResumeClassObjects is called and the message loop is entered.

Now the consuming application wants to create such an object and calls CoCreateInstance with CLSCTX_LOCAL_SERVER. Even tough the foreign process is running and has registered its objects the process is started again (at least it means that the object was correctly put in the registry) and the request is not sent to the already running one. But whats the reason for that beahaviour? Did i forget something about telling the OS that my objects are available?

On a sidenote there is another weird thing. If i remove the message loop and replace it with a WaitForSingleObject in the following way:

HANDLE hEvent = NULL;
unsigned long __stdcall ServerThread(LPVOID)
{
	CoInitialize(NULL);
	REG_CLASS(TestClass);
	CoResumeClassObjects();
	MSG msg;
	hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	/*while(GetMessage(&msg, 0, 0, 0) > 0)
	{
		std::cout << msg.message << std::endl;
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}*/
	std::cout << "Waiting for event" << std::endl;
	WaitForSingleObject(hEvent, INFINITE);
	std::cout << "Event set!" << std::endl;
	UNREG_CLASS(TestClass);
	ExitThread(0);
}



并尝试像这样在DllMain中进行设置:



And try to set it in DllMain like that:

BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
{
	if(reason == DLL_PROCESS_DETACH)
	{
		if(hEvent != NULL)
		{
			SetEvent(hEvent);
			std::cin.get();
		}
	}
	return TRUE;
}



我得到它等待事件的输出,以及其他输出,我也看到SetEvent返回TRUE,但是"Event set"从不输出到控制台.为什么该活动无法正常进行?我还检查了事件是否相同.

感谢您的帮助
Regner



I get the output that its waiting for the event and with other outputs i also see that SetEvent returns TRUE but "Event set" is never printed to the console. Why is the event not working? I also checked that the events are the same and they are.

Thanks for any help
Regner

推荐答案

好吧,我对问题的临时"解决方案如下:
问题是我以管理员和消费者客户端的身份像调用者一样开始了我的国外流程.如果我以调用者身份启动外部进程,它将被检测到并且请求将延迟到该进程.

我想我必须提供某种安全性选项,以允许较低级别的进程连接到我的进程.还是用UAC不可能?
Well, my own "temporary" solution to the problem is the following:
The problem was that i started my foreign process as administrator and the consumer client just as invoker. If i start the foreign process as invoker it gets detected and requests are delagated to it.

I guess that i have to provide some sort of security options allowing processes on lower levels to connect to my process. Or is that impossible with UAC?


目前还不清楚hEvent的来源在您的DllMain中.您不能在进程之间共享本地句柄.您应该按名称创建事件对象,这应该可以工作.
It is really unclear where the hEvent comes from in your DllMain. You cannot share local handles between processes. You should create the event object by name and this should work.
// exe
HANDLE h = CreateEvent(0,0,0,AnyGuid());
WaitForSingleObject(h,INFINITE);
CloseHandle(h);


// dll
HANDLE h = CreateEvent(0,0,0,SameGuidAsEXE());
SetEvent(h);
CloseHandle(h);



问候.



regards.


这篇关于[COM] COM服务器多次启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆