Solved

Uninstalling application from code requires elevated command prompt

Posted on 2011-03-24
5
716 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

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Connection String 16 54
VS2015 Redefinition errors 4 47
rest webservice call over https via c# 6 37
C# Desktop Application 3 30
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
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…

785 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