Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 738
  • Last Modified:

Uninstalling application from code requires elevated command prompt

I have written a piece of C# application that performs pre-install tasks like uninstalls previous versions of certain applications, installs drivers etc. Each of these tasks is run by giving my application an argument from 1 to 10. Argument 1 uninstalls previous versions of my application. When I launch my application from an elevated (administrator) command prompt with the argument 1, the uninstall code works perfectly. However, it wont work when run from normal command prompt. The code (see below) executes perfectly and does not give any errors. Simply the programs wont uninstall.

It seems an easy solution to simply run the code from an elevated command prompt. The problem is, however, that in my real-use-screnario, I am not running the uninstall code from command line, but rather from inside my Windows application. Therefore, I cannot launch it from an elevated command prompt specifically.

The uninstallation is performed using the general msiexec methodology in c# code. As the case seems to be some sort of authorization problem, I tried to elevate the call of msiexec in my code by FProcess.StartInfo.Verb = "runas". This, however, did not solve the problem. Is there any way of giving the application enough priviledges to perform the uninstallation task, or is the problem actually somewhere else?

Thank you very much for your help!
private static void UninstallApplication(string p)
        {
            SW.WriteLine("\n\n" + "Uninstalling previous installations not created with this installer.");
            Console.WriteLine("Uninstalling previous installations not created with this installer.");

            Microsoft.Win32.RegistryKey Fregistry =
                Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE")
                .OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion")
                .OpenSubKey("Installer").OpenSubKey("UserData")
                .OpenSubKey("S-1-5-18").OpenSubKey("Products");
            string[] Names = Fregistry.GetSubKeyNames();
            string uninstall = "";
            string ApplicationName = p;

            string[] names2 = new string[1000];

            for (int i = 0; i < Names.Length; i++)
            {
                Microsoft.Win32.RegistryKey FTemp = Fregistry.OpenSubKey(Names[i]).OpenSubKey("InstallProperties");
                if (FTemp.GetValue("DisplayName").ToString() == ApplicationName)
                {                    
                    object obj = FTemp.GetValue("UninstallString");
                    if (obj == null)
                        uninstall = "";
                    else
                        uninstall = obj.ToString();
                    i = Names.Length;
                }
                else
                {
                    names2[i] = FTemp.GetValue("DisplayName").ToString();
                };
            }
            if (uninstall != "")
            {
                SW.WriteLine("\n\n" + "Old installation found. Uninstalling...");
                Console.WriteLine("Old installation found. Uninstalling...");

                SW.WriteLine("Uninstall guid: " + uninstall + ".");
                System.Console.WriteLine(uninstall);

                System.Diagnostics.Process FProcess = new System.Diagnostics.Process();
                string temp = "/uninstall {" + uninstall.Split("/".ToCharArray())[1].Split("I{".ToCharArray())[2] + " /quiet";
                // replacing with /x with /i would cause another popup of the application uninstall
                FProcess.StartInfo.FileName = uninstall.Split("/".ToCharArray())[0];
                FProcess.StartInfo.Arguments = temp;
                FProcess.StartInfo.UseShellExecute = false;
                FProcess.StartInfo.Verb = "runas"; //This runs the process as admin, may trigger UAC!
                FProcess.Start();
                System.Console.Read();

                SW.WriteLine("\n\n" + "Uninstall complete.");
                Console.WriteLine("Uninstall complete.");
            }
            else
            {
                SW.WriteLine("\n\n" + "No old installations found. Continuing...");
                Console.WriteLine("No old installations found. Continuing...");
            }
        }

Open in new window

0
JaniHuttunen
Asked:
JaniHuttunen
  • 2
  • 2
1 Solution
 
parnassoCommented:
The reason why your program is not uninstalling is that in Windows Vista an Windows 7, when you run your process without elevation (UAC), your process has the default priviledge level which is not enough to change things under the HKEY_LOCAL_MACHINE registry key.

To run elevated you can add a manifest to your uninstaller to make Windows to ask you for elevation automatically. You can also try changing your line>

FProcess.StartInfo.UseShellExecute = false;
 
to

FProcess.StartInfo.UseShellExecute = true;

0
 
JaniHuttunenAuthor Commented:
How do I add a manifest to my application? The InstallShield setup, which is the main application running my application asks for UAC in the beginning of the setup already. Changing useshellexecute did not help the problem.
0
 
JaniHuttunenAuthor Commented:
Adding to the previous entry: after changing the useshellexecute from false to true, the application asks for UAC IF run from command prompt (with default priviledges). When it is run from my windows application, though, it does not ask for UAC and does not complete succesfully.
0
 
parnassoCommented:
To add a manifest to your secondary application try this:

Adding a manifest to require UAC

To get more information on this topic the msdn says:

UAC manifest elevation
0
 
Russell_VenableCommented:
Are you uninstalling from command prompt remotely or locally? Try psexec -s -h -u <user> -p <pass> file.exe (for local) or  psexec -s -h -u <user> -p <pass> \\host\\file.msc

I believe it has switch for arguments as well, try psexec /? Fir the help menu. You can get the tool here psexec this tool will elevate your process from a command prompt as long as the credentials you give are in the administrators group for that computer.
0

Featured Post

NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now