kyusan93
kyusan93

Reputation: 422

C# winform delete folders and files on uninstall. Permission Error

I am getting the below error.

I need to uninstall the app and delete all files and folders created either by the application or users in the program files/myapp.

How can I resolve this issue? Thanks.

Access to the path 'C:\Program Files (x86)\DefaultProgram\Application\app.exe' is denied.

My Code:

protected override void OnAfterUninstall(IDictionary savedState)
        {
            string sFolder = Path.GetDirectoryName(Context.Parameters["assemblypath"]);
            string sUsername = "NT AUTHORITY\\LOCALSERVICE";
            DirectoryInfo myDirectoryInfo = new DirectoryInfo(sFolder);
            DirectorySecurity myDirectorySecurity = myDirectoryInfo.GetAccessControl();
            myDirectorySecurity.AddAccessRule(
                new FileSystemAccessRule(
                    sUsername, FileSystemRights.Read | 
                    FileSystemRights.Write | 
                    FileSystemRights.Modify, InheritanceFlags.ContainerInherit | 
                    InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly, AccessControlType.Allow));
            myDirectoryInfo.SetAccessControl(myDirectorySecurity);
            base.OnAfterUninstall(savedState);
            string appPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            DeleteDirectory(Path.Combine(appPath, "DB"));
            DeleteDirectory(appPath);
        }

        public static void DeleteDirectory(string target_dir)
        {
            string[] files = Directory.GetFiles(target_dir);
            string[] dirs = Directory.GetDirectories(target_dir);
            foreach (string file in files)
            {
                File.SetAttributes(file, FileAttributes.Normal);
                File.Delete(file);
            }
            foreach (string dir in dirs)
            {
                DeleteDirectory(dir);
            }
            Directory.Delete(target_dir, false);
        } 

Upvotes: 0

Views: 2410

Answers (3)

G.Y
G.Y

Reputation: 6159

Your problem is related to security, for example in windows XP it might work while in Windows 7 it might fail and you will be denied of manipulating files.

In order to overcome the problem you need to make sure of the followings:

  1. package and deployment project output two files: .msi & .exe.

    .MSI file - is allowed to execute under some kind of pre-defined specifically for installers privileges - and that means it may not have enough privileges to delete file from any folder you want - it can only add or remove files from your target application folder.

    .Exe file - almost do the same as MSI file, it actually being set to execute the msi file. Yet.. since it is Exe file you can set a flag to instruct it must be execute under administrator privileges and that will allow you to achieve your goal. (.exe may have other stuff you may need to deploy i.e .net package or directX)

  2. since the situation is very inconvenient in the sense that you are being pushed to provide your users with the two files and they will not know what to execute.. I recommend that you to use WINRAR to archive both files into a RAR self extracting archive. you can set the RAR archive to execute the archived .EXE file in administrator privilege and set the RAR-sfx archive itself (which is also .exe) with the flag "require administrator privileges".

Upvotes: 1

Likurg
Likurg

Reputation: 2760

You can delete your app.exe in this way on XP

Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " + 
      Application.ExecutablePath); 
Application.Exit();

or this in Win7 (EDIT2)

Process.Start("cmd.exe", "timeout 5 > Nul & Del " + 
      Application.ExecutablePath); 
Application.Exit();

But you must add in foreach if(file.Contains("app.exe")) continue;

EDIT

protected override void OnAfterUninstall(IDictionary savedState)
    {
        base.OnAfterUninstall(savedState);
        string sFolder = Path.GetDirectoryName(Context.Parameters["assemblypath"]);
        string sUsername = "NT AUTHORITY\\LOCALSERVICE";
        DirectoryInfo myDirectoryInfo = new DirectoryInfo(sFolder);
        DirectorySecurity myDirectorySecurity = myDirectoryInfo.GetAccessControl();
        myDirectorySecurity.AddAccessRule(
            new FileSystemAccessRule(
                sUsername, FileSystemRights.Read | 
                FileSystemRights.Write | 
                FileSystemRights.Modify, InheritanceFlags.ContainerInherit | 
                InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly, AccessControlType.Allow));
        myDirectoryInfo.SetAccessControl(myDirectorySecurity);
        string appPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
       DeleteDirectory(Path.Combine(appPath, "DB"));
        DeleteDirectory(appPath);
    }

    public static void DeleteDirectory(string target_dir)
    {
        string[] files = Directory.GetFiles(target_dir);
        string[] dirs = Directory.GetDirectories(target_dir);
        foreach (string file in files)
        {
            File.SetAttributes(file, FileAttributes.Normal);
            if(file.Contains("app.exe")) continue;
            File.Delete(file);
        }
        foreach (string dir in dirs)
        {
            DeleteDirectory(dir);
        }
        Directory.Delete(target_dir, false);
    } 

Upvotes: 1

Writwick
Writwick

Reputation: 2163

Your main Problem is UAC in Windows Vista and Later Windows Versions!

Your Code will run correctly in XP but create complications in Vista or 7 or 8.

See the Answers Here to run your Application as Administrator!

Upvotes: 2

Related Questions