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
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.
Related
I'm having a hard time trying to figure out what is causing this odd issue.
So I've created a very basic .msi by following the WiX v3 Setup Project documentation, pretty much just the provided template, but no matter what i try, whenever i go to uninstall it via the Windows 10 Apps & Features interface, i keep getting this:
However, when i uninstall via Control Panel\Programs\Programs and Features or by right-clicking and hitting Uninstall in the .msi's Context Menu, it uninstalls fine.
What am i missing here, should i be implementing something within the installer project to support the Apps & Features uninstall?
Thanks in advance.
AVG Anti Virus: In this case it was AVG anti virus. Uninstalling this product made the uninstall run correctly when
invoked from the new settings GUI in Windows 10.
Blocking: Errors like these often mean something is blocking the uninstall. Please disable or uninstall any anti-virus and / or security software and try again.
General Check List: Please check this answer for a "deployment check list" or "mnemonic" to debug similar problems: Deployment Mnemonic (mid-page). Also see comments above. Sweep for malware with Windows Defender Offline.
Microsoft Tips: Windows cannot access the specified device, path, or file...
Make Log File: To debug, always make an MSI log file:
FireGiant: MSI log "how-to"
Installsite: MSI log "how-to"
Exact Error Message: "Error: Windows cannot access the specified device, path, or file. You may not have the appropriate permission to access the item"
Iam using visual studio setup project (msi installer) for my winforms application. How to remove write permission to c drive programefiles? How to implement file permission step by step in msi installer?
I tried cacls to remove file permission. But it is not works.
The Program Files folder can be written to only with administrator privilege. That means you are asking how to prevent code that is running elevated (with admin privilege) from writing to files in the Program Files folder. It's not clear to me what access restrictions you need that to prevent elevated code from doing what elevated code is supposed to do because that's a security related issue, not an installer question.
The short answer to the design issue is that you should try to run your app with limited user privilege instead of administrator privilege, because limited users cannot write to files in the Program Files folder. However you haven't described the underlying problem you're trying to solve, you've just asked how to implement your proposed solution.
If cacls didn't work, it's impossible to say if it will never work (because you are doing a Just me install, as an example) or if you had an implementation error (because you wrote some kind of custom action to do it and your code is incorrect). The general answer to all these types of question is "write a custom action", but without details of exactly what you tried it's impossible to know why it didn't work, but that's the answer, and if a custom action doesn't work then it's a design or coding problem that requires showing the code and saying if it's an Everyone or Just me install.
I have a project in c# which requires auto update functionality, since it has quite a lot of dependencies and runs a Windows service, ClickOnce installer is not suitable for this work. So I created a setup project for this application. Now I want to include an auto update feature.
My auto-update strategy is:
From the main application, check for updates every morning.
If an update is found, get the msi link
Application passes control to the msiexec and quits
Ex.
msiexec /i http://www.example.com/share/package.msi /L*V "C:\log\example.log"
Since my application is running on administrator account UAC prompt will not occur.
Are there any pitfalls that I haven't seen? Or there any superior way to do auto update gracefully?
Note: The setup project of the application is marked with the property RemoveAllPreviousVersion = True so it will take care of the uninstallation of previous versions.
A couple of comments/answers:
"Note: The setup project of the application is marked with the property RemoveAllPreviousVersion = True so it will take care of the uninstallation of previous versions."
But only if you increment the Version property of the setup project, accept the change in ProductCode, keep the UpgradeCode the same, ensure that the value of EveryOne or Just me is the same in the older product and the upgrade, and increase the file versions of files you need to update.
It's also not obvious to me that you won't get a UAC prompt because "running on an administrator account" does not mean the same as "running with administrator privilege". If the running process is not running elevated a prompt will occur, because UAC means that even administrators are running limited unless explicitly elevated. Even if you are elevated, calling msiexec as an external shell call will not result in msiexec being elevated. A shell execute does not transfer privilege to the offspring process. The other thing to consider is whether it's the current interactive user that is effectively doing this update, because there may be an issue trying to show UI if another user owns the desktop.
Anyway in general it's ok to do that, it's quite common, and signing the MSI would be more secure. Also, Windows Installer will sometimes prompt a repair, so that install URL needs to remain valid. A better approach would be for you to download the MSI to a location on the client system that you own and prompt the user to run it, or you run it - it's more friendly to offer that than pull the rug out and just do it.
I have a C# application, and a Visual Studio (2010) Setup Project with it. In my Setup Project, I am using InstallAllUsers = True. Additionally, my application needs to launch at Startup, so a shortcut is being added to the User's Startup Folder.
So I install my application as user Bob (from a share), and then I log off and log on as user Alice. Alice gets a dialogue that says:
The feature you are trying to use is on a network resource that is unavailable.
It provides the network path from which the MSI was installed. So, basically, it's looking for the MSI on a share that Alice doesn't have access to. This is repeatedly reproducible if Alice tries to manually launch the Startup link. However, Alice can directly launch the exe from the installation location, which works fine.
I don't fully understand why it is looking for an MSI, but I guess it makes sense that an application can not be completely installed by one user for another user, so the MSI is needed to complete the installation.
But if that is the case, then I don't understand why the MSI only seems to be required when launching from the Startup link, and not from the exe directly.
My question has several parts:
Is what I am experiencing expected behaviour for the InstallAllUsers option?
If so, how can I ensure that my application is fully installed for all users?
Is it necessary to copy the msi locally, and ensure that it does not get deleted before each user has had a chance to log on?
This is happening because the shortcuts are "advertised shortcuts" hence the greyed out target box.
More info here...
http://www.advancedinstaller.com/user-guide/advertised-shortcuts.html
When an advertised shortcut is launched it validates the checks
associated with the key resources. If any is missing it will fix it by
running the installation package and installing again all information
from the .msi file.
This is why its trying to run the msi.
You can turn off advertised shortcuts by reading this article...
DISABLEADVTSHORTCUTS=1 disables all shortcuts
If its an all users install, then the shortcut will probably want to reside in the all users start menu. Win 7: C:\ProgramData\Microsoft\Windows\Start Menu.
Eric, I would recommend taking a look at the shortcut file contents. You can do this by using Powershell, and there is a SO link to help you on your way:
Editing shortcut (.lnk) properties with Powershell
I need to get the username of the user running the installer for my custom install action. Because the installer gets special priviledges, Environment.UserName just gives "SYSTEM".
Environment.SpecialFolders.ApplicationData returns the current users appdata folder, but I can't reliably dig the username out of it.
More case specifics:
Using a Visual Studio 2008 Setup Project
The custom action is an installer class run after install and is the only one in the project.
You can get some information from Environment variables. I am using
Environment.GetEnvironmentVariable("USERNAME");
to get current user name.
Basically, you can't.
UAC in MSI Notes: Credential Prompt and Permissions explains some of this is more detail, but effectively once you've elevated your credentials the currently logged in user is SYSTEM from the installers point of view (you can have multiple people logged in and running applications on a machine, so you have to think from the context of the process itself rather than who is sitting in front of the physical machine).
Use WindowsIdentity.GetCurrent().Name from the System.Security.Principal namespace. This will include the domain portion as well so if you don't need that add a split to the end of it. WindowsIdentity.GetCurrent().Name.Split('')[1].
using System.Security.Principal;
this.nametext = WindowsIdentity.GetCurrent().Name.Split('')[1];
First, make sure you have the Impersonate bit set to OFF. Here is how.
Unfortunately, there is not a way to
directly set this flag for a custom
action in the UI for the setup project
in the Visual Studio IDE. In Visual
Studio 2005, you can use a post-build
step that modifies the MSI to set this
bit using a strategy previously
described in this blog post.
Second, I assume you are running Vista because people seem to have this problem with Vista and someone asked this question on MSDN and his solution was to follow the blog post linked here.
Robert Flaming's Blog post on UAC in MSI Notes: The NoImpersonate Bit Mistake also gives some insight into these issues.
I've never touched VS setup projects (played with WiX though and can recommend it). Looking at your problem it seems that your CA runs deferred (and with elevated privileges).
Searching the net for VS setup projects I came across a lengthy article 1 that contained this paragraph (search for "deferred"):
In other words, the Visual Studio design restricts you to custom actions that are called when your files are on the system (deferred custom actions), which means that you must use the CustomActionData property. Other tools that generate MSI files are often more flexible, so if you anticipate complex setups, investigate those tools.
1: http://www.simple-talk.com/dotnet/visual-studio/visual-studio-setup---projects-and-custom-actions/