I have a task to develop an update agent that launches an msi file after downloading it, the installation has to be invisible to the user.
But i have a problem with launching it with no UI. I tried using /q and /qn but it doesn't work, it only works with UI options.
internal static class MSI_runner
{
public static bool RunInstallMSI(string sMSIPath)
{
try
{
Console.WriteLine("begin");
//Starting to install application
Process process = new Process();
process.StartInfo.FileName = "msiexec.exe";
process.StartInfo.Arguments = string.Format(" /q /i \"{0}\" REINSTALLMODE=amus ", sMSIPath);
Console.WriteLine("start");
process.Start();
process.WaitForExit();
Console.WriteLine("end");
return true;
}
catch
{
// "There was a problem installing the application!
return false; //Return False if process ended unsuccessfully
}
}
}
The most likely reason is that the install requires elevation, so there are a few things that this affects, but there are some guesses here because your "but it doesn't work" isn't very specific.
When you run it in UI mode it probably asks for elevation. An administrator would just get an elevation prompt, a limited user would be asked to enter admin credentials. Either way, it runs elevated. When you run it silently the elevation prompt is not shown (silent means silent) and therefore it fails silently too because it requires elevated privileges.
Your code almost certainly defaults to ProcessStartInfo.UseShellExecute=true, so any credentials of the process will not be used to launch the MSI. In situations where the MSI needs elevation and you want to install it silently you must give your exe a manifest for elevation (so it prompts) or runs elevated some other way. You also need UseShellExecute to be false so that the launch is a CreateProcess type of launch where the process privileges are inherited into the process you launch. In addition, there's also no real need to launch anything and get into this type of issue. If your process is elevated then just call MsiInstallProduct passing the path to the MSI and the command line. Then you know that the install runs with your privileges.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa370315(v=vs.85).aspx
Assuming that your code is working, and as an aside, it's not clear what type of upgrade you are expecting. There's no mention of whether your MSI has a new ProductCode, ProductVersion etc. The normal method of applying a small update by reinstalling a new MSI with REINSTALLMODE is here:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa367575(v=vs.85).aspx
and REINSTALLMODE should be vomus.
try cactch (Exception ex) and see what ex.message is.
check here for msiexec params :
http://www.advancedinstaller.com/user-guide/msiexec.html
Related
I'm having problems with a program and its buttons (I know, I'm awesome lol) the buttons can be "programmed" to run programs. They also can be set to run as admin (different credentials).
If I set up simply notepad or cmd or explorer it runs like charm. But if I start iexplore it has got no admin rights.
I had problems before with running explorer.exe the solution was that I had to run it by typing the full path C:\windows\explorer.exe to be able to run it but that I solved it by setting up the VB2015 compiler (?) to Platform target: x64.
My other problem is that if I try to run dsa.msc or generally anything ends with msc it throws the following exception, even if I set up the full path to the syswow64 (or the system32) folder like c:\windows\syswow64\dsa.msc
"The specified executable is not a valid application for this OS platform."
Running the C:\Windows\System32\mmc.exe "services.msc" (or syswow64, with or without the /computer= switch) throws
"The requested operation requires elevation." which I have since I'm able to run services.msc (and all other msc-s from command line with the same user rights)
Thank you.
A beginner.
Basically you don't need to run the host app as administrator! There is a variable (inside your Process instance) called StartInfo (which is an instance of the ProcessStartInfo Class), where Verbs could be used as followed:
Process p = new Process()
{
StartInfo = new ProcessStartInfo("E:\\Users\\Temp\\app.exe")
{
Verb = "runas"
}
};
p.Start();
This will prompt the user to run the app.exe as administrator.
Edit
Running a Process as a defined user:
Process p = new Process()
{
StartInfo = new ProcessStartInfo("E:\\Users\\Temp\\app.exe")
{
Verb = "runas",
Arguments = "/user:Vira"
}
};
For more information about those RUNAS Arguments, click me! :)
I'm running msiexec.exe with the following code.
Process setupProc = new Process();
setupProc.StartInfo.UseShellExecute = true;
setupProc.StartInfo.CreateNoWindow = true;
setupProc.StartInfo.FileName = "msiexec.exe";
setupProc.StartInfo.Arguments = String.Format("/i \"{0}\" /qn {1}",
sSetupFilePath, installerProperties);
setupProc.StartInfo.Verb = "runas";
setupProc.Start();
I want to change Program Name in the UAC, Is this possible at all to change program name.
Program name coming as "C:\Windows\SysWOW64\msiexec.exe with the arguments I provide to run.
I just want to get rid of the arguments coming the rhe msiexec.exe.
I did lot of rnd but could not get possible solution and I think it is not possible.
You should explain what your actual goal is. For example, if you wish to launch an MSI install from a standalone process, then give that process an elevation manifest so it will request elevation (your program name) and run elevated, and then use the CreateProcess version of your code, UseShellExecute=false.
Or if your code is already running elevated just set UseShellExecute=false.
In both cases msiexec will run elevated and not show elevation requests because you are firing it off in CreateProcess mode.
BTW, if you're running this from a custom action of an MSI install there's a good chance it will fail - this is really not recommended at all.
I need to run "manage-bde" shell command from C# code.
The main application process is already running as administrator and is Elevated.
I used code from : UAC self-elevation example on MS website for confirming the app process is elevated.
(http://code.msdn.microsoft.com/windowsdesktop/CSUACSelfElevation-644673d3)
However, when I try to run manage-bde from the C# code, I get "System can't find file specified".
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\System32\\manage-bde.exe";
p.StartInfo.UseShellExecute = true;
p.Start();
As a workaround, I tried to create a batch file that runs the command.
string batchFileName = DateTime.Now.Ticks + ".bat";
StreamWriter writer = new StreamWriter(batchFileName);
writer.WriteLine("manage-bde");
writer.Flush();
writer.Close();
Process p = new Process();
p.StartInfo.FileName = batchFileName;
p.StartInfo.UseShellExecute = true;
p.Start();
The batch file is written , and executed successfully; However, the command "manage-bde" is not recognized.
I changed the code to use the verb "runas" and use admin password and that works, but I want the batch file to work without the need for providing the admin password. The current logged in user is already administrator on the computer but the batch file is not getting executed with the existing admin privileges . I need the batch file to execute and manage-bde to run successfully.
Your help or advice will be very highly appreciated :)
ps: some commands other than manage-bde work fine without need for admin runas.
The reason of the behavior I encountered was the Windows File System Redirector.
In most cases, whenever a 32-bit application attempts to access %windir%\System32, the access is redirected to %windir%\SysWOW64
https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187%28v=vs.85%29.aspx
My application build was 32 bits. Whenever it tried to access System32 windows automatically redirected it to SysWow64 which does not contain "manage-bde.exe". I changed the build to 64 bits and then the application could access manage-bde.exe from System32
Even if you're running as the Administrator user, you're not fully elevated if UAC is running. Meaning that you'll have either the UAC prompt come up or you'll be prompted for a password.
The only real way you could get around that is to run your application elevated first, or to write a service that runs with elevated permissions to start your new process.
The alternative of course is to disable UAC, but that is undesirable in most situations.
I was always under the impression that when you're running a process as (domain\user) mydomain\myuser, when using Process.Start() it would start this new process using the same credentials - mydomain\myuser.
The issue I'm having is that my Process.Start() call seems to be creating a process under the SYSTEM account which is causing me permission issues in the started process (which must run under an admin account due to the work it does). If it changes things - I'm spawning this process (a custom built exe) from within a windows installer.
Any suggestions? I've read about windows group policies (possibly) having an impact on this, but if I'm honest, it's lost on me.
EDIT: a little snippet:
Where exename and commandLine are parameters for this method body:
ProcessStartInfo procInfo = new ProcessStartInfo(exeName, commandLine);
procInfo.WorkingDirectory = workingDirectory;
procInfo.UseShellExecute = false;
procInfo.CreateNoWindow = true;
Process process = Process.Start(procInfo);
Process.WaitForExit();
return process.ExitCode;
Either set procInfo.UseShellExecute to true, or execute cmd as a process with your exe as a parameter to the cmd command. When UseShellExecute is set to false, here are a lot of interesting side effects: UseShellExecute
Your impression is true. Process.Start() will always start the new process under current user's credentials - unless you provide alternative credentials in the ProcessStartInfo or use one of the overloads that take credentials.
There must be another problem - share a snippet of your code.
UPDATE
OK! You did not mention anything about installer. All MSI installers will be running under system since they will be run by "Windows Installer" which you can check and they run under SYSTEM.
my application include a self-updater executable that is used to update the application.
One of the first steps the updater is performing is to check that it does have write permission to the application folder
IPermission perm = new FileIOPermission(FileIOPermissionAccess.AllAccess, _localApplicationCodebase);
if (!SecurityManager.IsGranted(perm))
{
OnProgressChanged("Security Permission Not Granted \n The updater does not have read/write access to the application's files (" +
_localApplicationCodebase + ")",MessageTypes.Error);
return false;
}
OnProgressChanged("Updater have read/write access to local application files at " + _localApplicationCodebase);
return true;
When executing under Win7/Vista, this code pass (meaning that according to CAS, the code does have write access), however when I try to write files, I got an Access Denied (and I confirmed that the files are NOT in use)
I understand that Vista/Win7 UAC is preventing users from writing files in the program files folders. However, what I don't understand is why the permission is granted if in reality it is not
Regards,
Eric Girard
PS : If I run the same code using 'Run As Administrator', it works fine
The important thing to know about UAC is that by default, no code runs with Administrator privileges and thus cannot write to the Program Files directory. Even if you are logged in as an administrator, the apps are launched with standard user privliges.
There are two ways around this. You can have the user start the app with the Run As Administrator menu item. But this relies on the user to remember something. The better was is to embed a manifest into your executable that requests administrator privileges. In the manifest, set requestedExecutionLevel to requireAdministrator. This will cause UAC to prompt the user for admin credentials as soon as the app starts.
As Daniel said, the best solution is to put the updating functionality in a separate application. Your primary app will have an manifest that sets the requestedExecutionLevel to "asInvoker" and your updater app with request "requireAdministrator". Your primary app can run with standard privileges. But when the update needs to happen, use Process.Start to launch the updater application that requires the user to enter the admin credentials.
The best way to write an auto updater is to have a secondary application. The first program calls the second with elevated privileges, prompting UAC. Then the second application can install the patches.
I'm not sure if this is what you're trying to do, but I've found this post helpful. The included code let's you detect if you're app is running on Vista, if UAC is enabled and if user is elevated.
http://www.itwriting.com/blog/198-c-code-to-detect-uac-elevation-on-vista.html
then restart your app with runas to let user elevate permissions
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.Verb = "runas";
processInfo.FileName = Application.ExecutablePath;
Process.Start(processInfo);