我正在 Vista 上创建一个应用程序,其中包括一个服务和一个控制台应用程序。两者都在同一用户帐户中运行。
在服务中,我正在创建一个事件并等待该事件。在控制台应用程序中,我正在打开相同的事件(问题从这里开始)并调用SetEvent函数。 我无法在控制台应用程序中打开事件(出现错误 5,访问被拒绝)。我在网上搜索并看到了有关完整性级别的信息(我不确定问题是否与完整性级别有关)。它告诉该服务并且应用程序具有不同的完整性级别。
这是代码的一部分,其中IPC发生
服务
DWORD
WINAPI IpcThread(LPVOID lpParam)
{
HANDLE ghRequestEvent = NULL ;
ghRequestEvent = CreateEvent(NULL, FALSE,
FALSE, "Global\\Event1") ; //creating the event
if(NULL == ghRequestEvent)
{
//error
}
while(1)
{
WaitForSingleObject(ghRequestEvent, INFINITE) //waiting for the event
//here some action related to event
}
}
控制台应用程序
在应用程序中,打开事件并设置事件
unsigned int
event_notification()
{
HANDLE ghRequestEvent = NULL ;
ghRequestEvent = OpenEvent(SYNCHRONIZE|EVENT_MODIFY_STATE, FALSE, "Global\\Event1") ;
if(NULL == ghRequestEvent)
{
//error
}
SetEvent(ghRequestEvent) ;
}
我正在运行两个应用程序(服务和控制台应用程序)具有管理权限(我以管理员身份登录并通过右键单击并使用选项“以管理员身份运行”来运行控制台应用程序)。
我在控制台应用程序(我在其中打开事件)中遇到的错误是错误号 5(访问被拒绝。)。
因此,如果您告诉我们如何在 Vista 中的服务和应用程序之间进行 IPC,将会非常有帮助
提前感谢
Navaneeth
I am creating an appcation on Vista,which include a service and a Console application .Both running in same user account
In service i am creating an event and waits for that event.In console application i am opening the same event (problem starts here) and calling SetEvent function. I can not open the event (getting error 5,Access is denied) in the console application.I searched in the net and saw something about integrity level (I am not sure that the problem is related to integrity level).Its telling that service and applicaation got differnt integrity levels.
here is the part of the code,where IPC occures
service
DWORD
WINAPI IpcThread(LPVOID lpParam)
{
HANDLE ghRequestEvent = NULL ;
ghRequestEvent = CreateEvent(NULL, FALSE,
FALSE, "Global\\Event1") ; //creating the event
if(NULL == ghRequestEvent)
{
//error
}
while(1)
{
WaitForSingleObject(ghRequestEvent, INFINITE) //waiting for the event
//here some action related to event
}
}
Console Application
Here in application ,opening the event and seting the event
unsigned int
event_notification()
{
HANDLE ghRequestEvent = NULL ;
ghRequestEvent = OpenEvent(SYNCHRONIZE|EVENT_MODIFY_STATE, FALSE, "Global\\Event1") ;
if(NULL == ghRequestEvent)
{
//error
}
SetEvent(ghRequestEvent) ;
}
I am running both application (serivce and console application) with administrative privilege (i logged in as Administraor and running the console application by right clicking and using the option "run as administrator") .
The error i am getting in console application (where i am opening the event) is error no 5(Access is denied. ) .
So it will be very helpfull if you tell how to do the IPC between a service and an application in Vista
Thanks in advance
Navaneeth
发布评论
评论(5)
服务和应用程序是以具有不同完整性级别的同一用户身份运行,还是以不同的用户身份运行?
如果是前者,那么 MSDN 中讨论完整性级别的这篇文章可能会有所帮助。 他们有一些用于降低文件完整性级别的示例代码。 但我不确定这是否与某个活动相关。
如果是后者,您可以查看此链接 建议创建一个 NULL ACL 并将其与对象关联(在示例中它是一个命名管道,但我确信该方法与事件类似:
Are the service and the application running as the same user with different integrity levels, or are they running as different users?
If it is the former, then this article from MSDN which talks about integrity levels might help. They have some sample code for lowering the integrity level of a file. I'm not sure that this could be relevant for an event though.
If it is the latter you might look at this link which suggests creating a NULL ACL and associating it with the object (in the example it is a named pipe, but the approach is similar for an event I'm sure:
我注意到您正在“全局”命名空间中创建对象,但试图在本地命名空间中打开它。 在公开征集的姓名中添加“Global\”有帮助吗?
另外,在 //error 区域中,有什么东西可以让您知道它没有创建吗?
I notice that you are creating the object in the "Global" namespace but are trying to open it in a local namespace. Does adding "Global\" to the name in the open call help?
Also, in the //error area, is there anything there to let you know it wasn't created?
首先,从概念上理解需要什么很重要。 一旦理解了这一点,我们就可以从那里开始。
在服务器上,它应该看起来类似于:
在客户端上:
需要注意的几点:
First, it is important to conceptually understand what is required. Once that is understood we can take it from there.
On the server, it should look something similar to:
On the client:
Several points to note:
@Navaneeth:
非常好的反馈。 由于您的错误是访问被拒绝,那么我会将所需的访问权限从您实际上不需要的 EVENT_ALL_ACCESS 更改为
SYNCHRONIZE 让您等待事件,而 EVENT_MODIFY_STATE 让您调用 SetEvent、ResetEvent 和 PulseEvent。
您可能需要更多访问权限,但这种情况极不寻常。
@Navaneeth:
Excellent feedback. Since your error is Access Denied, then I would change the desired access from EVENT_ALL_ACCESS, which you really don't need, to
SYNCHRONIZE lets you wait on the event and EVENT_MODIFY_STATE lets you call SetEvent, ResetEvent and PulseEvent.
It is possible that you might need more access, but that is highly unusual.
“1800 INFORMATION”是对的——这是一个UIPI问题; 无论如何,不要在新代码中使用事件,如果触发事件时阻塞的目标恰好位于用户模式 APC 代码中,则事件信号可能会丢失。 在 Win32 中编写服务/应用程序的规范方法是使用 RPC 调用来跨越 UIPI 边界。
"1800 INFORMATION" is right - this is a UIPI issue; don't use Events in new code anyways, the event signal can be lost if the target blocking on the event happens to be in user-mode APC code when it is fired. The canonical way in Win32 to write a service/application is to use RPC calls to cross the UIPI boundary.