在通常的客户PC机上,这不是什么大不了的问题。之所以提出来,是因为在服务器应用环境中,这可是一个大麻烦。试想一下下面这段代码:
// Process 1:
......
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, _T("my_private_event_name")); // 假定这里会成功
......
// Process 2:
HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, _T("my_private_event_name")); // 你会成功吗???
设想两个场景,
1、普通的用户调用。即用户先启动进程1,之后再启动进程2;
2、用户先启动进程1,进程2由脚本语言调用(如asp、数据库的存储过程……)。
很显然,在第一种情况下,基本都不会出现问题。问题在于第二种应用环境!
在这种情况下,很不幸,你面临的是“The system cannot find the file specified” 错误!这是哪儿出了问题呢——权限?如果只是这么简单,犯不着单独写一篇文章来记录这个问题。我也在这个上面“浪费”了一上午的时间问题最终的根源还在于“命名空间”!听着挺熟悉的吧?但这个确实让人匪夷所思!!! 既然为内核对象,应该是存在于OS全局当中,不管什么应用程序都可以查找得到的,为什么加了个名字反而找不到了?这只能说内核的名字在OS内部,也是被以名字空间来划分存储的。当我们两个进程都通过explorer或者cmd来启动的时候,这些名字都会存储在同一空间中。但当脚本语言来调用这些进程的时候,这些子进程可能继承了父进程(脚本语言)的一些特性——包括内核对象的名字空间。这样当你分别在不同的应用环境中启动上面两个进程时,会发现通常情况下不会出问题的API出了问题:由于名字空间的不同,导致通过名字来找内核对象失败(ErrorCode: 2)!
这个问题最终的解决办法是:给内核对象的名字加上全局的命名空间,即以上两段改为:
//Process 1:
......
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, _T("Global\\my_private_event_name")); // 假定这里会成功
......
// Process 2:
HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, _T("Global\\my_private_event_name")); // 你会成功吗???
经此一劫,以后再写类似的代码时,最好都加上“Global”的命名空间。