Process.Start doesn't work in IIS - c#

I'm trying to print a PDF manually through Process.Start, but it isn't working in IIS. I copied the same code in a windows form application and that worked. I already tried giving the rights to 'Network Service' user (my application pool has Network Service permission). I've also followed the steps here:
IIS7 does not start my Exe file by Process Start
string file = #"C:\test.pdf";
string printer = "TestPrinter";
string processFilename = Microsoft.Win32.Registry.LocalMachine
.OpenSubKey("Software")
.OpenSubKey("Microsoft")
.OpenSubKey("Windows")
.OpenSubKey("CurrentVersion")
.OpenSubKey("App Paths")
.OpenSubKey("AcroRd32.exe")
.GetValue(String.Empty).ToString();
var info = new ProcessStartInfo();
info.FileName = processFilename;
info.Arguments = string.Format("/h /t \"{0}\" \"{1}\"", file, printer);
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
info.UseShellExecute = false;
Process p = Process.Start(info);
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
int counter = 0;
while (!p.HasExited)
{
System.Threading.Thread.Sleep(1000);
counter += 1;
if (counter == 5) break;
}
if (!p.HasExited)
{
p.CloseMainWindow();
p.Kill();
}

Well, it took me three days and multiple ways and tools to test printing only to confirm that it's not a programming problem. It is a permission problem. When I was searching for tips, this particular problem seemed to be ongoing for more than a decade and it always happens to certain web server setups. So, here is the solution for anyone who stumbled upon the same situation as I had and save the three days of headache.
The setup:
Have a web application or service running on IIS server and you need to print some documents.
Have a network printer set up for this purpose, such as printing to a particular departmental printer within the office network.
The printing works when you are testing on localhost with your development machine.
The printing silently drops and nothing happens when deployed to the actual web server.
The reason is that a network printer is accessed in the form of \networkserver\printername and the web application account, IIS_IUSER, is not a domain account and, therefore, doesn’t have access to any network server.
Solutions:
Add the IIS_IUSER account to the domain BUT this is a very bad idea because you would need to give Internet users of your web app to have access to some network drive. Therefore, this is a no-no.
Add the printer using TCP/IP instead of setting it up as a network drive. By IP address, all local users, including the IIS_IUSER account will have access to the printer by default.
With an IP printer, no matter you use ProcessStartInfo or a third-party tool to print, it will work. Happy programming!

Related

C# WPF, How to hide hard coded password?

I have an internal only Helpdesk program that has admin access to servers on the private network to pull logs, reboot hung servers, and perform other various admin tasks..
Rather than giving admin access to a significant number level 1 helpdesk users across hundreds of servers, my program runs under a single admin account, which access to this program is protected under a AD group, and launched only on a single Windows server via Citrix published app. So access to run the app is protected, but the password for the account with server access is hardcoded in the code using securestring.
I am not an expert level programmer. Just an advanced sysadmin with enough knowledge to do more things to accomplish my needs.
I know securestring is not recommended anymore, but i dont have the advanced knowledge to implement another password encryption solution without some help.
This is the code being used in my C# WPF app..
secureString pass = new NetworkCredential("", "hardcodedpassword").SecurePassword;
strCmdText = "command to be run here"
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = strCmdText;
process.StartInfo.UserName = "Helpdesk1";
process.StartInfo.Password = pass;
process.StartInfo.Domain = "Domain1";
process.StartInfo.ErrorDialog = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = false;
process.StartInfo.RedirectStandardOutput = false;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForExit();
pass.Dispose();
I also have some users who are not very technical, but need to perform some limited tasks, like logging off stuck users from servers where you need admin access. That is why i do not want to assign Admin to these individual AD accounts. Having them access a single tool with the required access running on a single windows server solves that problem compared to giving all these users direct server admin access. So bottom line is I just want to be able to at least hide password in the code at least at the minimum, fully understanding its not the best approach. Thank you for the help!

C# System.Diagnostics.Process doesn't work properly

I am using System.Diagnostics.Process in a Windows service application. The application that I call uses DropBox API and Google Drive API. When I login on Google Drive or DropBox it is supposed to open the Web browser and allow access to Drop or Drive, but it doesn't open it. Other functions works properly (create folder on local computer, read files, write logfiles etc).
When I open this application manually with double click, the login process works properly, the web browser is shown and I can allow access.
Something similar happens with other application using Saraff Twain. If I open it manually it works properly, I can scan and save files (on this process some alerts or message box are shown, like a "scanning", "no paper", "no scanner" messages) but when the windows service call it no messages are shown, it scans and save files but without messages.
If I call this application from another windows form or console application the applications works properly.
I don't know what is the problem with the Windows service.
Thanks for your help.
Here is the code that I used in the Windows service app (here it fails), and Windows forms app (here it works fine). I have tried calling CMD.exe and application path as argument, and directly the path on file name.
p.StartInfo.UseShellExecute = false;
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C" + " \"" + execName+"\" " + argument;
//p.StartInfo.Verb = "runas";
// writeLogLine(argument + " " + execName);
p.Start();
output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
writeLogLine("out" + output);
A Windows Service is not meant for user interaction as it should be capable of running without any users logged in.
Windows Services are isolated from the users' desktops as a security measure this is why any interaction with a desktop is bound to fail.
Either replace the Windows Service with a regular desktop application or change the Windows Service in such a way that it doesn't need desktop access.

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.

Running bat file on IIS server

I'm trying to run a .bat file on a windows server 2008 R2 64bit with IIS version 6.1 SP1.
On my local machine everything goes well but on server nothing happens, except for a process that gets created (cms.exe *32).
From my search the main problem is permissions. I read in several places that IIS for default blocks access to batch files for security reasons. I do understand the problem but in my case there would be no security issue so i would like to still run my file.
The solutions i found passed by implementing impersonation which means:
Change web.config
-> identity impersonate="true"
Change IIS Site Authentication
-> ASP.NET Impersonation Enabled
Give permissions to the file and folders
Even tried a different version of step 1
-> identity impersonate="true" userName=**********
Give permissions to the IIS User:
set allow service to interact with desktop on the IIS Admin Service
To call the batch i use the following code in C#:
private void StartPervasive(string npu)
{
try
{
ProcessStartInfo startInfo = new ProcessStartInfo(ConfigurationManager.AppSettings.Get("PervasivePath"));
//startInfo.UseShellExecute = true;
//startInfo.WorkingDirectory = ConfigurationManager.AppSettings.Get("PervasiveWorkingPath");
//startInfo.WindowStyle = ProcessWindowStyle.Normal;
//startInfo.RedirectStandardInput = true;
//startInfo.RedirectStandardError = true;
//startInfo.RedirectStandardOutput = true;
//startInfo.FileName = ConfigurationManager.AppSettings.Get("PervasivePath");
startInfo.Arguments = npu;
Process myProcess = Process.Start(startInfo);
//StreamReader sr = File.OpenText(ConfigurationManager.AppSettings.Get("PervasivePath"));
//StreamWriter sw = myProcess.StandardInput;
//while (sr.Peek() != -1)
//{
// string readed = sr.ReadLine();
// readed = readed.Replace("%1", npu);
// sw.WriteLine(readed + Environment.NewLine);
//}
//myProcess.WaitForExit();
//myProcess.Close();
}
catch (Exception ex)
{
throw ex;
}
}
It should also be of note that i tried to execute other files including .exe files but with no results.
Would appreciate any advice, help and or corrections to the steps described.
This may not be what your looking for, but may help. I would suggest you create a Scheduled Task on the Server to run the BAT file, you can set the User Permissions and then schedule when you wish to run it.
Hope this helps.
Below is a link to another Stackoverflow article that appears to have a very detailed response to the same problem.
IIS7 does not start my Exe file...

How to start the bat-file at Asp.net web server side?

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.

Categories

Resources