7

I know We can uninstall a windows application using its MSI by passing command arguments as follows,

Process p = new Process(); 
p.StartInfo.FileName = "msiexec.exe"; 
p.StartInfo.Arguments = "/x \"C:\\MyApplication.msi\"/qn"; 
p.Start(); 

But what i want to know is how can we uninstall the application without using MSI ? In the above scenario I should have the MSI in the specific location to uninstall this application, If i could unstaill using product code then I dont need to have the MSI in the target machine.

Kurubaran
  • 8,696
  • 5
  • 43
  • 65

4 Answers4

7

According to MSDN, You can uninstall it using the product code:

msiexec.exe /x {your-product-code-guid}

When you use the product code, it uses the cached MSI from C:\WINDOWS\Installer.

Ramesh Durai
  • 2,666
  • 9
  • 32
  • 55
  • Thanks, I was wondering how uninstallation works without primary MSI. Now ony i got to know the caching part :) – Kurubaran Jul 08 '13 at 14:46
7

Along the lines of PhilmE's answer, Windows Installer XML (WiX) ships the Microsoft.Deployment.WindowsInstaller interop library as part of Deployment Tools Foundation (DTF). This skips the COM interop and encapsulates the Win32 API instead.

using Microsoft.Deployment.WindowsInstaller;

public static void Uninstall( string productCode)
{
    Installer.ConfigureProduct(productCode, 0, InstallState.Absent, @"REBOOT=""R"" /l*v uninstall.log");
}
Nicke Manarin
  • 3,026
  • 4
  • 37
  • 79
Christopher Painter
  • 54,556
  • 6
  • 63
  • 100
4

Probably for your case, knowing the "/x" Parameter was sufficient. Two remarks on that: More secure is adding a "REBOOT=R" part to your commandline. And you can add a logfile path:

msiexec /x "..." /qn REBOOT=R /L*v "c:\mylogdir\mymsi.log"

Second, don't try to change anything to "the caching". You don't need even to understand it. If the cached package would be broken, a regular uninstallation is no longer possible, which could bring the computer in a "support needed" state.

Because your question was originally talking about C# .. You don't have to use msiexec for it:

a) Use the original C/C++ API with the function MsiInstallProduct() or MsiConfigureProduct(). MSDN ref: http://msdn.microsoft.com/en-us/library/windows/desktop/aa370315(v=vs.85).aspx

You have to use interop to use that in C#.

or b) Use the Windows Installer Object. For example, this related case was already answered here in stackoverflow: Programmatically installing MSI packages But using this function needs the physical package, also for uninstallation. With a slight indirection, here is the better code for uninstallation:

First, add a reference to COM object "Microsoft Windows Installer Object Library" to your project.

using WindowsInstaller;


public static class MyMsiLib
{
    public static void Uninstall(string productCode)
    {

         Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
         Installer installer = (Installer)Activator.CreateInstance(type);
         installer.UILevel=msiUILevelNone;
         installer.ConfigureProduct(productCode, 0, msiInstallStateAbsent);
    }
}

The UILevel property before is set here hardcoded to determine the UI level silent as you seem to want. Same for other properties. See MSDN documentation e.g. mentioned in the link above.

Of course "real programmers" work with the original API instead of the "Installer Object" :-) But for small purposes it is sufficient. And easier.

Community
  • 1
  • 1
Philm
  • 3,448
  • 1
  • 29
  • 28
  • 1
    FYI Windows Installer XML (WiX) ships the Microsoft.Deployment.WindowsInstaller interop library as part of Deployment Tools Foundation (DTF). This skips the COM interop and encapsulates the Win32 API instead. – Christopher Painter Jul 08 '13 at 20:32
  • Yes, using the mentioned library is the third possibility. It is a question of taste and usage. The lib is of course worth trying if you are doing many things with MSI. I don't know it well. You have maybe to fulfill special license requirements for shipping your software, if you use that library as for similar open source. And using the native MSI API is not so difficult in my eyes after once generated an interop assembly. But good to know for everyone interested that you have the choice between several possibilities. – Philm Jul 08 '13 at 20:54
  • Technically WindowsInstaller.Installer is one of the two "real" API's exposed by MSI.dll. However, I find P/Invoking MSI to be a lot less problematic then COM interop. The DTF library is done really well and should have been shipped in the BCL. That said, if you only need 1 or 2 API's google "MSIInterop.cs" and cut that down to your needs. The FOSS argument is FUD. – Christopher Painter Jul 08 '13 at 20:57
  • In fact WindowsInstaller.Installer is a COM wrapper of the "base" API, so it calls the other one. I agree that it is not as stable and bullet-proof as P/Invoking the MSI API, for several reasons. Originally, it was made for scripting tasks. – Philm Jul 09 '13 at 14:04
3

This command works on the command line:

msiexec /x {3A40307D-6DF2-4412-842F-B1D848043367} /quiet

I haven't tried it in C#, but replacing your arguments with the key shown above should work. You can find the GUID in the registry key for the app you are trying to uninstall.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Bravo11
  • 898
  • 2
  • 11
  • 24