Service Stoppen und zugriff auf die Dateien ***gelöst***



  • Hallo Leute,

    ich stoppe den Druckerservice und möchte danach eine Dll ersetzten die von diesem genutzt wird. Nur leider passiert es manchmal das die CopyFile Funktion mir den Fehler liefert:

    ERROR_SHARING_VIOLATION
    32 (0x20)
    The process cannot access the file because it is being used by another process.

    obwohl ich in einer Schleife Warte bis der service gestoppt ist

    if ((hServiceManager) && (hService))
    	{
    		if (!ControlService(hService,SERVICE_CONTROL_STOP,&ServiceState))
    			eError = EC_CantStopSpooler;
    	}
    	else eError = EC_CantStopSpooler;
    
    	while (SERVICE_STOP_PENDING == ServiceState.dwCurrentState)
    	{
    		Sleep(10);
    		QueryServiceStatus(hService,&ServiceState);
    	}
    
    		if (!CopyFile(sSourcePath,sSystem32Path,false))
    		{
    			eError = EC_CantCopyFile;
    			ulError = GetLastError();
    		}
    

    hat jemand eine Idee warum windows noch auf die dll zugreift?

    MfG



  • Der Service wird gestoppt und du wartest auf die Rückmeldung von Windows, dass der Service nicht mehr "stoppt" - ob der neue Status jetzt aber error oder gar starting ist, weil der Service sich automatisch neustartet, überprüfst du nicht.

    Sinniger wäre es darauf zu warten, dass windows auch das Handle des Prozesses zerstört, denn erst dann wird das Program aus dem Speicher entfernt und solange ist die DLL eben noch im Speicher des Services geladen und dementsprechend auf der disk noch read-only. Das Problem mit dem Handle ist natürlich, dass der Spooler-Service als nt-local-system läuft und dein usermode Programm normalerweise nicht darauf zugreifen können sollte.

    Eine andere möglichkeit ist natürlich noch, dass andere Programme die DLL geladen haben. Das kannst du mittels der WinApi oder zur not via "tasklist /M dllname.dll" aber relativ einfach rausfinden.



  • ich habe die eine Zeile nicht mehr gezeigt

    if (SERVICE_STOPPED != ServiceState.dwCurrentState)
    		eError = EC_CantStopSpooler;
    

    also müßte ich auf das beenden des spooler prozesses warten. Wieso sollte das nicht mit WAitForSingleObject gehen der ist doch auch im TaskManager sichtbar (spoosv.exe)?

    MfG



  • also

    if (WAIT_OBJECT_0 != (ulTemp = WaitForSingleObject(hSpooler,1000)))
    	{
    		ulTemp = GetLastError();
    		eError = EC_Wait;
    	}
    

    hilft.

    MfG


Anmelden zum Antworten