1

I can't make an uninstall using ConfigureProduct run quietly. I have the following:

using Microsoft.Deployment.WindowsInstaller;

Installer.ConfigureProduct(productCode, 0, InstallState.Absent, "/q");

According to some earlier posts "/q" should work except I get the following exception every time I run the code.

"Invalid command line argument. Consult the Windows Installer SDK for detailed command line help."

Notice that "/q" does work when using msiexec.exe but I would like to do this using Microsoft.Deployment.WindowsInstaller.

I have also tried setting the UI to silent with the following:

Installer.SetInternalUI(InstallUIOptions.Silent);
Installer.ConfigureProduct(productCode, 0, InstallState.Absent, "");

But then I get the following exception:

"Fatal error during installation."

From the message I gather that SetInternalUI is for installations instead of uninstallations but not sure.

I am using the DLL from the WiX 3.9 R2 installation which is version 2.0.50727.

Any help is appreciated. Thanks!

EDIT: I looked a little closer at the comments for the "commandLine" parameter in the "ConfigureProduct" method.

    //   commandLine:
    //     Specifies the command line property settings. This should be a list of the
    //     format Property=Setting Property=Setting.

So basically no, you can't pass "/q", "/l", or anything else not in the form "Property=Setting". The example in the reference post linked in the answers seems to be wrong. (Or something changed between versions but I doubt it.)

user2958211
  • 69
  • 1
  • 7

3 Answers3

1

Try this reference of different ways to uninstall an MSI file (option 6 describes DTF):

Unfortunately I don't have Visual Studio available to test with at the moment - I'll still give it a go though I can't test anything. Needless to say this makes answering difficult:

  • It is possible that your silent uninstaller is crashing and this is why it fails in silent mode.
  • Typically this would involve a custom action that might not be conditioned properly and runs inappropriately (or not at all whilst running in silent mode).

Try to enable logging during silent uninstall as shown here (adjust the path to the log file as appropriately). The special ! flag will flush the log file - meaning it is written continuously instead of in batches so no logging is lost due to any potential crashes (this slows the (un)installation process considerably):

using Microsoft.Deployment.WindowsInstaller;

public static void Uninstall( string productCode)
{
   Installer.SetInternalUI(InstallUIOptions.Silent);
   Installer.ConfigureProduct(productCode, 0, InstallState.Absent, "REBOOT=\"R\" /L*V! c:\uninstall.log");
}

To find relevant information in the log file, check out this log file checking tip from Rob Mensching (creator of Wix).

Community
  • 1
  • 1
Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
  • Wow, how long did that take you to write up? And you must have really dug WAY back to find a time that I was still using VBScript. :) – Christopher Painter Apr 16 '15 at 00:55
  • 10 years it would seem. Seems poor Puneet had no idea what "foo" meant. https://community.flexerasoftware.com/showthread.php?153737-How-to-uninstall-a-product-without-using-msiexec-exe – Christopher Painter Apr 16 '15 at 00:58
  • That's one of those "evolved topics" edited and extended dozens of times. And VBScripts are good enough to use still. Not great, but simple and effective with the worlds worst error handling. – Stein Åsmul Apr 16 '15 at 00:59
  • Yes, I remember laughing at your Wikipedia link: http://en.wikipedia.org/wiki/Foo :-). – Stein Åsmul Apr 16 '15 at 01:00
  • The world's worst error handling and interception by virus scanners are what makes scripting unacceptable these days. I can't tell you how many times I've seen "on error resume next" end very, very poorly. – Christopher Painter Apr 16 '15 at 01:03
  • The link provided is exactly the "earlier post" I refer to in my question. I have used the same code, except to add what I think is the quiet parameter, which doesn't work. Look at the code I posted, look at the example in option 6 you refer to. – user2958211 Apr 16 '15 at 01:06
  • Two questions. **1)** Did you verify that productCode resolves to a product code and not an empty string? **2)** Did you try [Tom Blodget's code](http://stackoverflow.com/a/17175837/129130). – Stein Åsmul Apr 16 '15 at 01:11
  • 1) Yes, if I do the ConfigureProduct line with an empty string where the "commandLine" parameter goes, and don't use the SetInternalUi method, then the program runs the MSI and I can see it uninstalling, in other words I see the uninstall UI. 2) Yes, I thought maybe using both SetInternalUi and SetExternalUI like that post would work, but it didn't. – user2958211 Apr 16 '15 at 06:28
  • As I wrote above, I don't have Visual Studio available to test properly, but please see updates in the answer. – Stein Åsmul Apr 16 '15 at 14:52
1

If it uninstalls normally without any errors, then the most likely issue is that the uninstall requires elevation and your code is not running elevated, and so it fails. It will not ask the user for elevation during a silent uninstall!

SetInternalUI works fine for uninstalls. For example, the following C++ snippet does exactly what you want, making the uninstall totally silent:

INSTALLUILEVEL il = MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
UINT n = MsiConfigureProductEx(productid, INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT, L"REBOOT=R"); 

and that ConfigureProduct call uses the same API.

PhilDW
  • 20,260
  • 1
  • 18
  • 28
  • Yes, this is the reason why I get the fatal error. I started the program from an elevated command prompt and it worked. Is there an easy way to run ConfigureProduct in elevated mode using the Microsoft.Deployment.WindowsInstaller API? – user2958211 Apr 22 '15 at 06:55
  • To suppress all UI except UAC prompt, call `MsiSetInternalUI` with `INSTALLUILEVEL_NONE | INSTALLUILEVEL_UACONLY` . – Oleg Aug 29 '22 at 11:46
0

Just to provide a better answer by linking to a new one: Uninstalling program.

UAC & GUI: Essentially your silent uninstall fails because it runs without elevation. When run interactively you get the UAC prompt and can elevate the rights - provided your account is an admin account and allows you to do so. When run silently this elevation can't happen and the uninstall fails. The solution is to run your application executable elevated.

Exception Handling: You might also want to use proper exception handling to ensure that the error message that results from the lack of elevation is reported to the user. See the code in the link above for an example. Here is a quick inlined section:

try
  {
    Installer.SetInternalUI(InstallUIOptions.Silent); // Set MSI GUI level
    Installer.ConfigureProduct(productcode, 0, InstallState.Absent, "REBOOT=\"ReallySuppress\"");
  }
  catch (Exception e)
  {
     Console.WriteLine("Exception: " + e.Message);
     Console.ReadLine (); // Keep console window open
  }
Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164