概述由Windows服务生成的进程调用CreateMutex()失败,并返回ERROR_ACCESS_DENIED
我只花了好几天的时间来追踪由于:: CreateMutex()的调用失败而导致抛出一个未处理exception的错误。 请记住, CreateMutex()不会尝试locking互斥锁,只是打开一个句柄。 即使互斥体已经存在 , 也不应该失败 ,至less只要我将bInitialOwner设置为FALSE即可。
但是,如果我打电话::CreateMutexA(0,\”testtesttest123\”); ,从一个由windows服务产生的程序( w3wp.exe是其父项, scvhost.exe是其父项,并在IIS APPPOolWorker1用户帐户下运行),则失败并返回NulL,如果互斥量已经由IIS APPPOol*下运行的另一个进程创build的。
我创build了一个重现此问题的最小示例:
voID main() { HANDLE handle = CreateMutexA(0,\”testtesttest123\”); std::string lastError = MyGetLastErrorAsText(); MyAppendTolog(\”%p %sn\”,handle,lastError.c_str()); Sleep(INFINITE); }
我通过从资源pipe理器(普通用户帐户)双击运行可执行文件2次,然后使其由windows服务产生,并再次从资源pipe理器中运行。
如何在不使用IISpipe理器的情况下更改IIS中默认网站的端口?
如何在开发机器上testing子域名? abc.localhost
PHP的梅勒 – 电子邮件不发送超过100 KB的附件
IIS 10:windows 10与windows Server 2016,连接数
为什么我的ASP.Net网站在IIS7下运行需要很长时间才能加载一段时间的不活动?
这将创build以下日志:
C: Test ReproduceMutexCrash.exe:00000034 ERROR_SUCCESS
C: Test ReproduceMutexCrash.exe:00000034 ERROR_ALREADY_EXISTS
c: inetpub wwwroot Worker1 ReproduceMutexCrash.exe:00000034 ERROR_SUCCESS
c: inetpub wwwroot Worker2 ReproduceMutexCrash.exe:00000000 ERROR_ACCESS_DENIED
C: Test ReproduceMutexCrash.exe:00000034 ERROR_ALREADY_EXISTS
这里的Worker1在IIS APPPOolWorker2下运行,而Worker2在IIS APPPOolWorker2用户帐户下运行。
从日志中可以明显看出,如果互斥体是由普通的用户进程创build的,这不会阻止另一个用户进程甚至windows服务打开句柄。 但是,如果一个windows服务创build了一个互斥锁,那么::CreateMutex()在被另一个windows服务调用时会失败,虽然用户进程仍然可以打开一个句柄而不会出现问题。
有谁知道为什么发生这种情况?
编辑:当进程由资源pipe理器产生时,我看到互斥对象是Sessions1Basenamedobjectstesttesttest123 ,而当它由IIS创build时,它是Basenamedobjectstesttesttest123 ,而拥有者是Worker1 (第一个pipe理的进程创build互斥体)。
Nginx反向代理 – 直通基本authentication
.net核心应用程序无法通过FTP上传,托pipe在IIS上
Visual Studio无法在IIS中创build网站
子域和主机之间的cookie
windows身份valIDation在本地IIS 7.5上不起作用。 错误401.1
感谢评论的帮助,我终于明白了为什么会发生。 这确实是因为权限,因为这些进程是从不同的用户帐户运行的。 我验证了通过运行2个独立的进程,但从相同的用户帐户 – IIS APPPOolWorker1 ,并为两个::CreateMutex()工作并返回一个有效的句柄。
只有当IIS APPPOolWorker1下的进程锁定互斥锁并且IIS APPPOolWorker1下的进程尝试访问它时,它IIS APPPOolWorker2 。
另外,我尝试通过创建一个空的DACL来创建没有任何安全性的互斥锁:
Security_ATTRIBUTES sa = { sizeof(sa) }; Security_DESCRIPTOR SD; InitializeSecurityDescriptor(&SD,Security_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&SD,TRUE,NulL,FALSE); sa.lpSecurityDescriptor = &SD; HANDLE mutex = CreateMutexA(&sa,\”testtesttest123\”);
使用一个空的DACL,来自不同用户帐户的2个进程可以打开相同的互斥锁。
此外,用户进程创建的互斥体不会导致ERROR_ACCESS_DENIED的原因是因为它在不同的作用域中创建了互斥体 – Sessions1Basenamedobjectstesttesttest123 ,所以没有权限冲突,服务进程正在Basenamedobjectstesttesttest123创建一个新的互斥体,所以它们不会访问同一个对象。
总结
以上是内存溢出为你收集整理的由Windows服务生成的进程调用CreateMutex()失败,并返回ERROR_ACCESS_DENIED全部内容,希望文章能够帮你解决由Windows服务生成的进程调用CreateMutex()失败,并返回ERROR_ACCESS_DENIED所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
请登录后查看评论内容