Install msi with msiexec and c#

2019-07-25 17:08发布

What is the best way to install a .msi in a c# application in silent mode. I want to install a .msi file using msiexec, but I don't know how to do this. The problem is for using msiexec with /qn, you have to run it in a cmd.exe process start "as a administrator" and I don't know how to accomplish something similar with a c# application (for more details, a wpf project in VS 2010). The best I come to is :

Process p = new Process();
p.StartInfo.FileName = "runas.exe";
p.StartInfo.Arguments = "/user:Administrator cmd";
p.Start();

A windows will pop and ask for a password, but I found this behavior pretty ugly. I mean, I don't want to ask the user for his password. Is there anyway way to start my project, set it as a kind of "run as administrator" (the UAC will pop-up, but that's ok) and just run the msiexec command ? Or is there any other way to make a silent install of a .msi file ?

Thank you

标签: c# uac msiexec
1条回答
干净又极端
2楼-- · 2019-07-25 17:38

Despite somebody voted down without comment, this is a very thorough answer IMO: Maybe somebody misunderstood, because the answer is quite long. Recommendation for short reading: Take option 2) .

First, generally, try to avoid RunAs as often you can. With RunAs you are creating a mixed user situation which is not supported by all scenarios and applicatons/processes. With operating systems newer than XP it is not really necessary. Requiring admin rights with UAC (e.g. the correct manifest in the .exe) is at least MS recommendation ! (Just a security remark: Most secure way is still having the admin account completely separated so that neither RunAs nor UAC are normally needed.)

1) The most easy (but not my recommended) method to assure admin rights for a MSI install is doing nothing and let UAC work.

If the MSI needs admin rights, UAC will normally come up itself after some time (not every part of the install process needs admin rights, so it will take some time.

To ensure, that UAC requests come up in child processes, kinda UAC-inheritance, you have to use ShellExecute in the baseline. This is a Windows thing, has nothing to do with MSI or C#.

In C# you can do this like this:

ProcessStartInfo startInfo = new ProcessStartInfo(exeFile, arguments);
StartInfo.UseShellExecute = true;

This is of not much use, if you want a silent installation with no installation dialog (e.g. "/qn") at all.

Moreover the UAC so late has small disadvantages, so the following is recommended and very much safer:

2) Admin rights from the beginning, e.g. in the bootstrapper .exe: If it is sure, that a setup should be started, or in general, your app needs admin rights for it's own or child processes, the best idea ist to assure, that your app itself has already admin rights from the beginning.
In other words, UAC comes up when starting the app. Then your child processes have admin rights too, and it works also for CreateProcess-type child processes and not only for ShellExecute-type.

To achieve this, just add a manifest to your app containing the following line.

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

How to do it?

Given the fact that the whole Windows 7 evangelism was based on manifests ("What is the sense of life? Giving applications a manifest."), Visual Studio in it's different versions of the last years has not really done an excellent job of supporting this. Every version is different, and it is different for C#, C++, VB apps.

For VS 2010 and C# the way to go is: (For VB.Net, it's in 'View Windows Settings' in the solution's Application tab, I've read here.)

In Solution Explorer, right click on the project and select "Add New Item", "New element" and choose "Application Manifest File".

Open this in VS by clicking and you will find the existing node of together with comment lines describing the alternatives. If you don't know about them, it is a good point of googling to learn one of the most important things about modern Windows.
Change the line so that level="requireAdministrator" is configured, and you are done. Your app now needs elevated rights. Try out after build.

(The "uiAccess" attribute, you can ignore, until your app shall control/automate the UI of other apps like in a remote control or UI testing app.)

Start the MSI install normally with "msiexec.exe ...". Don't forget the quotes at the right places and to catch the return code for errors and reboots.

An alternative to msiexec is using the MSI API (socalled external UI), but it is more complicated.

3) No admin rights at all. Unfortunately this is not possible or would break security policies for standard applications which should be installable machine-wide in the programs directory. There is a lot more to say to this in detail of course.

查看更多
登录 后发表回答