0

I have a problem to execute uninstallString using process, it won't work in all cases. I need a generic procedure that will run in any case.

  • one of my ideas was to parse uninstall string

Code:

int indexOfExe = uninstallString.ToLower().IndexOf(".exe") + 4;
string exeFile = uninstallString.Substring(0, indexOfExe).Trim();
string args = uninstallString.Substring(indexOfExe, uninstallString.Length - indexOfExe).Trim();

if (args.Length > 0)
{
    procStartInfo.FileName = exeFile;
    procStartInfo.Arguments = args;
}
else
{
    procStartInfo.FileName = exeFile;
    procStartInfo.Arguments = "";
}

procStartInfo.Verb = "runas";
procStartInfo.CreateNoWindow = true;
procStartInfo.UseShellExecute = false ;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
  • my second idea was:

Code:

if (uninstallString.Contains("msiexec"))
{
    uninstallString = uninstallString.Replace("\"", "");
    uninstallString = RegistryHandler.getCommandInCommaAndArgumentsOutside(uninstallString);
}
else
{
    procStartInfo.FileName = "cmd";

    string[] words = uninstallString.Split("/".ToCharArray());

    if (uninstallString.StartsWith(@"""") && words.Count() == 1)
    {
        procStartInfo.FileName = uninstallString;
        procStartInfo.Arguments = "";
    }
    else
    {
        //procStartInfo.Arguments = "/c " + "\"" + uninstallString + "\"";
        if ((uninstallString.StartsWith(@"""") && words.Count() > 1))
        {
            procStartInfo.Arguments = "/c " + uninstallString;
        }
        else
        {
            procStartInfo.Arguments = "/c " + RegistryHandler.getCommandInCommaAndArgumentsOutsideByExe(uninstallString);
        }
    }
}

but still it won't cover all cases.

What is the generic solution for all cases?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Roy
  • 1
  • 1
  • 1
  • You have described what you have tried but not what went wrong. Are you trying to replace the add/remove programs dialog? – David Heffernan Sep 04 '11 at 07:04
  • What is the issue in directly executing the value in uninstallstring key in a commandline process? Does the uninstall have to be without user intervention? – NoviceProgrammer Sep 04 '11 at 18:53

3 Answers3

0

Your second idea should, technically, work (for all programs using Windows Installer). However, you need to get the proper uninstall string. I suspect the problem is your Uninstall String is incorrect.

You should be able to query the registry for the Uninstall String by looking at:

HKLM\Software\Microsoft\Windows\Currentversion\Uninstall\{NameOfApplication}\UninstallString

The section above marked {NameOfApplication} should have an entry for all programs which can be uninstalled. For details, see the Uninstall Registry Key.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Yes, i know that's the uninstallString registry path. but still my second idea won't cover all casses. what microsoft is doing in order to uninstall software (MSI & nonMSI) ? – Roy Sep 04 '11 at 07:37
  • @Roy: Microsoft doesn't - I have software that doesn't show up in the Control Panel - However, other software *should* put in an Uninstall String. This is all the Control Panel uses to find software to uninstall. For example, "CutePDF" doesn't use MSI, so the uninstall string on my system is "C:\Program Files (x86)\Acro Software\CutePDF Writer\Setup64.exe /uninstall" – Reed Copsey Sep 05 '11 at 06:02
0
//i wrote this code, which is working in most of the cases :

//----------------------------------------------------------------------------------------------          

            if (uninstallString.Contains("msiexec"))
                {
                uninstallString = uninstallString.Replace("\"", "");
                uninstallString = RegistryHandler.getCommandInCommaAndArgumentsOutside(uninstallString);
                }
                else
                {
                  if (uninstallString.StartsWith(@""""))
                     {
                     int indexOfLastComma = uninstallString.IndexOf("\"", 1) + 1;
                     procStartInfo.FileName = uninstallString.Substring(0, indexOfLastComma);
                     procStartInfo.Arguments = uninstallString.Substrin(indexOfLastComma,uninstallString.Length - indexOfLastComma));

                     }
                     else
                     {
                      procStartInfo.FileName = "cmd.exe";
                      procStartInfo.Arguments = "/c " + RegistryHandler.getCommandInCommaAndArgumentsOutsideByExe(uninstallString); 
                      }     
}

//----------------------------------------------------------------------------------------------


          public static string getCommandInCommaAndArgumentsOutsideByExe(string command)
                 {
                   int ind = 0;
                   string[] prms = command.Split(' ');

                   ind = prms[0].Length; //command.IndexOf(".exe") + 4;

                   int exeLocationIndex = command.IndexOf(".exe") + 4;
                   string cmd = command.Substring(0, exeLocationIndex);
                   string arguments = command.Substring(command.IndexOf(".exe") + 4, command.Length - exeLocationIndex);

                   return "\"" + cmd + "\"" + arguments;
                       }
Roy
  • 1
-1

Here is my code, using the same way as Roy did,perhaps a litter simpler:

  private string SwitchCondition(string uninstallstring)
    {
        if (uninstallstring.Substring(0, 1).Equals("\"") |
            uninstallstring.ToLower().Contains("msiexec") |
            uninstallstring.Contains("~"))
        {
            Debug.WriteLine(uninstallstring);
        }
        else if (uninstallstring.ToLower().IndexOf(".exe") > 0)
        {
            uninstallstring = "\"" + uninstallstring.Insert(uninstallstring.ToLower().IndexOf(".exe") + 4, "\"");
            Debug.WriteLine("Contains .exe" + uninstallstring);
        }
        else
        {
            uninstallstring = "\"" + uninstallstring + "\"";
            Debug.WriteLine("Case end " + uninstallstring);
        }

        return uninstallstring;
    }