Running Process on Server via ASP.NET/C# on IIS - c#

What I am trying to do is run a batch file that is located on the webserver's desktop when a button is clicked. This is what I have thus far.
ProcessStartInfo psi = new ProcessStartInfo("Notepad.exe");
psi.WorkingDirectory = #"C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Accessories";
psi.UseShellExecute = false;
psi.UserName = "administrator"; //username
psi.Password = secure; //secure string
var process = Process.Start(psi);
When I debug it, it does exactly what I want it to, but when I access the site on IIS (localhost:81) the batch file never runs. I've tried many different variants of ProcessStartInfo and Process with no luck. I've tested the username and password and they are both correct too.
I don't get any errors, the button just triggers a page post back.
I have given IUSR and IIS_IUSRS permissions to the file, and still nothing runs. I also removed the username and password and set the UseShellExecute to true, but that did nothing as well.
EDIT:
It looks like everyone thinks its some permissions. Any idea on what I need to do to allow IIS to open the process?
Thanks in advance!

Just change the third line to this:
psi.UseShellExecute = true;
or read this article which really gets the work done:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;889251

Related

C# / .Net: Run CMD as admin with provided credentials

i searched for this some hours today but i only find solutions that wont work.
Maybe it is impossible but let's give it a try:
I'm in a company and I will write some code so that a user can run the software whenever he need it. The software needs administrator-permissions. For example I've wrote some code to start the cmd as admin and create a folder at c:/Windows (you'll need admin-permission for that). The credentials for the admin account are right (we use Microsoft AD) but I only get "Access denied" in the cmd.
Does anyone know whether it is possible to get admin permission with hard coded credentials?
Note: Don't talk about security risks, the cmd is not the target software but it should demonstrate the problem.
My code:
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = #"/Kmkdir C:\Windows\_Test";
p.StartInfo.UserName = "admin";
System.Security.SecureString sPW = new System.Security.SecureString();
sPW.AppendChar('a');
sPW.AppendChar('b');
sPW.AppendChar('c');
p.StartInfo.Password = sPW;
p.StartInfo.UseShellExecute = false;
p.Start();
You are still getting an error because all admin accounts in newer windows versions (since Vista) technically are standard user accounts. The way administrative tasks are performed is through the User Account Control (UAC). It allows you to elevate permissions as administrator to perform administrative tasks. So yes, you are executing the process using an administrator account, but you did not elevate the process. To do so, add this parameter:
p.StartInfo.Verb = "runas";
p.StartInfo.UseShellExecute = true;
You can remove all other parameters regarding authentication, since all the authentication is handled by UAC. If for some reason you wish not to use UAC, then you probably will have to disable it, which is not recommended in most cases.

How to fix DirectoryNotFoundException while using Process in Web App

I'm using Pdf2Text in an ASP.NET web app. The web interface allows PDF files to be uploaded and converted to text. To convert to text, I use the C# function below, which relies on running the Pdf2Text program via the Process library.
void ExtractOCR(string input, string output)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = true;
startInfo.FileName = Server.MapPath("ocr/Pdf2Text.exe");
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = input + " " + output;
Process exeProcess;
using (exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
I've double-checked that the input and output paths are all valid. However, when I run the web app, I get the following error.
I've tried the Just-In-Time debugger but it won't even run for some reason. The Pdf2Text is a precompiled file, I don't have it's source code. I believe this is the file's download site, but not 100% sure. I've checked online to find solutions to similar errors but none has worked.
Thank you #GraDea for suggesting to look into the pool's permissions into the web app directory, this was the solution.
The web app was located at a custom location (not the default ASP server directory of inetpub\wwwroot). After the suggestion, I tried adding the pool user to the web app's custom location, but that didn't seem to work. Next, I moved the web app to the inetpub\wwwroot location and added the pool user to the folder, restarted the site via IIS and everything is now back to normal.
For future reference to anyone, easiest fix to a similar problem is to make sure your web app is in the default IIS server directory, and that your site pool's username is added to the application folder's security permissions. I've not tried the fix for a custom location because it's not so important for me, but I'm guessing it will most likely also involve adding the necessary IIS default pool users (e.g. IIS_IUSRS) and the site pool's user.

Failing to run C# process as different user

I'm trying to run djoin.exe tool with System.Diagnostics.Process from a C# service using a different user (not as the service user).
The process returns code -1073741502.
In the event log I can see:
Application popup: djoin.exe - Application Error : The application was
unable to start correctly (0xc0000142). Click OK to close the
application.
No stderr or stdout.
Here is the process configurations I used:
ProcessStartInfo startInfo = new ProcessStartInfo
{
Arguments = "/Provision /Domain domain.com /Machine PC12 /SaveFile NUL /printblob",
WorkingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
FileName = "djoin.exe"
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow =true,
Domain = "domain.com",
UserName = "other-user",
Password = "***"
};
if (username!=null)
{
startInfo.Domain = domain;
startInfo.UserName = username;
startInfo.Password = ToSecureString(password);
}
p = new Process { StartInfo = startInfo };
p.Start();
When using the RUNAS command, everything works fine.
What is the problem?
Seems like it is a permissions issue. This can either be at the folder level of where the exe is located, or to do with the user that the process is running under.
To diagnose this, you can first go to the folder where the exe is located. Then right click and set the permissions to "everyone" with full control. Then try to run again and see if you get the same message.
Also when you run Visual studio, at the start, right click and run as administrator. I take it from your comment that this works OK, leading me to believe it is in fact permission related. e.g. Are the different users in the same domain? Once you work out the permissions of the folder where the applcation lives, create an account with permission on that folder and then have whatever process schedules/runs the exe to execute under that account.
Update - the comments above prompted another idea, you could use system.diagnostics to write eventlog entries at each point of the code, to help determine what is going wrong. Another tool that may be of use if WinDBG to get more info about what is throwing that exception.

Allow System Account to start impersonated process

I am working on a project where I have a Windows service running under Local System Account.
What I want to do is to start another process (C++ application) that should write files to disk.
If I just use Process.Start, then the target application also runs under Local System Account, and as far as I know I can not simply write files anywhere.
For this reason I'm trying to make the target application run as a different user.
ProcessStartInfo psi = new ProcessStartInfo(#"C:\Path\to\Application.exe", parameters);
psi.UseShellExecute = false;
psi.UserName = "Username";
System.Security.SecureString sec = new System.Security.SecureString();
foreach (Char c Password)
sec.AppendChar(c);
psi.Password = sec;
psi.Domain = ".";
psi.LoadUserProfile = true;
Process.Start(psi);
But I am getting a Win32 Exception telling me the "Acces is denied".
Does anybody know how I can achieve my goal?
Check the file system permissions. Does the user you are using have execute permissions for the specified application?

Running command from ASP.NET App Pool Identity

I am running an executable process from my ASP.NET application when a user clicks a button. This process creates several files and serves them up to the end-user. I can't really see what the process is or isn't doing, but it didn't work until I specified the admin user as the application pool identity on the server. I am using IIS7.
using (var proc = new Process())
{
proc.StartInfo.FileName = Server.MapPath("~/Testing/Demo/MyExe.exe");
proc.StartInfo.Arguments = String.Format("\"{0}\"", commandFilePath);
proc.StartInfo.UseShellExecute = true;
proc.Start();
proc.WaitForExit();
}
I'm assuming that this is generally a bad thing to do. Can you give me insight into what needs to be done in order to enable this for the normal ApplicationPoolIdentity account?
Thanks!
First of all, why you need the Shell to execute it ? Isn't a console application - do you open any window ?
Second you need to redirect the input and the output.
And final, what you need to do, is to place on the directory that your script runs, permission for the user under witch your pool is run. And remove the Admin from your pool.
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardInput = true;
proc.Start();
proc.StandardInput.Flush();
proc.StandardInput.Close();
proc.WaitForExit();
proc.Close();
So for example, if you add your pool to run under the UserA, then go to your directory that your program runs and add permission for the UserA to been able to execute programs on that directory. If your program also use other directories to read and write, also add permission to the UserA for that ones.
I can't really see what the process is or isn't doing
You can take a look if you use on the server the Process Explorer and see if its runs, if its close, if its stop but stay there.
It is likely a file/execution permissions issue.
Try granting execute permissions to the ApplicationPoolIdentity to ~/Testing/Dema/MyExe.exe and read permissions to commandFilePath. You mentioned that your process creates files. You will need to grant either modify or full control permissions to the ApplicationPoolIdentity on the folder where the files will be created. Here is a matrixed list of permissions.
See assign permissions to ApplicationPoolIdentity account for information on granting permissions.
The security event log should capture permission denied errors. Check there to see if you have access permission issues. The System and application logs might also contain information on the problem.
Process Explorer can also show File Access requests. Here is a technet article on troubleshooting with Process Explorer.
Whenever you run any process from an ASP.NET page, it runs under the security context of the worker process, the privilege of your app pool account. It is not like you normally running the MyExe.exe, in that case it will run using logged in account. It is because of this, your code worked when you gave Admin account to app pool.
There are many ways to solve this issue.
One of the easiest would be to change your app pool identity to Network Service and add the Network Service to permissions of the folders in which the MyExe.exe will be accessing files form.
Hope it helps.
Thank you all for your help. All I needed to do was set the StartInfo.WorkingDirectory to somewhere that I was able to write.
using (var proc = new Process())
{
proc.StartInfo.FileName = Server.MapPath("~/Testing/Demo/MyEXE.exe");
proc.StartInfo.Arguments = String.Format("\"{0}\"", commandFile);
proc.StartInfo.WorkingDirectory = savePath;
proc.Start();
proc.WaitForExit();
}
This causes the temp files to be written to a non-system folder and thus does not need any elevated permissions for the application pool.

Categories

Resources