12

I'm curious about something. I'm developing a Windows service and log all the diagnostic events into the Windows Event Log. So when the service is running I open the Event Viewer (from Administrative tools) to view the results of my service's operation.

This works great except for the moment when I need to uninstall my program (again, for the testing purposes.) For some weird reason the Event Viewer holds a lock on the .exe image file for my service so the uninstaller fails to delete it with the error code ERROR_SHARING_VIOLATION:

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

This happens only on Vista and later OS and seems not to be an issue on XP.

Any idea how to make Event Viewer release the file lock? (I'm asking about programmatic approach. I can obviously close it manually, but that's not what I'm after.)

c00000fd
  • 20,994
  • 29
  • 177
  • 400
  • Event Viewer opens the file in order to access the string resources (category names, event descriptions, etc). I guess you could try closing the file out from under it, but that's probably not going to be a good user experience if Event Viewer craps out. It's really a larger issue than that, though. What if some backup or anti-virus program has the file "locked" the moment you try to delete it? – Luke Aug 26 '13 at 18:48
  • @Luke: Yes, agreed. Although most of these issues come from badly written software, stuff like `acrotray.exe` or all those would-be AVPs. Also there's really no reason for Event Viewer to hold a file lock even if it needs to access resources. It can read them and then release the file lock (pretty much like it does in XP.) – c00000fd Aug 26 '13 at 19:30
  • You might want to consider putting your resources in a resource DLL. Still, that DLL would be locked by Event Viewer. – MSalters Aug 27 '13 at 08:18
  • 1
    @MSalters: Thanks, it would just shift the problem. I'm not really getting it though, using the restart manager method suggested below I get 6 locks from `svchost.exe` processes coming from these: `Windows Audio`, `DHCP Client`, `Windows Event Log`, `TCP/IP NetBIOS Helper`, `Security Center`, `Task Scheduler`. Task scheduler and Windows audio? Really? – c00000fd Aug 27 '13 at 17:02
  • I've seen the misleading error message _The action can't be completed because the file is open in DHCP Client_ instead. Same cause: Event Viewer being open. – qris Aug 09 '20 at 21:19

3 Answers3

8

I released the lock this way:

  1. Start -> Services
  2. Locate Windows Event Log
  3. Right click -> Restart
Sam
  • 40,644
  • 36
  • 176
  • 219
5

There's a less known feature introduced in Vista called Restart Manager that can help you release file locks via a user-mode code. Since you tagged it as C++, based on this article here's a small code sample to do that:

#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;
}
ahmd0
  • 16,633
  • 33
  • 137
  • 233
1

I just met same problem. The DLL was locked by svchost.exe process (Windows Audio, DHCP Client, Windows Event Log, TCP/IP NetBIOS Helper, Security Center, Task Scheduler)

Solution: close Event Viewer! :)

user2708351
  • 121
  • 7