C++ Windows事件查看器锁定了我的EXE文件

C++ Windows事件查看器锁定了我的EXE文件,c++,windows,winapi,event-viewer,C++,Windows,Winapi,Event Viewer,我有点好奇。我正在开发一个Windows服务,并将所有诊断事件记录到Windows事件日志中。因此,当服务运行时,我打开事件查看器(从管理工具)以查看服务运行的结果 除了我需要卸载我的程序的时候(出于测试目的),这非常有效。出于某种奇怪的原因,事件查看器锁定了我的服务的.exe映像文件,因此卸载程序无法删除它,错误代码为error\u SHARING\u违例: The process cannot access the file because it is being used by anoth

我有点好奇。我正在开发一个Windows服务,并将所有诊断事件记录到Windows事件日志中。因此,当服务运行时,我打开事件查看器(从管理工具)以查看服务运行的结果

除了我需要卸载我的程序的时候(出于测试目的),这非常有效。出于某种奇怪的原因,事件查看器锁定了我的服务的.exe映像文件,因此卸载程序无法删除它,错误代码为
error\u SHARING\u违例

The process cannot access the file because it is being used by another process.
这只发生在Vista和更高版本的操作系统上,在XP上似乎不是问题


知道如何让事件查看器释放文件锁吗?(我问的是编程方法。我显然可以手动关闭它,但这不是我想要的。)

Vista中引入了一个鲜为人知的功能,叫做重启管理器,它可以帮助您通过用户模式代码释放文件锁。既然你把它标记为C++,这里是基于这里的一个小代码示例:

#include <RestartManager.h>
#pragma comment(lib ,"Rstrtmgr.lib")

BOOL ReleaseFileLock(LPCTSTR pFilePath)
{
    BOOL bResult = FALSE;

    DWORD dwSession;
    WCHAR szSessionKey[CCH_RM_SESSION_KEY+1] = { 0 };
    DWORD dwError = RmStartSession(&dwSession, 0, szSessionKey);
    if (dwError == ERROR_SUCCESS) 
    {
        dwError = RmRegisterResources(dwSession, 1, &pFilePath,
            0, NULL, 0, NULL);
        if (dwError == ERROR_SUCCESS) 
        {
            UINT nProcInfoNeeded = 0;
            UINT nProcInfo = 0;
            RM_PROCESS_INFO rgpi[1];
            DWORD dwReason;

            dwError = RmGetList(dwSession, &nProcInfoNeeded,
                &nProcInfo, rgpi, &dwReason);
            if (dwError == ERROR_SUCCESS ||
                dwError == ERROR_MORE_DATA) 
            {
                if(nProcInfoNeeded > 0)
                {
                    //If current process does not have enough privileges to close one of
                    //the "offending" processes, you'll get ERROR_FAIL_NOACTION_REBOOT
                    dwError = RmShutdown(dwSession, RmForceShutdown, NULL);
                    if (dwError == ERROR_SUCCESS)
                    {
                        bResult = TRUE;
                    }
                }
                else
                    bResult = TRUE;
            }
        }
    }

    RmEndSession(dwSession);

    SetLastError(dwError);
    return bResult;
}
#包括
#pragma注释(lib,“Rstrtmgr.lib”)
布尔释放文件锁(LPCTSTR pFilePath)
{
BOOL-bResult=FALSE;
德沃德·德塞恩;
WCHAR szSessionKey[CCH_rmu SESSION_KEY+1]={0};
DWORD dwError=RmStartSession(&dwSession,0,szSessionKey);
if(dwError==ERROR\u SUCCESS)
{
dwError=RmRegisterResources(dwSession、1和pFilePath、,
0,空,0,空);
if(dwError==ERROR\u SUCCESS)
{
UINT nProcInfoNeeded=0;
UINT nProcInfo=0;
RM_流程_信息rgpi[1];
德沃德·德雷森;
dwError=RmGetList(需要dwSession和nprocInfo、,
&nProcInfo、rgpi和dwReason);
如果(dwError==ERROR\u成功||
dwError==错误(更多数据)
{
如果(nProcInfo需要>0)
{
//如果当前进程没有足够的权限关闭其中一个
//“违规”进程,您将得到错误\u失败\u无操作\u重新启动
dwError=RmShutdown(dwSession,RmForceShutdown,NULL);
if(dwError==ERROR\u SUCCESS)
{
bResult=TRUE;
}
}
其他的
bResult=TRUE;
}
}
}
RmEndSession(dwSession);
SetLastError(dwError);
返回结果;
}

我刚刚遇到了同样的问题。DLL被svchost.exe进程(Windows音频、DHCP客户端、Windows事件日志、TCP/IP NetBIOS帮助程序、安全中心、任务计划程序)锁定


解决方案:关闭事件查看器!:)

我这样释放了锁:

  • 开始->服务
  • 找到Windows事件日志
  • 右键单击->重新启动

  • 事件查看器打开文件以访问字符串资源(类别名称、事件描述等)。我想您可以尝试从下面关闭文件,但如果事件查看器出现问题,这可能不是一个好的用户体验。不过,这确实是一个更大的问题。如果某个备份或反病毒程序在你试图删除文件时“锁定”了该文件怎么办?@Luke:是的,同意。尽管这些问题大多来自编写糟糕的软件,比如
    acrotray.exe
    或所有那些可能是AVP的东西。此外,即使事件查看器需要访问资源,它也没有理由持有文件锁。它可以读取它们,然后释放文件锁(类似于XP中的文件锁)。您可能需要考虑将资源放入资源DLL中。尽管如此,该DLL仍将被事件查看器锁定。@MSalters:谢谢,这将解决问题。不过,我并没有真正理解它,使用下面建议的重启管理器方法,我从以下进程中获得了6个锁:
    svchost.exe
    Windows音频
    DHCP客户端
    Windows事件日志
    TCP/IP NetBIOS帮助程序
    安全中心
    任务调度程序
    。任务调度程序和Windows音频?真的吗?我看到了误导性的错误消息,操作无法完成,因为文件在DHCP客户端中打开。同样的原因:事件查看器正在打开。谢谢!这正是我所需要的。