通过内核对象在服务程序和桌面程序之间通信的小问题 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的时候,首先要讲述内核对象以及它们的句柄.本章将要介绍一些比较抽象的概念,在此并不讨论某个特定内核对象的特性,相反只是介绍适用于所有内核对象的特性. 首先介 ...
随机推荐
- zookeeper 半数可用/选举机制
1.半数可用机制,半数可用指的是zk集群中一半以上的机器正常时集群才能正常工作 已经启动了hadoop002(follower),hadoop003(leader) 下面停止hadoop002 在ha ...
- Eclipse Che安装依赖
java Java 用于运行Che的服务器和用于创建Plug-in包的SDK工具,所以需要安装Java Jdk 1.8 如果只是运行Che的话下载JRE就足够了,但是加入你需要从源代码编译的话你还需要 ...
- C#--动态操作DataTable
C#动态操作DataTable(新增行.列.查询行.列等) 方法一:动态创建一个DataTable ,并为其添加数据 public void CreateTable() { ...
- C#7
C#7 阅读目录 out变量 元组(Tuples) 模式匹配(Pattern matching) 本地引用和返回(Ref locals and returns) 本地函数(Local function ...
- sdk manager 打不开
解决方法1: 提示 [SDK Manager] Failed to convert path to a short DOS path: C:\windows\system32\java.exe 打开t ...
- 在.net core自带DI中服务生命周期 Transient,Scoped,Singleton
只要是透过WebHost产生实例的类型,都可以在构造方法注入.所以Controller.View.Filter.Middleware或自定义的Service等都可以被注入. Transient是瞬时的 ...
- 正确 C#
未来的期望
接触 C# 一年.整体上是一个很完好的语言,可是某些细节特征还是不够完美.这里记下我如今对它将来的一些期望. 更强大的泛型约束 与 C++ 的模板相似,C# 的泛型使得编写适用于多种类型的代码更加简洁 ...
- 非参贝叶斯(Bayesian Non-parameter)初步
0. motivations 如何确定 GMM 模型的 k,既观察到的样本由多少个高斯分布生成.由此在数据属于高维空间中时,根本就无法 visualize,更加难以建立直观,从而很难确定 k,高斯分布 ...
- Python缺乏调查的陷阱 动态实例属性、引用、逃生
--看到哪里.想到哪里,记到哪里 非常多时候.非常多人学python的时候,会忽略的东西非常多.大多数都盯着能"出货"即可,可是通常在读别人的代码的时候发现,看不懂...一方面是自 ...
- wxWidgets开始编程
开始学习wxWidgets.上一页写"安装wxWidgets两遇到的障碍"(缩写"前言"). 先推荐一下这两天找到的学习材料. 博客中有一个系列教程,貌似作者没 ...