I have a WebAPI that works great but need to add the ability to call to an EXE on the server to run some tasks with Video, the server is our machine and running IIS to host the WebAPI.
I have tried it working with Process() and the calls make it to the cmd.exe file I have written but the issue is that the user is IUSER and this won't work as the Video processing needs to use system hardware so needs to be the current logged in Windows User.
I don't want to give the IUSER this privilege for obvious security reasons so I am looking for another way to call and pass data to the an EXE or background task (Short running <3seconds) and for that process to reply with the results.
It's all on the server which we have full control over.
Current Code:
string exeLoc = Environment.ExpandEnvironmentVariables(baseEXELocation);
using var process = new Process();
process.StartInfo.FileName = exeLoc;
process.StartInfo.Arguments = $"{command}";
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += (sender, data) =>
{
if (!String.IsNullOrEmpty(data.Data))
{
Console.WriteLine(data.Data);
consoleData += data.Data;
}
};
process.Start();
process.BeginOutputReadLine();
var exited = process.WaitForExit(1000 * 10); // (optional) wait up to 10 seconds
Thanks
You could try to use the impersonation in iis:
<identity impersonate="true" />
https://support.microsoft.com/en-us/help/306158/how-to-implement-impersonation-in-an-asp-net-application
or assign the administrator permission to the application pool by using application pool advance setting -> identity to the custom account.
or You can try using the verb runas in Process.Start to execute the exe file as an Administrator.
ProcessStartInfo proc = new ProcessStartInfo();
proc.WindowStyle = ProcessWindowStyle.Normal;
proc.FileName = myExePath;
proc.CreateNoWindow = false;
proc.UseShellExecute = false;
proc.Verb = "runas"; //this is how you pass this verb
Related
I'm setting local auditing policies from a C# .NET program that reads settings from a file then uses Process.Start() with 'cmd' to execute the commands. This way has worked in the past for everything that I've needed it to do (including this exact situation), but recently it's just started to mysteriously fail to set the policies.
Here's the code: (command is of the form "auditpol /set /subcategory:"blah" /success:enable")
ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
string result = proc.StandardOutput.ReadToEnd();
string error = proc.StandardError.ReadToEnd();
In debug in VS2013 it's applying the policies just fine and even on the same computer in the full on .exe it's applying just fine, but when it gets transferred to another computer it will not set the policies from the auditpol command. Anyone have any ideas what could be happening?
I am trying to restart a windows service from the same windows service with this piece of code
var proc = new Process();
var psi = new ProcessStartInfo();
psi.CreateNoWindow = true;
psi.FileName = "cmd.exe";
psi.Arguments = "/C net stop \"EmailService-3.1.0\ && net start \"EmailService-3.1.0\"";
psi.LoadUserProfile = false;
psi.UseShellExecute = false;
psi.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo = psi;
It is not working and I have no idea why, is there anything I can do to log or determine what is happening or get the output of what is happening when the net stop command is called?
You can redirect the output of the net stop command, but as per TomT's comment, this seems a very roundabout way to restart a service.
psi.Arguments = "/C net stop \"EmailService-3.1.0\" > C:\\svclog.txt "; //&& net start \"EmailService-3.1.0\"";
I can see a missing quotation mark after the name of your service in the stop command. Otherwise it can be a permission issue. Maybe the user with whom your service has logged in does not have enough privileges to stop a service.
Yes, there are many articles related to elevating permissions when installing MSI packages. I have a twist on the issue that I can't find a good answer to. If I'm logged in as a user and I run my MSI elevation code (Below), the package installs but the current user actions are performed on the user I elevated the installer with.
For example, if the MSI adds a file to the CURRENT USER's desktop. The result of elevation (running as "Joe Admin") is the file gets put on Joe Admin's desktop -not the currently logged in user ("Sally User"). I have owned software that Elevates as Joe but puts the file on Sally's desktop as if she installed it. -I'd like to write my own. This is on a Windows 7 Machine, UAC is turned off.
Here is the non-working code. (Sally is logged in, Elevate as Joe -File goes to Joe's Desktop) (LoadUserProfile property was an attempt to solve this issue -didn't work).
Process watchThis = ImpersonateInstaller(#"c:\temp\Test.msi", "SuperJoePassword");
watchThis.WaitForExit();
private static Process ImpersonateInstaller(string msiPath, string Password)
{
Domain d = Domain.GetCurrentDomain();
Process process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.LoadUserProfile = true;
process.StartInfo.FileName = #"C:\Windows\System32\msiexec.exe";
process.StartInfo.Arguments = string.Format(#"/i {0} REBOOT=ReallySuppress /qb-", msiPath);
process.StartInfo.WorkingDirectory = Environment.GetEnvironmentVariable("WINDIR");
process.StartInfo.UserName = "JoeAdmin";
process.StartInfo.Password = new SecureString();
process.StartInfo.Domain = d.ToString();
foreach (char c in Password.ToCharArray())
{
process.StartInfo.Password.AppendChar(c);
}
process.Start();
return process;
}
From an elevated process call msiexec /jm foo.msi to perform an advertisement. This blesses the package. From a standard user process call msiexec /I foo.msi REBOOT=R /qb and this will start the installation off as the user but elevate seamlessly as needed. Standard Actions and Custom Actions with No Impersonation will run as SYSTEM and Custom Actions with Impeornation will run as the user without privs as designed.
With Help from Christopher Painter, this appears to be the answer (THANKS CHRISTOPHER!!!)
I've read the words "advertise" before and always assumed it had something to do with 'publishing in GPO' so I never follwoed through. Seems I'm wrong. Here's the trick should anyone else run across this.
First, advertise with elevated rights to "bless" the msi for end user installation. In my mind an adminstrator is saying, sure this msi is safe for Sally end user to install:
msiexec.exe /jm install.msi
Then, install as the end user as if they are admin:
msiexec.exe /i install.msi /your /typcial /installOption /switches /here
My code (surely could be better):
Process advertise = advertiseMSI(#"c:\temp\test.msi", "JoeWhoHasAdminRights", "Joe'sSuperPassword");
advertise.WaitForExit();
Process install = installMSI(#"c:\temp\test.msi");
install.WaitForExit();
private static Process advertiseMSI(string msiPath, string userName, string Password)
{
Domain domain = Domain.GetCurrentDomain();
Process process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = #"C:\Windows\System32\msiexec.exe";
process.StartInfo.Arguments = string.Format(#"/jm {0}", msiPath);
process.StartInfo.WorkingDirectory = Environment.GetEnvironmentVariable("WINDIR");
process.StartInfo.UserName = userName;
process.StartInfo.Password = new SecureString();
foreach (char c in Password.ToCharArray())
{
process.StartInfo.Password.AppendChar(c);
}
process.StartInfo.Domain = domain.ToString();
process.Start();
return process;
}
private static Process installMSI(string msiPath)
{
Process process = new Process();
process.StartInfo.FileName = #"C:\Windows\System32\msiexec.exe";
process.StartInfo.Arguments = string.Format(#"/i {0} REBOOT=ReallySuppress /qb-", msiPath);
process.StartInfo.WorkingDirectory = Environment.GetEnvironmentVariable("WINDIR");
process.Start();
return process;
}
I'm running a batch file from some ASP.NET/C# code on a web server. Basically the batch file performs some test automation tasks on a VM using tools like psloggedon and pexec.
If I run the batch file manually when I'm logged into the server under an administrative account, it works fine.
My problem comes when I run it from my code (below), it seems to run under the 'SYSTEM' account, and psloggedon etc. don't seem to work correctly.
Code
Process p = new Process();
p.StartInfo.FileName = "C:\SetupVM.bat";
p.Start();
p.WaitForExit();
I've got this in my web.config, it doesn't seem to make any differance?
<identity impersonate="true" userName="Administrator" password="myadminpassword"/>
Is there anyway I can ensure the batch file runs under the 'Administrator' account?
UPDATED CODE
Process p = new Process();
p.StartInfo.FileName = "C:\\SetupVM.bat";
p.StartInfo.UserName = "Administrator";
p.StartInfo.UseShellExecute = false;
p.StartInfo.WorkingDirectory = "C:\\";
string prePassword = "myadminpassword";
SecureString passwordSecure = new SecureString();
char[] passwordChars = prePassword.ToCharArray();
foreach (char c in passwordChars)
{
passwordSecure.AppendChar(c);
}
p.StartInfo.Password = passwordSecure;
p.Start();
p.WaitForExit();
From MSDN:
When UseShellExecute is false, you can start only executables with the Process component.
Maybe this is the issue as I'm trying to run a .bat file?
Thanks.
You can provide the username and password to the StartInfo:
Process p = new Process();
p.StartInfo.FileName = "C:\SetupVM.bat";
p.StartInfo.UserName = "Administrator";
p.StartInfo.Password = "AdminPassword";
p.Start();
p.WaitForExit();
See the documentation for ProcessStartInfo.
We have an asp.net application that is able to create .air files.
To do this we use the following code:
System.Diagnostics.Process process = new System.Diagnostics.Process();
//process.StartInfo.FileName = strBatchFile;
if (File.Exists(#"C:\Program Files\Java\jre6\bin\java.exe"))
{
process.StartInfo.FileName = #"C:\Program Files\Java\jre6\bin\java.exe";
}
else
{
process.StartInfo.FileName = #"C:\Program Files (x86)\Java\jre6\bin\java.exe";
}
process.StartInfo.Arguments = GetArguments();
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.UseShellExecute = false;
process.PriorityClass = ProcessPriorityClass.Idle;
process.Start();
string strOutput = process.StandardOutput.ReadToEnd();
string strError = process.StandardError.ReadToEnd();
HttpContext.Current.Response.Write(strOutput + "<p>" + strError + "</p>");
process.WaitForExit();
Well the problem now is that sometimes the cpu of the server is reaching 100% causing the application to run very slow and even lose sessions (we think this is the problem).
Is there any other solution on how to generate air files or run an external process without interfering with the asp.net application?
Cheers,
M.
The problem is here: process.WaitForExit();, you are simply halting the execution of the application. You might want to use a thread to start the process and some sort of IPC (Inter Process Communication, like remoting, named pipes) to know when the generation is finished.