通过内核对象在服务程序和桌面程序之间通信的小问题 good
关于在通过 事件对象 在服务程序和普通桌面应用程序相互之间通信的问题,分类情况进行讨论:
1、普通桌面应用程序中创建事件,服务程序中打开事件
XP的情况
普通桌面应用程序中创建:
- m_hEvent = ::CreateEvent(NULL, FALSE, FALSE, TEXT("{67BDE5D7-C2FC-49f5-9096-C255AB791B75}"));
服务程序中打开并置其为有信号:
- HANDLE hEvent = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("{67BDE5D7-C2FC-49f5-9096-C255AB791B75}"));
- DWORD dwErr = ::GetLastError();
- ::SetEvent(m_hEvent);
vista下情况
vista下有点问题是,如果像上面那样写的话,服务程序在打开该事件对象时报错“系统找不到指定的文件。”,原因是XP下服务程序和应用程序创建的内核对象的命名空间默认是全局的,而vista下则不是,服务创建的内核对象默认在session0下,而用户创建的内核对象默认在各自的session下(session1,session2……),解决此问题的方法很简单,就是在创建命名时间对象时指定名字是全局的,也就是将CreateEvent和OpenEvent的最后一个参数设置为TEXT("Global//{67BDE5D7-C2FC-49f5-9096-C255AB791B75}")。
2、服务程序中创建事件,普通桌面应用程序中打开事件
下面就不分系统说明,只说说根本的问题。
服务程序中创建:
- m_hEvent = ::CreateEvent(NULL, FALSE, FALSE, TEXT("{67BDE5D7-C2FC-49f5-9096-C255AB791B75}"));
普通桌面应用程序中打开:
- HANDLE hEvent = ::OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("{67BDE5D7-C2FC-49f5-9096-C255AB791B75}"));
- ::SetEvent(hEvent);
上面的代码不能正常工作,在普通桌面应用程序中打开事件对象时,报错“拒绝访问。”,并且获得的事件句柄是NULL,原因是这样的,在服务程序中创建的内核对象,默认情况下桌面程序无法打开这个对象,每个内核对象都是有访问控制的,而服务中创建的内核对象权限比较高,当LPSECURITY_ATTRIBUTES这个参数传NULL的时候,将使用默认访问控制。普通桌面应用程序自然没有权限访问了,解决方法如下,在服务程序创建事件对象时,指定确定的安全描述符。
- // set SECURITY_DESCRIPTOR
- SECURITY_DESCRIPTOR secutityDese;
- ::InitializeSecurityDescriptor(&secutityDese, SECURITY_DESCRIPTOR_REVISION);
- ::SetSecurityDescriptorDacl(&secutityDese,TRUE,NULL,FALSE);
- SECURITY_ATTRIBUTES securityAttr;
- // set SECURITY_ATTRIBUTES
- securityAttr.nLength = sizeof SECURITY_ATTRIBUTES;
- securityAttr.bInheritHandle = FALSE;
- securityAttr.lpSecurityDescriptor = &secutityDese;
- m_hEvent = ::CreateEvent(&securityAttr, FALSE, FALSE, TEXT("{67BDE5D7-C2FC-49f5-9096-C255AB791B75}"));
这样普通桌面应用程序再去打开该事件对象就没有问题了。(注:vista下事件对象的名字仍然要指定全局空间)
另外再谈谈Windows编程中的session,最近遇到一些很郁闷的问题。一直在折腾Vista下的服务程序启动进程的问题,有了点小小的体会,记下来,希望能帮到跟我遇到一样问题的朋友。Windows xp、Vista中,服务程序都是运行在session0中,而后面的第1、2、...、N个用户则分别运行在session1、session2、...、sessionN中。不同的session有不同的namespace,但是由于目前主流的用户windows平台WinXP支持快速用户切换,所以我们感觉不到这些差异。
在XP中,用Sevice启动的进程跟我们用当前用户启动的进程在编程上似乎没什么区别,用起来都一样。 可是到了vista下,情况就不一样了。vista新的安全机制对不同的session之间的限制做了加强。一些命名内核对象,如Event的使用,为了进行进程通信,在进程1(处在session1中)中,我创建了一个命名的事件对象,然后在进程2(由我的服务启动,所以运行在session0中)中检测该Event,发现始终检查不到,而且错误信息是“系统找不到指定的文件。”另外专门写了个小程序去检测(直接运行,也是运行在session1中),却能检测到。
后来仔细读了MSDN中关于“ Kernel Object Name Spaces”的资料,才明白:一些命名的内核对象,比如: events, semaphores, mutexes, waitable timers, file-mapping objects, job objects,都只是在自己的namespace里唯一存在,不同的session因为namespace不同,所以会导致上面的现象。详细的信息可以参考MSDN中的CreateEvent资料中对参数lpName的说明。
大家可以参考MSDN中的“ Kernel Object Name Spaces”(没事贴点MSDN中的东东,MSDN才是王道啊):
Kernel Object Name Spaces
A Terminal Services server has multiple namespaces for the following named kernel objects: events, semaphores, mutexes, waitable timers, file-mapping objects, and job objects. There is a global namespace used primarily by services such as client/server applications. In addition, each client session has a separate namespace for these objects. Note that this differs from the standard Windows environment in which all processes and services share a single namespace for these objects.
The separate client session namespaces enable multiple clients to run the same applications without interfering with each other. For processes started under a client session, the system uses the session namespace by default. However, these processes can use the global namespace by prepending the "Global/" prefix to the object name. For example, the following code calls CreateEvent and creates an event object named CSAPP in the global namespace:
CreateEvent( NULL, FALSE, FALSE, "Global//CSAPP" );
Service applications in a Terminal Services environment use the global namespace by default. Processes started under session zero (typically the console session) also use the global namespace by default. The global namespace enables processes on multiple client sessions to communicate with a service application or with the console session. For example, a client/server application might use a mutex object for synchronization. The server component running as a service can create the mutex object in the global namespace. Then the client component running as a process running under a client session can use the "Global/" prefix to open the mutex object.
Another use of the global namespace is for applications that use named objects to detect that there is already an instance of the application running in the system across all sessions. This named object must be created or opened in the global namespace instead of the per-session namespace. Note that the more common case of running the application once per session is supported by default since the named object is created in a per session namespace.
Client processes can also use the "Local/" prefix to explicitly create an object in their session namespace.
The "Local", "Global" and "Session" prefixes are reserved for system use and should not be used as names for kernel objects. These keywords are case sensitive. On Windows 2000 without Terminal Services, these keywords are ignored. On Windows NT 4.0 without Terminal Services, and earlier versions of Windows NT, the functions for creating or opening these objects fail if you specify a name containing the backslash character (/).
Windows XP: Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session zero, the next user to log on uses session one, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so that applications can support multiple users. For more information, see Fast User Switching.
http://blog.csdn.net/magictong/article/details/3726827
通过内核对象在服务程序和桌面程序之间通信的小问题 good的更多相关文章
- DELPHI编写服务程序总结(在系统服务和桌面程序之间共享内存,在服务中使用COM组件)
DELPHI编写服务程序总结 一.服务程序和桌面程序的区别 Windows 2000/XP/2003等支持一种叫做“系统服务程序”的进程,系统服务和桌面程序的区别是:系统服务不用登陆系统即可运行:系统 ...
- windows核心编程---第三章 内核对象及句柄本质
本章讨论的是相对抽象的概念,不涉及任何具体的内核对象的细节而是讨论所有内核对象的共有特性. 首先让我们来了解一下什么是内核对象.内核对象通过API来创建,每个内核对象是一个数据结构,它对应一块内存 ...
- c++事件内核对象(event)进程间激活(转)
源出处:http://blog.csdn.net/richerg85/article/details/7538493 此文主要说明的是,c++中创建的一个事件内核对象可以在不同的程序(进程)间共用,也 ...
- 《windows核心编程系列》三谈谈内核对象及句柄的本质
内核对象 本章讨论的是相对抽象的概念,不涉及任何具体的内核对象的细节而是讨论所有内核对象的共有特性. 首先让我们来了解一下什么是内核对象.内核对象通过API来创建,每个内核对象是一个数据结构,它对应一 ...
- H5 页面与小程序之间 传递数据
H5 页面与小程序之间 传递数据 小程序里面的 H5页面与小程序之间怎么传递数据 webview与小程序之间的实时通信 webview主动发消息给小程序 webview可以利用jssdk提供的 wx. ...
- Know the Core Objects of Your App---了解应用程序的内核对象
Back to App Design You develop apps using the Cocoa application environment. Cocoa presents the app’ ...
- RT-thread内核之线程内核对象
在RT-Thread实时操作系统中,任务采用了线程来实现,线程是RT-Thread中最基本的调度单位,它描述了一个任务执行的上下文关系,也描述了这个任务所处的优先等级.重要的任务能拥有相对较高的优先级 ...
- C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案
本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...
- Windows核心编程 第三章 内核对象
第3章内核对象 在介绍Windows API的时候,首先要讲述内核对象以及它们的句柄.本章将要介绍一些比较抽象的概念,在此并不讨论某个特定内核对象的特性,相反只是介绍适用于所有内核对象的特性. 首先介 ...
随机推荐
- php redis操作具体解释
phpredis是redis的php的一个扩展,效率是相当高有链表排序功能,对创建内存级的模块业务关系 非常实用;下面是redis官方提供的命令使用技巧: 下载地址例如以下: https://gith ...
- hadoop 集群及hbase集群的pid文件存放位置
一.当hbase集群和hadoop集群停了做一些配置调整,结果执行stop-all.sh的时候无法停止集群, 提示no datanode,no namenode等等之类的信息, 查看stop-all. ...
- NET Framework、.NET Core、Xamarin
认识.NET Core 上篇介绍了.NET 新的生态环境:包括.NET Framework..NET Core.Xamarin三驾马车 其中.NET Framework是基于Windows平台专属的开 ...
- Linux虚拟文件系统(VFS)学习
虚拟文件系统(Virtual Filesystem)也可称之为虚拟文件系统转换(Virtual Filesystem Switch),是一个内核软件层,用来处理与Unix标准文件系统相关的全部系统调用 ...
- delphi之IOCP学习(一)
困扰已久的网络通信(IOCP:完成端口),今天终于揭开她的神秘面纱了,之前百度N久还是未能理解IOCP,网络上好多博文都没有贴出源码,初学者很难正在理解IOCP并自己写出通信例子 ,经过努力,今天自己 ...
- protobuf反射详解
本文主要介绍protobuf里的反射功能,使用的pb版本为2.6.1,同时为了简洁,对repeated/extension字段的处理方法没有说明. 最初是起源于这样一个问题: 给定一个pb对象,如何自 ...
- 简单使用.net core 自带的DI
1.创建一个web api项目 2.在项目中创建一个接口类 namespace LearnCore.CoreDI { public interface ILearnDI { string GetNam ...
- 安装mysql5.7.17
参见 网易云课堂的视频教程 :mysql视频教程
- moost — Last.fm's collection of C++ utility libraries(功能很多)
libmoost libmoost is a collection of C++ utility libraries, including: algorithms (set intersection, ...
- windows下启动redis
解决方案 使用现成的基于windows的redis程序 github上有许多封装好的基于windows的redis程序,可以直接使用,但是版本更新不及时比如: https://github.com/M ...