Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete windows service folder with files throws error

Tags:

c#

.net

service

I know this question was already asked, but I couldn't find the solution so far.

What I'm trying to do is uninstall a windows service and delete the folder with the windows service using C#.

Windows service uninstall

    public static void Uninstall(string exeFilename)
    {
        var commandLineOptions = new string[1] { "/LogFile=uninstall.log" };

        if (!Directory.Exists(exeFilename)) return;

        var fileNames = Directory.GetFiles(exeFilename);
        var serviceFile = fileNames.FirstOrDefault(f => f.EndsWith(".exe"));
        var serviceFileName = Path.GetFileName(serviceFile);
        var serviceName = Path.GetFileNameWithoutExtension(serviceFile);

        var serviceExists = ServiceController.GetServices().Any(s => s.ServiceName == serviceName);

        if (!serviceExists) return;

        var installer =
            new AssemblyInstaller($"{exeFilename}\\{serviceFileName}", commandLineOptions)
            {
                UseNewContext = true
            };

        installer.Uninstall(null);
        installer.Dispose();
    }

Folder and files delete

    public static void DeleteFolder(string folderPath)
    {
        if(!Directory.Exists(folderPath)) return;
        
        try
        {
            foreach (var folder in Directory.GetDirectories(folderPath))
            {
                DeleteFolder(folder);
            }

            foreach (var file in Directory.GetFiles(folderPath))
            {
                var pPath = Path.Combine(folderPath, file);
                File.SetAttributes(pPath, FileAttributes.Normal);
                File.Delete(file);
            }

            Directory.Delete(folderPath);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }

Error that I get

Access to the path 'c:\services\x\x.exe' is denied.

 at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
 at System.IO.File.InternalDelete(String path, Boolean checkHost)
 at System.IO.File.Delete(String path)

This error occurs randomly. The .exe file is not readonly, sometimes the files get deleted.

Does anyone know what's wrong?

like image 925
Gerald Hughes Avatar asked Jul 14 '21 10:07

Gerald Hughes


People also ask

How do I force a windows service to delete?

You can also remove services using a command line. Hold down the Windows Key, then press “R” to bring up the Run dialog. Type “SC DELETE servicename“, then press “Enter“.

How do you fix could not find this item error when deleting files?

To do that, follow the steps below: Right-click Start on the Taskbar and select Task Manager. In the Processes tab, select Windows Explorer and click the Restart button in the bottom right corner. Try to delete the file or folder and see if the “Could not find this item” prompt will show up again.

How do you delete a folder in windows that won't delete?

Delete the file/folder using Command PromptGo to Search and type cmd. Click on Run as administrator to open Command Prompt with full permissions. In the Command Prompt, enter del, followed by the path of the folder or file you want to delete, and press Enter (for example del c:usersJohnDoeDesktoptext. txt).

How do I force delete a folder in windows Server?

Use “RMDIR /S /Q” command to force delete a folder in CMD: After entering Command Prompt window, you can type the rmdir /s /q folder path, for example, rmdir /s /q E:\test, and press Enter key. This deletes the folder named “test” in my USB drive.


2 Answers

Stopping a Windows service does not equate to exiting a process. An executable can house multiple Windows services (it's essentially the physical shell for the services).

So what you're running into, it looks like, is that the service likely stopped just fine, and uninstall can proceed and the deletion of files can proceed, but only up until the point where it reaches the executable, which hasn't yet had a chance to exit.

Stopping, exiting, uninstalling are all asynchronous and need time to complete before moving to the next step.

What you have to do is follow this formula

  1. Ensure your code is running with elevated privileges if you can; if you can't you may run into Access Denied. You can also try changing the ownership of the target executable.
  2. Stop or ensure the service is stopped. If there are multiple services, stop all of them.
  3. Wait for stop to actually occur. It's not always immediate.
  4. Call the Uninstall().
  5. Wait some amount of time. Check to see if the process is running. If it is you will call Process.Kill() (see an implementation below).
  6. Finally, you can call the DeleteFolder() for which your implementation looks adequate to me.

Exiting the Process

Write a method that looks something like this. You might want to tweak it.

void Exit(Process p)
{
    for (int i = 0; i <= 5; i++)
    {
        // doesn't block
        if (p.HasExited) return;

        // doesn't block; pass true to terminate children (if any)
        p.Kill(true);

        // wait 5 seconds then try again
        Thread.Sleep(5000);
    }
}

After all that you should be good to go.

like image 162
Kit Avatar answered Sep 27 '22 19:09

Kit


Is the service stopped / executable stopped and does the program have Administrator access? If you don't have administrator access, refer to: How do I force my .NET application to run as administrator? to run as administrator. When uninstalling a program, administrator permissions are almost always required. If this still fails, you are not the owner of the file and you must change the owner to yourself or Administrators. You can do this programatically here: Getting / setting file owner in C#

like image 33
Ethan Avatar answered Sep 27 '22 19:09

Ethan