I have A requirement to run SAS script through Web application using asp.net and c#.
I have used ProcessStartInfo to execute SAS script. This works fine locally with solution.Once i hosted the application in IIS, it is not working and returning exit code with 111. Please help me to solve this issue.
ProcessStartInfo info = new ProcessStartInfo("path of SAS EXE","file path");
int exitCode = 0;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
Process p = Process.Start(info);
p.WaitForExit();
exitCode = p.ExitCode;
Have you considered not doing it using process? SAS has a technology called Integration Technologies which you most likely have. It interfaces using a COM interface. You can then execute SAS that way and pass what is needed vs using a command line call.
Here is sample code:
SAS.Workspace ws = new Workspace();
LanguageService ls = ws.LanguageService;
StoredProcessService sp = ls.StoredProcessService;
sp.Repository = #"file:" + #"x:\temp";
sp.Execute("test.sas", string.Empty);
string log = ls.FlushLog(1000);
If you need to do it via the process start, here is code:
Also, if you are passing commands to SAS, I don't see any. You have to pass commands to SAS from command line (program name at a minimum). info.Arguments is a start. Also, redirect the std output to a file. Look at info.RedirectStandardOutput and info.RedirectStandardError. However, i don't believe that is the issue. I think you are encountering a security issue. Look at Event Viewer and see if it pops up. IISS requires security to execute in a directory.
Finally, why are you using IIS? Unless you have a legacy requirement, IIS should not be used. Switch to Kestrel and ASP.NET Core. I will be presenting a paper at SGF on the use of SAS in this way. Download the paper and code as soon as they are available (next week?)
Related
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.
I am attempting to verify the security of an application. The scenario is this:
A C# WinForms application is run by a limited user via Terminal Services (no desktop, just the app). One of the things this C# app can do is execute a batch file that runs a lengthy process with elevated privileges. I am afraid that the limited user may be able to interrupt the batch script (vua Ctrl+C or some other method) and gain access to the underlying elevated shell.
I have tried to do this myself with various combos of Ctrl+C and Ctrl+Break, etc. All I can get is the "Teminate batch job? (Y/N)" prompt, and if you choose terminate, then control is immediately returned to the C# app (which is good). I have not found a way to break this but it seems dangerous to me.
Does anyone know of a way to break out of a C# instantiated batch script and access the underlying shell without returning to the C# app?
No, don't think there is one. But if you're really worried, why not set the CreateNoWindow property on the ProcessStartInfo object you are presumably using to true to prevent user interaction at all?
Not quite an answer to your described scenario but a different way to look at it.
If possible, I would have a "jobs server" who sole responsibility is to run the jobs your Terminal Services-run apps create. Then you would communicate the job (or just it parameters) via WCF to the server. The users would have no access to the server and very little control of the jobs (possibly just a cancel option and success/failure status reports).
You could do something like this (with a Textbox on your app)
ProcessStartInfo info = new ProcessStartInfo();
info.Arguments = "/C ping 127.0.0.1";
info.WindowStyle = ProcessWindowStyle.Hidden;
info.CreateNoWindow = true;
info.FileName = "cmd.exe";
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
using (Process process = Process.Start(info))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
textBox1.Text += result;
}
}
Then you can see the results of the batch without the users being able to actually see the window at all, that way it's only visible as a process so they can't interupt it.
i need to launch simple console application from my asp.net webpage, that creates a file using given parameters. hereis my code:
string filePath = Server.MapPath(#"~/Patcher/TestPatcher.exe");
System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo(filePath , "-sn:123456789123456 -upd -fn:test.hd");
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(info);
p.WaitForExit(25000);
// Display the output
string str = p.StandardOutput.ReadToEnd();
problem is that program doesnt create any file, but it does launch - i got some output in "str". any suggestions? and btw, that website must work on shared hosting.
Yeah. I think you have a security issue there... you can't just run an exe from a sandboxed environment (which the browser is).
Besides the code snippet you provided, is trying to run code on the webserver, not on from the asp.net page.
I need to call a console application to load data into another desktop application on the remote server that located within the corporate domain.
Users will enter the web page and upload data to asp.net web server, which after transformation should call that console application. Users are located remotely and do not have any other access except the web server.
I decided to lower the security web application context and let the asp.net working process to start the console application on the current IIS 6.0 web server
What I have done:
I changed the security account for the application pool for Local System;
I added ASPNET Account and IIS_WPG IIS Process Account to Administrators group;
I added “Allow service to interact with desctop” for “IIS Admin Service” and “World Wide Web Publishing Service” processes and restarted the machine;
I tried to start BAT-file at server side through the test page code-behind, but failed:
protected void btnStart_Click(object sender, EventArgs e)
{
Process process = new Process();
process.StartInfo.FileName = #”C:\run.bat”;
process.StartInfo.UseShellExecute = false;
process.Start();
process.WaitForExit();
}
The error was access denied.
Please help me to find any workable idea how to start the bat-file at web server side.
Thanks
Try setting UseShellExecute to true instead of false. After all, batch files run in a shell - so you need a shell to execute it. (Another option is to run cmd.exe and pass the name of the batch file in as an argument, e.g. "cmd.exe /k c:\run.bat")
You might also want to try creating a simple .NET app which just (say) creates a file with a timestamp in. That way you can test the "can I start another process" bit separately from the "can I get the batch file to work" bit.
Put that particular batch file in your application itself.
string str_Path = Server.MapPath(".") + "\\run.bat";
ProcessStartInfo processInfo = new ProcessStartInfo(str_Path);
processInfo.UseShellExecute = false;
Process batchProcess = new Process();
batchProcess.StartInfo = processInfo;
batchProcess.Start();
Take a look at this example: Run Interactive Command Shell or Batch Files From ASP.NET
It uses little different approach. They suggest running cmd.exe and executing command line by line.
In a .NET windows application to to modify a remote machine config file that is used by an ASP.NET application. However, I keep getting the error:
System.IO.IOException: The process cannot access the file '[file name]' because it is being used by another process.
Now, this may not be the problem, but I'm figuring that if I can stop the IIS, then I can modify the machine config file (without getting the exception), and then I can restart the IIS using this code:
Process proc = new Process();
proc.EnableRaisingEvents = false;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.FileName = "iisreset";
proc.StartInfo.Arguments = serverName;
try
{
proc.Start();
proc.WaitForExit();
...
1) Is there a way to stop the IIS without restarting it, and 2) Doe this approach to changing the server.config file even make sense?
(note, I am modifying the file with regular expressions search and replace; is this a problem?)
You should be able to do something like this. I don't have windows, so I can't check the exact name of the service, but I think it is "IISADMIN" or "w3svc". Remember this should be the service name and not the display name you see in the service control panel.
ServiceController controller = new ServiceController();
controller.MachineName = "."; // or the remote machine name
controller.ServiceName = "IISADMIN"; // or "w3svc"
string status = controller.Status.ToString();
// Stop the service
controller.Stop();
// Start the service
controller.Start();
You can also use
net stop w3svc
or
net stop IISADMIN
from the commandline or in your process in your code
Strange. A .config file should not be locked exclusively.
But to answer your question, you can also use the net command for this:
net stop w3svc
to stop the www service, and
net start w3svc
to start it again.
You can also do this programmatically as described by #monkeyp
Note that I would advice against this and first try to determine (and resolve) the cause of the lock as described by #RichardOD.
Using System.Diagnostics;
//to stop ISS
ProcessStartInfo startInfo = new ProcessStartInfo("iisreset.exe", " /stop");
System.Diagnostics.Process.Start(startInfo);
//to start ISS
ProcessStartInfo stopInfo = new ProcessStartInfo("iisreset.exe", " /start");
System.Diagnostics.Process.Start(stopInfo);
You can use the IISRESET /STOP command.
If you type IISRESET /? you will get a list of other available options.
[Edit: Pass the "/STOP" switch as the arguments property on the process' startinfo object.]
Should be "iisreset /STOP" to stop the services, then "iisreset /START" to restart them.
Use a tool like wholockme or unlocker to find the root cause of the locking.
Update- another option is to use Process Explorer (thanks fretje)- this is a good option as lots of developers have this utility on their PC.
You can often just recycle or stop/start the Application Pool IIS is running, rather than restarting IIS altogether.