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

12

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

这很好用,除了在需要卸载我的程序时(再次为测试目的),出现问题。由于某种奇怪的原因,事件查看器锁定了我的服务的.exe映像文件,因此卸载程序无法删除它,错误代码为ERROR_SHARING_VIOLATION

The process cannot access the file because it is being used by another process.

这只发生在Vista及更高版本的操作系统上,似乎在XP上不是问题。

有什么办法可以让事件查看器释放文件锁定?(我在询问编程方法。我显然可以手动关闭它,但那不是我想要的。)


事件查看器打开文件以访问字符串资源(类别名称、事件描述等)。我猜你可以尝试在其下关闭文件,但如果事件查看器崩溃,那可能不是一个好的用户体验。但这实际上是一个更大的问题。如果某个备份或反病毒程序在你尝试删除文件的那一刻将其“锁定”了呢? - Luke
@Luke:是的,同意。尽管大多数这些问题来自编写不良的软件,比如acrotray.exe或那些本应该成为AVP的东西。此外,即使需要访问资源,事件查看器也没有理由保持文件锁定。它可以读取它们然后释放文件锁定(基本上就像在XP中一样)。 - c00000fd
你可能需要考虑把你的资源放在一个资源 DLL 中。但是,这个 DLL 会被事件查看器锁定。 - MSalters
1
@MSalters:谢谢,但这只会转移问题。虽然我不太理解,但是使用下面建议的重启管理器方法,我从以下进程中获得了6个来自svchost.exe的锁:Windows AudioDHCP ClientWindows Event LogTCP/IP NetBIOS HelperSecurity CenterTask Scheduler。任务计划程序和Windows音频?真的吗? - c00000fd
我曾经看到过误导性的错误信息“由于DHCP客户端中的文件已打开,因此无法完成操作”。原因相同:事件查看器处于打开状态。 - qris
3个回答

8

我是这样释放锁的:

  1. 开始 -> 服务
  2. 找到 Windows 事件日志
  3. 右键单击 -> 重启

谢谢!那正是我所需要的。 - EvenThis

5

在Vista中引入了一个不太知名的功能叫做Restart Manager,可以通过用户模式代码帮助您释放文件锁定。鉴于您标记为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;
}

1

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接