如何让进程外COM只启动唯一实例?

时间:2022-08-29 18:47:57
使用ATL将类厂注册为MULTPLEUSER,在XP下正常,所有的client都会连接到一个COM实例上。
但是到了vista下,由于用户权限的问题,vista会自动的为在不同的上下文下的COM请求生成不同的实例,不知道如何解决。
初学COM,请高手指教!

80 个解决方案

#1


mark
只在xp环境下玩过,Vista环境不清楚
帮顶

#2


做成COM Server等,实现单例模式,其他的客户端请求,都由它处理...
来了请求第一个创建实例,后面请求,发现已经创建,就直接处理

#3


把进程外组件做成服务类型

#4


每日友情UP

#5


引用 2 楼 oyljerry 的回复:
做成COM Server等,实现单例模式,其他的客户端请求,都由它处理...
来了请求第一个创建实例,后面请求,发现已经创建,就直接处理

客户端的请求我只知道用CoCreateInstance来获得服务提供的接口,如何判断已经存在实例并获得接口呢?谢谢!

#6


引用 3 楼 jameshooo 的回复:
把进程外组件做成服务类型

做成服务就不会存在这个问题?一会试验一下 。不过如果可以的话,那不是就绕过了vista的安全机制?

#7


引用 3 楼 jameshooo 的回复:
把进程外组件做成服务类型

经过测试,做成服务结果也是一样的,还是会启动多个服务进程。

#8


引用 7 楼 flyhigh 的回复:
引用 3 楼 jameshooo 的回复:
把进程外组件做成服务类型

经过测试,做成服务结果也是一样的,还是会启动多个服务进程。

是否Regsvr32注册服务...

#9


关注一下

#10


引用 8 楼 oyljerry 的回复:
引用 7 楼 flyhigh 的回复:
引用 3 楼 jameshooo 的回复:
把进程外组件做成服务类型

经过测试,做成服务结果也是一样的,还是会启动多个服务进程。

是否Regsvr32注册服务...

注册了。如果不注册,那客户端就不可能引用了。

#11


mark。。。

#12


http://www.eggheadcafe.com/software/aspnet/29825236/singleton-against-win-vis.aspx
看看这个链接,他是通过CoInitializeSecurity解决了uac下的单实例问题。
也有人提出利用service来解决的方案。

#13


引用 12 楼 sgzwiz 的回复:
http://www.eggheadcafe.com/software/aspnet/29825236/singleton-against-win-vis.aspx
看看这个链接,他是通过CoInitializeSecurity解决了uac下的单实例问题。
也有人提出利用service来解决的方案。

都不行。

#14


程序里加个互斥

#15


程序里加互斥,启动的新的服务实例是可以关闭,但是client请求的接口没有得到。

#16


采用Moniker技术试试,在vista下,moniker技术有所不同

#17


关键问题不在服务器端,而在客户端口。客户端应当先调用GetActiveObject 来判断所请求的服务器端是否已经运行,如果已经运行,则 AttachDispatch, 否则的话 CreateDispatch. 参考代码:

CLSID clsidWMP;
LPDISPATCH pWMPDispatch = NULL;

AfxCheckError(::CLSIDFromProgID(_T("COMServer.application"), &clsidWMP));

IID_IDispatch, (LPVOID*)&pWMPDispatch);
LPUNKNOWN lpUnk;
HRESULT hr = ::GetActiveObject(clsidWMP, NULL, &lpUnk);
if (hr == NOERROR)
{
HRESULT hr = lpUnk->QueryInterface(IID_IDispatch,
(LPVOID*)&pWMPDispatch);
lpUnk->Release();
if (hr == NOERROR)
m_Comserver.AttachDispatch(pWMPDispatch, TRUE);
}
if (m_Comserver.m_lpDispatch == NULL)
{
m_Comserver.CreateDispatch(clsidWMP);
}

#18


我用过ROT,但是GetActiveObject返回“不能执行的操作”。不知道楼上的方法行不行,理论上应该也不行,因为没有解决vista的安全问题。

#19


mark

#20


做成Automation server可以么?

#21



路过路过路过

#22


研究一下

#23


只在xp环境下玩过,Vista环境不清楚

#24


做成COM Server等,实现单例模式,其他的客户端请求,都由它处理...
来了请求第一个创建实例,后面请求,发现已经创建,就直接处理
或者加一个互斥

#25


不懂。。。呵呵

#26


mark 帮顶

#27


路过,关注一下

#28


mark。。。

#29


该回复于2010-04-22 14:24:54被版主删除

#30


学习了

#31


thanks

#32


haoa

#33


哦,好的,明白了

#34


学习路过看看

#35


每日友情UP

#36


了解一下。。。

#37


 在UAC下似乎做不到.

#38


路过接分...

#39


ding

#40


   学习!!!!

#41


hao

#42


路过学习一下

#43


不错不错不错不错

#44


不错不错不错不错

#45


看看 ~~~~

#46


学习了。。

#47


顶下,先注册下

#48


顶顶顶顶顶顶顶顶顶

#49


不怎么理解            什么意思 

#50


我是来学习的

#1


mark
只在xp环境下玩过,Vista环境不清楚
帮顶

#2


做成COM Server等,实现单例模式,其他的客户端请求,都由它处理...
来了请求第一个创建实例,后面请求,发现已经创建,就直接处理

#3


把进程外组件做成服务类型

#4


每日友情UP

#5


引用 2 楼 oyljerry 的回复:
做成COM Server等,实现单例模式,其他的客户端请求,都由它处理...
来了请求第一个创建实例,后面请求,发现已经创建,就直接处理

客户端的请求我只知道用CoCreateInstance来获得服务提供的接口,如何判断已经存在实例并获得接口呢?谢谢!

#6


引用 3 楼 jameshooo 的回复:
把进程外组件做成服务类型

做成服务就不会存在这个问题?一会试验一下 。不过如果可以的话,那不是就绕过了vista的安全机制?

#7


引用 3 楼 jameshooo 的回复:
把进程外组件做成服务类型

经过测试,做成服务结果也是一样的,还是会启动多个服务进程。

#8


引用 7 楼 flyhigh 的回复:
引用 3 楼 jameshooo 的回复:
把进程外组件做成服务类型

经过测试,做成服务结果也是一样的,还是会启动多个服务进程。

是否Regsvr32注册服务...

#9


关注一下

#10


引用 8 楼 oyljerry 的回复:
引用 7 楼 flyhigh 的回复:
引用 3 楼 jameshooo 的回复:
把进程外组件做成服务类型

经过测试,做成服务结果也是一样的,还是会启动多个服务进程。

是否Regsvr32注册服务...

注册了。如果不注册,那客户端就不可能引用了。

#11


mark。。。

#12


http://www.eggheadcafe.com/software/aspnet/29825236/singleton-against-win-vis.aspx
看看这个链接,他是通过CoInitializeSecurity解决了uac下的单实例问题。
也有人提出利用service来解决的方案。

#13


引用 12 楼 sgzwiz 的回复:
http://www.eggheadcafe.com/software/aspnet/29825236/singleton-against-win-vis.aspx
看看这个链接,他是通过CoInitializeSecurity解决了uac下的单实例问题。
也有人提出利用service来解决的方案。

都不行。

#14


程序里加个互斥

#15


程序里加互斥,启动的新的服务实例是可以关闭,但是client请求的接口没有得到。

#16


采用Moniker技术试试,在vista下,moniker技术有所不同

#17


关键问题不在服务器端,而在客户端口。客户端应当先调用GetActiveObject 来判断所请求的服务器端是否已经运行,如果已经运行,则 AttachDispatch, 否则的话 CreateDispatch. 参考代码:

CLSID clsidWMP;
LPDISPATCH pWMPDispatch = NULL;

AfxCheckError(::CLSIDFromProgID(_T("COMServer.application"), &clsidWMP));

IID_IDispatch, (LPVOID*)&pWMPDispatch);
LPUNKNOWN lpUnk;
HRESULT hr = ::GetActiveObject(clsidWMP, NULL, &lpUnk);
if (hr == NOERROR)
{
HRESULT hr = lpUnk->QueryInterface(IID_IDispatch,
(LPVOID*)&pWMPDispatch);
lpUnk->Release();
if (hr == NOERROR)
m_Comserver.AttachDispatch(pWMPDispatch, TRUE);
}
if (m_Comserver.m_lpDispatch == NULL)
{
m_Comserver.CreateDispatch(clsidWMP);
}

#18


我用过ROT,但是GetActiveObject返回“不能执行的操作”。不知道楼上的方法行不行,理论上应该也不行,因为没有解决vista的安全问题。

#19


mark

#20


做成Automation server可以么?

#21



路过路过路过

#22


研究一下

#23


只在xp环境下玩过,Vista环境不清楚

#24


做成COM Server等,实现单例模式,其他的客户端请求,都由它处理...
来了请求第一个创建实例,后面请求,发现已经创建,就直接处理
或者加一个互斥

#25


不懂。。。呵呵

#26


mark 帮顶

#27


路过,关注一下

#28


mark。。。

#29


该回复于2010-04-22 14:24:54被版主删除

#30


学习了

#31


thanks

#32


haoa

#33


哦,好的,明白了

#34


学习路过看看

#35


每日友情UP

#36


了解一下。。。

#37


 在UAC下似乎做不到.

#38


路过接分...

#39


ding

#40


   学习!!!!

#41


hao

#42


路过学习一下

#43


不错不错不错不错

#44


不错不错不错不错

#45


看看 ~~~~

#46


学习了。。

#47


顶下,先注册下

#48


顶顶顶顶顶顶顶顶顶

#49


不怎么理解            什么意思 

#50


我是来学习的