I am trying to insert msi file using asp.net application. when i run visual studio in administrators mode it is working fine but when i run it in normal mode it is not working.
I had tried following code:
string installerFilePath;
installerFilePath = #"D:\ActivexPractice\test\test\NewFolder1\setup.msi";
System.Diagnostics.Process installerProcess = System.Diagnostics.Process.Start(installerFilePath, "/q");
can any body guide me on this
how to install it without administrators right
You can use msiexec.exe to run installer. Here is sample code.
Process installerProcess = new Process();
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.Arguments = #"/i D:\ActivexPractice\test\test\NewFolder1\setup.msi /q";
processInfo.FileName = "msiexec";
installerProcess.StartInfo = processInfo;
installerProcess.Start();
installerProcess.WaitForExit();
If the MSI requires admin rights to install then it will ask for elevation in a UI install. Your /q is failing because a silent install is really silent and will not prompt for elevation. Note that limited users are not allowed to break security rules simply because they are doing an install.
So in that situation your launching process would need to be elevated, either by running as administrator or giving it a requiresAdministrator manifest so it asks for elevation.
When you fire off the install you need to make sure that your elevated state is used to fire off the install. The simplest way to guarantee this is to just call (p/invoke to...) MsiInstallProduct () directly from your code. The issue with Process.Start is that by default ProcessStartInfo.UseShellExecute is true and your elevated state (if you have one) will not be used to start the install. When the install is launched it needs to be a CreateProcess type of execution rather than a ShellExecute type so that your elevated credentials are used.
static void installMSIs(string path)
{
string[] allFiles = Directory.GetFiles(path, "*.msi");
foreach (string file in allFiles)
{
System.Diagnostics.Process installerProcess =
System.Diagnostics.Process.Start(file, "/q");
while (installerProcess.HasExited == false)
{
installerProcess.WaitForExit();
}
}
}
Related
I have an elevated C# exe file that can run elevated commands using System.Diagnostics.Process just fine, however I need to run a specifically unelevated command - that being subst. I am not sure whether I should (or respectively could) make a secondary .exe file or .bat or something?
There is an alternative, as there is only one command that requires admin privileges to run - that being a WSL mount command. Can I make the C# script unelevated and just elevate that one specific command, or vice versa?
I've tried using runas /trustlevel:0x20000, but that throws an access denied (even though the directory being accessed by the SUBST command is \\WSL$\
As for the alternative solution I've tried the following code:
startInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.Arguments = $"/c powershell -command wsl --mount \\.\PHYSICALDRIVE1 --partition 2;pause"
startInfo.Verb = "runas";
Process proc = Process.Start(startInfo)
proc.WaitForExit();
That opens up an UAC prompt, opens up an elevated powershell Window, but for some reason doesn't recognize "WSL" as a command, even when using it's absolute path.
Fixing either method would fix the issue.
I have an issue where I'm trying to deploy a driver installation via an MSI Installer, it contains the .CAT and .INF files and outputs them to a directory, typically from here an infrastructure engineer could right click the .INF file and press install, however we're trying to streamline this process and automate this step.
Via C# I have a class utilising the System.Diagnostics.Process namespace to spawn a powershell process to run a powershell script containing a simple command as follows:
var process = new System.Diagnostics.Process();
var newProcessInfo = new System.Diagnostics.ProcessStartInfo();
string powerShellScript = #"C:\PowershellScript\DriverInstall.ps1"
newProcessInfo.FileName = #"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
newProcessInfo.Verb = "runas";
string newArgs = "-File " + powerShellScript;
newProcessInfo.Arguments = newArgs;
process.StartInfo = newProcessInfo;
process.Start();
Powershell script command is as follows:
Get-ChildItem "C:\DriverLocation" -Recurse -Filter "*inf" | ForEach-Object {PNPUtil.exe /add-driver $_.FullName /install }
when running this from powershell it works as expected, however if I try and spawn a powershell process from a C# class it doesn't work, comes up with some red error message text but the process windows spawns and closes immediately so I can't identify what the error is.
Essentially I either need the output from the powershell process to a text file or I need the powershell window to persist so I can identify why the script won't work when running from the System.Diagnostics.Process namespace.
I have tried editing the registries so that powershell will remain open to no avail.
Please don't suggest using the System.Management.Automation.Powershell namespace because utilisation of .NET core is unavailable in our project scenario.
Thanks for taking the time to read this, any help is much appreciated.
Resolution was to specify the execution policy within the powershell script, when running from the powershell window it had local admin rights and therefore didn't need an execution policy specified, however because it was being spawned from a separate process it only had remote access rights, therefore it wouldn't allow the script to execute.. never managed to output the particular error message but by process of elimination identified the resolution.
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
I have a .exe file which checks the system architecture and based on the system architecture it calls the corresponding msi file.
I am trying to run this exe file from C# using the code below
Process process = new Process();
process.StartInfo.FileName = "my.exe";
process.StartInfo.Arguments = "/quiet";
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.WorkingDirectory = "path//to//exe//directory";
Console.WriteLine(process.StartInfo.WorkingDirectory);
process.Start();
process.WaitForExit();
The exe is getting invoked. i can see the application logs and there are no errors in the logs.
But the msi is not getting started or installed.
When I try to run the same exe file manually the msi is installed.
Note: There are other dependency files for this my.exe which are placed in the same directory.
Why am i not able to install the msi from C# program while i am able to do this manually.
I am running the VisualStudios in administrator mode.
You need to execute .exe (and msi) as an administrator.
To ensure that, use:
process.StartInfo.Verb = "runas"
Also, try it removing quiet arguments to see any possible errors.
Is "my.exe" installing your MSI if you call it, isn't it?
I got this resolved after i added Thread.Sleep(). before "process.WaitForExit()"
I finished my software and I'm not able to find a correct way to create its setup.
I searched the web and here but I found only old post referring old visual studio versions.
As I know in VS 2013 community edition I have a limited Installshield plugin and I was able to download the Visual Studio Installer plugin too. To create a simple setup is relatively easy but I need to silent install a small software during my setup. The software is Double Agent (an updated version of the Microsoft Agent) and the developer recommend to launch the setup in this way:
Simply run:
msiexec /i DoubleAgent_x86.msi /qb-!
during your setup (i think the best place should be the Commit event).
By the way it's not possible to launch .msi installer with an action and I really don't understand the best practice to create a custom action.
I read something about to create a class but most articles refer to Visual Studio 2008 or to Wix plugin. I'm searching a way to use Msiexec with Visual Studio Installer or installshield.
Edit: I found this solution and it works so good: https://msdn.microsoft.com/it-it/library/vstudio/d9k65z2d%28v=vs.100%29.aspx
It's in Italian but it's easy to translate to the original language (English) with the top right radio button. It's working perfectly with Visual Studio Setup plugin and VS Community edition 2013.
I have no code to post at this time because I built only their sample but I will post it asap with the usage of msiexec for the hidden installation.
I created a test winform project, I added the installer class with this code:
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
public override void Commit(IDictionary savedState)
{
base.Commit(savedState);
// Use ProcessStartInfo class
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "msiexec.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = "/i DoubleAgent.msi /qb-!";
try
{
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
catch
{
// Log error.
}
}
And I created the setup with Visual Studio installer. At the end of the main setup something start saying there is another installation but the double agent does not install.
Edit again: I have not Admin right to execute msiexec silently. I think because the Double Agent setup need admin rights. I don't want to use manifest to elevate privileges then I think the only solution is to show the DoubleAgent installer (also if in minimal output).
By the way I have this code working in form 1 Button:
private void button1_Click(object sender, EventArgs e)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.FileName = "msiexec.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = "/i DoubleAgent.msi /qn";
try
{
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
MessageBox.Show("Finish");
}
}
catch
{
// Log error.
}
}
But the same code does not work during the installation process.
This isn't going to work! One MSI setup cannot launch another MSI setup. When it says "another install is in progress" it is referring to your one that is already running. It's not about admin privilege - you cannot install another MSI from an installer custom action, no matter what that developer says.
In general this is what bootstrappers are for, to install prerequisites before installing the main MSI. That's why even VS setups let you generate a setup.exe to install prerequisites (many of which are MSI-based) before installing your MSI.
So you'll need to figure out a bootstrapper (don't know if InstallShield LE has one) that will install that MSI. There used to be a tool called Bootstrap Manifest Generator that you could use to tailor the setup.exe to install custom prerequisiyes like yours. Or you could use the bootstrapper from WiX to install that MSI then your MSI. Or you could just copy that MSI to the system and have your app install it the first time it is used.
Or maybe that agent software is available as merge modules, in which case you just add the merge modules to your MSI build.
Sometimes I need to delete or replace a dll file in system32 folder of windows 7.
The code below always has Permission Denied Error :
if (File.Exists(#"C:\Windows\system32\mydll.dll"))
{
fileInfo.IsReadOnly = false;
File.Delete(#"C:\Windows\system32\mydll.dll");
}
How can I bypass this error and replace a file in system32 folder?
A user doesn't have sufficient rights to delete files from c:\windows\system32 on Windows Vista and up. Even when logged-on using an administrator account. UAC puts a stop to it. You must ask for elevation to let the user know that you are about to tinker with the private parts. That requires embedding a manifest in your program to trigger the UAC prompt. This answer shows you how.
if (File.Exists(#"C:\Windows\System32\mydll.dll"))
{
new Process() { StartInfo = new ProcessStartInfo("cmd.exe", #"/k takeown /f C:\Windows\System32\mydll.dll && icacls C:\Windows\System32\mydll.dll /grant %username%:F") }.Start();
File.Delete(#"C:\Windows\System32\mydll.dll");
}
Note that you can't delete a system DLL like shell32.dll even after taking ownership but you can rename or move it.