Solved

Uninstalling application from code requires elevated command prompt

Posted on 2011-03-24
5
712 Views
Last Modified: 2012-06-27
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
Comment
Question by:JaniHuttunen
  • 2
  • 2
5 Comments
 
LVL 4

Accepted Solution

by:
parnasso earned 500 total points
ID: 35205428
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
 

Author Comment

by:JaniHuttunen
ID: 35205593
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
 

Author Comment

by:JaniHuttunen
ID: 35205607
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
 
LVL 4

Expert Comment

by:parnasso
ID: 35206048
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
 
LVL 15

Expert Comment

by:Russell_Venable
ID: 35217983
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now