Process Start in IIS - c#

Want to execute a exe within Application directory, in Dev system it works fine. In IIS, it is not executed, I have tried below points:
set default application pool to local system
set defualtpool, NETWORK_SERVICE, Everyone access to exe
Enabled 32 bit application to application pool
Server Version : Windows Server 2012
IIS Version: IIS 8.0
Below is my code
p.StartInfo = new ProcessStartInfo();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = System.AppDomain.CurrentDomain.BaseDirectory.ToString() + "wkhtmltopdf\\wkhtmltopdf.exe";
string arg1 = "";
arg1 = "www.google.com" + " test.pdf";
p.StartInfo.Arguments = arg1;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.WaitForExit(60000);
p.Close();
p.Dispose();

Make sure that the location at which your pdf file is getting generated "everyone has access to it"
it seems you are trying to convert html data to pdf file on your iis server. Make sure IIS server can access the site which your are trying to convert "Check if you can access those site using IE on your IIS server as there could be proxy issues"

Consider to set the working path of your exe:
p.StartInfo.WorkingDirectory = System.AppDomain.CurrentDomain.BaseDirectory.ToString() + "wkhtmltopdf";
Also check task manager if the exe is in memory.
Sometimes when a batch got a low level error open a prompt, and IIS do not capture it, so the process is freezed in memory.
Consider also the set a log in the exe in order to understand what goes wrong.
I had similar problem. Solved moving the exe in another folder outside IIS application. This folder should have execution rights.

Related

Server-side application fails to run command

I have an ASP.NET application that is already deployed in an Azure virtual machine. The situation is as follows:
This application, OCREngine, is deployed on the server along with other 3rd party applications. OCREngine is executed on the server by using a service reference to the web service. It runs fine most of the time. But there is one exception: one of the branches of execution won't run the program it needs to run. Both of the branches have to run a program (both are being run in the same way), but one works and the other one doesn't.
This one works: CleanJPEG.exe
proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "CleanJPEG.exe";
proc.StartInfo.Arguments = "\"" + tempPages + "Color Info.JPEG\"";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
And this one doesn't: cpctool.exe
proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "cpctool.exe";
proc.StartInfo.Arguments = "\"" + file + "\" -o \"" + tempPages + "page.tiff\"";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
They are both in the same folder, which has full permissions for the AppPool and so does %TEMP%.
If I run the application from the server, everything works fine. But when I run it through the web service, an instance of cpctool.exe gets created (can be seen on Background processes in the task manager) but it doesn't do it's job. And thus the execution of OCREngine never finishes.
This last part is what made me think it was a problem with permissions, but I don't know what else to give permissions to.
I run Folder Changes View on cpctool.exe and it showed access to the folder where the files are stored and one file being saved in %TEMP% (which, funny enough, doesn't appear when running Folder Changes View on the server).
Can anyone think of any special folder that needs permission that I might be forgetting?
You are completely correct to concentrrate on the permissions as that is usually the issue.
If an EXE process starts and does nothing, then it's probably only made for interactive use, and is prompting for something.
Looking at this page it says:
The FIRST TIME the CPCTool.exe runs the user is prompted to read/accept a User Agreement from Cartesian – this agreement MUST be accepted or the converter will not work.
I reckon that's what it's doing. Try logging in as the application pool user, start the program and accept the agreement.

Process on ASP.Net server not running correctly over IIS

I am trying to run an antivirus scan on an uploaded file in an ASP.Net web app. We are using Sophos so have access to their command line API sav32cli. In the code I use:
Process proc = new Process();
proc.StartInfo.FileName = #"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe";
proc.StartInfo.Arguments = #"-remove -nc " + SavedFile;
proc.StartInfo.Verb = "runas";
proc.Start();
proc.WaitForExit();
int exitCode = proc.ExitCode;
When stepping through the code, when attached to the w3wp process on dev server, the code just jumps from one line to the next seemingly doing nothing at all. When running from code on dev server, it performs as expected scanning file and deleting if it is seen as a virus.
The server is running IIS 8.0, and the app built in .Net Framework 4. I have changed the machine config to allow the process to run as SYSTEM account, in accordance to these instructions. https://support.microsoft.com/en-us/kb/317012#%2Fen-us%2Fkb%2F317012
<processModel userName="SYSTEM" password="AutoGenerate" />
Is there something I'm missing? What is the best practice for this kind of implementation?
EDIT: When called, the Process returns an ExitCode of 2 (Error stopped execution), rather than the expected 0 (Scan worked, no viruses), or 3 (Scan worked, viruses found).
EDIT 2: As per comment below I changed the code to:
Process proc = new Process();
proc.StartInfo.FileName = #"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe";
proc.StartInfo.Arguments = #"-remove -nc " + SavedFile;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
StringBuilder output = new StringBuilder();
while (!proc.StandardOutput.EndOfStream)
{
string line = proc.StandardOutput.ReadLine();
output.AppendLine(line);
}
proc.WaitForExit();
int exitCode = proc.ExitCode;
ASPxMemo2.Text = exitCode.ToString() + Environment.NewLine + output.ToString();
output is always empty when run over IIS, but is populated correctly when running from code.
EDIT 3: Instead of looking at StandardOutput we looked at StandardError and it revealed this error:
Error initialising detection engine [0xa0040200]
(Possible insufficient user Admin rights.)
For the time being we are going to move to another method of virus checking, but would still like to know a possible solution if anyone has it.
You will need to make sure that the application pool that is running your .NET application inside IIS has execute permissions to your file
"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe"
You may also need to add this permission to the folder location where the file to be scanned is uploaded (c:\temp) for example
You may also need to have administrator privileges to run the anti virus scan since IIS8 does not run as an administrator. When you are debugging visual studio uses your current logged in windows user(unless you use runas) so this will explain why it would work when debugging.
Have you tried running your web process in elevated trust?
Configuring .NET Trust Levels in IIS 7
<system.web>
<securityPolicy>
<trustLevel name="Full" policyFile="internal"/>
</securityPolicy>
</system.web>
ASP.NET Trust Levels and Policy Files
Most likely the permissions are not configured correctly on the content being scanned (the uploads folder) or the worker process user doesn't have the full permissions it needs to use Sophos. You know the executable itself is accessible by the worker process because you are getting exit codes and error messages that are specific to Sophos.
Because your process will delete files that are perceived as threats you need to grant the user running the process modify or full control permissions on the folders that store the uploaded files.
By default you could use the IIS_IUSRS group for ApplicationPoolIdentity processes, but you can verify (and modify) the user in IIS Manager > App Pools > Advanced.
This answer has more details
Here are some ideas:
Create the process using a different user with elevated privileges on the folder, see for reference start-a-net-process-as-a-different-user
If the previous suggestion fails, login one time on the server using the credentials used in point 1. It will configure registry entries connected to the user profile, some programs requires it.
Develop a simple .net service running on the server and monitoring the upload folder. The service has more probability running the Sophos scan succesfully. Here is a reference on service creation using .net.
The service may also talk to your web page using DB/file system/ etc.. so the operation may seem synchronous.
These are my 4 cents :-)

Starting a process

As part of SharePoint automation testing, I am trying to open Internet Explorer as another user by using the System.Diagnostics.Process . Here is the following C# code
System.Diagnostics.Process p = new System.Diagnostics.Process();
// Domain and User Name:
p.StartInfo.Domain = "MYDOMAIN";
p.StartInfo.UserName = "myusername";
// Command to execute and arguments:
p.StartInfo.FileName = "C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe";
p.StartInfo.Arguments = "http://url/AllItems.aspx";
// Build the SecureString password...
System.String rawPassword = "thepassword";
System.Security.SecureString encPassword = new System.Security.SecureString();
foreach (System.Char c in rawPassword)
{
encPassword.AppendChar(c);
}
p.StartInfo.Password = encPassword;
// The UseShellExecute flag must be turned off in order to supply a password:
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = false;
p.Start();
When I run this automated test Visual Studio returns informing me that the test was successful, however Internet Explorer does not open.
Is there something in my code I am missing in order for a window to appear? There is no iexplore process running prior to the test being run.
putting double quotes around the file path (since it contains spaces) may help:
p.StartInfo.FileName = "\"C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe\""
^^ ^^
In addition, if your intention is to start this from a service process or dll running in a service such as "SharePoint", then this code will probably not launch the process in the desktop desired. You'll need to set the desktop to "winsta0\\default" in the startup info.
To run a process the worker process should have high privileges and this is not an ideal case in any web application. If your purpose is to use IE for unit testing then I would consider using something like WaitIN. If your purpose is for application logic to access a URL and do something then consider using HttpWebRequest. If you still need a process to be started then create a Windows Service and then expose a web call so in Share Point you can just make a call and your Windows Service can run on local account or some other high privilege account.
Hope this helps and please provide the scenario why you want to start the IE and that can give you a better answer in the forum.

Where does my console program's text file go when it is run from a WCF service?

I need to run a console application for which I do not have any source code (I only have the binaries) from my WCF REST web service. Once my service is up and running (localhost, debug), I enter the following code :
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = strCommand;
p.StartInfo.Arguments = strCommandParameters;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
My .exe file is found but nothing happens. I put a breakpoint after this code and it stops there so the code is executed. Whatever happens regarding the command parameters, the console application is supposed to produce at least a log.txt file in its directory, but it does not. Any ideas?
EDIT: It was working...the only difference is the log.txt file was generated in the debug directory of the running web application instead of the directory of the console application. So the relative path of the output file is relative to the server web application.
I´d guess you are hosting the WCF Service in IIS and the console application is started using the AppPool Credentials not having enough privileges. You may try to use the ProcessMonitor to monitor the Service/ConsoleApp and check for access denied messages

Run exe from webpage

We have an internal page that I want to use to run an executable that updates some files on the server. In other words, rather than logging in to the server every time I need to manually run this executable, I would like to run it from the browser. The executable is self-contained on the server and does not interact with the user.
Here is my code:
try
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = Server.MapPath(#"\iPhoneXMLCreator.exe");
p.StartInfo.WorkingDirectory = Server.MapPath(#"\");
p.StartInfo.RedirectStandardOutput = false;
p.Start();
p.WaitForExit();
lblResult.Text = "Success!";
}
catch (Exception ex)
{
lblResult.Text = "Oops, there was a problem.<br><Br>" + ex.Message;
}
When I run it, the process shows up in Task Manager, but then exits within a few seconds without updating the files it is supposed to. There are no arguments to be passed, just a simple executable. Any ideas?
I would start by checking to see if the account which runs the web application has the appropriate permissions.
Most likely this is a permissions issue. Since it's the Asp.Net runtime that is executing this program, you need to ensure that the user account that the Asp.Net runtime uses has access to this executable, and to modify any resources (files, databases, etc) that get modified by the executable.
You can do this via impersonation, or by granting rights tot he appropriate accounts. The proper approach is to use impersonation.
http://msdn.microsoft.com/en-us/library/xh507fc5.aspx
Does the executable file run and process the XML when you run it manually on the server logged in as yourself?
Then it may be a simple permissions issue, since unless you are impersonating ...it's probably trying to run the exe under the ASPNET machine account, which most likely doesn't have rights to the folder the XML is in. Just a thought based on the info you provided.
2 things that you could do:
Run Process Monitor while you attempt to run the exe. I've used it many times to help to find security config problems (especially on web servers). It will log every io and registry access, and more importantly indicate success or failure. Get it here: http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx It requires no setup. Great tool!
Redirect stdout on your console exe. This will allow you to capture any error message that it is attempting to write to the console. Here's how to do it:
try
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = Server.MapPath(#"\iPhoneXMLCreator.exe");
p.StartInfo.WorkingDirectory = Server.MapPath(#"\");
// redirect stdout
p.StartInfo.RedirectStandardOutput = true;
var ConsoleOutput = new StringBuilder();
p.OutputDataReceived += (s, e) => ConsoleOutput.AppendLine(e.Data);
p.Start();
p.BeginOutputReadLine(); // if I remember correctly, you have to call Start() first or you get an exception
p.WaitForExit();
string output = ConsoleOutput.ToString();
lblResult.Text = "Success!";
}
catch (Exception ex)
{
lblResult.Text = "Oops, there was a problem." + ex.Message;
}
Rather than playing with website permissions for the Exe, one workaround that uses a level of indirection and puts a buffer between your web site and the Exe is to simply set a flag value into a text file on the web server when the Page representing the Exe is hit.
Set up a scheduled job on the server to check for that flag value every X hours, or minutes, or whenever and if the flag is seen, run the executable. Reset the flag/file when done. This opens up the possibility to check the flag via a webservice or other mechanisms, such that the target Exe doesn't even need to be on the same web server machine.
This is only viable if the exe does not need to run immediately when the page is hit.
Ok, figured it out. It was a data access issue. The .config file for the .exe had an invalid database connection string. Why it would work when logged in, I'm not sure, but it works now.

Categories