SteveCalPoly
SteveCalPoly

Reputation: 151

Attempting to call command prompt execuable in a C# / ASP.NET / IIS 7.5 / Win7 Environment

On the server, I'm attempting to open the command prompt and call an executable which converts a file to PDF. For this I am using the PDFCreator open source program.

In C# I am calling with this code:

    ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd.exe");
    processStartInfo.RedirectStandardInput = true;
    processStartInfo.RedirectStandardOutput = true;
    processStartInfo.UseShellExecute = false;
    Process process = Process.Start(processStartInfo);

    process.StandardInput.WriteLine(@"cd c:\program files (x86)\pdfcreator");
    process.StandardInput.WriteLine(@"PDFCreator.exe /PF""c:\dwf\dwf.dwf""");

It runs with no error, yet yields no result. What this PDFCreator.exe does is call another program, Autodesk Design Review which opens, uses the PDF driver to print to PDF, and saves the file. The command you see works fine being running standalone by me.

From scouring other threads it seems security could be my issue. So I have gone to the PDFCreator and Design Review folders/executables and granted full access to NETWORK, NETWORK SERVICE, IIS_WPG, IIS_IUSRS, and ASP.NET Machine account (realize this is probably a security thread but will disable once i figure out source of the issue). This has not helped.

It should be noted than i can change directory using the first command above, and then create a "test123" folder in both PDFCreator and Design Review folders. Seems I am getting close here, any ideas?

Upvotes: 4

Views: 5818

Answers (4)

SteveCalPoly
SteveCalPoly

Reputation: 151

Found out the issue over at serverfault. The app I was calling needs to open another app on the desktop and then print to PDF. IIS cannot open programs on the desktop unless set in the services --> service name --> log on tab.

Unfortunately, the app I am calling isn't in the services panel so I'm currently stuck again, but at least I know it's not a C# problem.

Upvotes: 0

codeulike
codeulike

Reputation: 23064

Perhaps the errors are going to the StandardError stream and so you never see them?

Also, why not call PDFCreator.exe directly instead of via cmd.exe?

Try something like this

ProcessStartInfo processStartInfo = new ProcessStartInfo(@"c:\program files (x86)\pdfcreator");
processStartInfo.Arguments = @"/PF""c:\dwf\dwf.dwf"""
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardError = true;
processStartInfo.UseShellExecute = false;
Process process = Process.Start(processStartInfo);

// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
string errors = p.StandardError.ReadToEnd();

Upvotes: 0

Emanuele Greco
Emanuele Greco

Reputation: 12721

SteveCalPoly and Val Akkapeddi comments are very interesting.
Anyway, I use the following methods to run executable with command prompt

    /// <summary>
    /// Executes a shell command synchronously.
    /// </summary>
    /// <param name="command">string command</param>
    /// <returns>string, as output of the command.</returns>
    public void ExecuteCommandSync(object command)
    {
        try
        {
            // create the ProcessStartInfo using "cmd" as the program to be run,
            // and "/c " as the parameters.
            // Incidentally, /c tells cmd that we want it to execute the command that follows,
            // and then exit.
            System.Diagnostics.ProcessStartInfo procStartInfo =
                new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);

            // The following commands are needed to redirect the standard output.
            // This means that it will be redirected to the Process.StandardOutput StreamReader.
            procStartInfo.RedirectStandardOutput = true;
            procStartInfo.UseShellExecute = false;
            // Do not create the black window.
            procStartInfo.CreateNoWindow = true;
            // Now we create a process, assign its ProcessStartInfo and start it
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            proc.StartInfo = procStartInfo;
            proc.Start();
            // Get the output into a string
            string result = proc.StandardOutput.ReadToEnd();
            // Display the command output.
            Console.WriteLine(result);
        }
        catch (Exception objException)
        {
            // Log the exception
        }
    }
    /// <summary>
    /// Execute the command Asynchronously.
    /// </summary>
    /// <param name="command">string command.</param>
    public void ExecuteCommandAsync(string command)
    {
        try
        {
            //Asynchronously start the Thread to process the Execute command request.
            Thread objThread = new Thread(new ParameterizedThreadStart(ExecuteCommandSync));
            //Make the thread as background thread.
            objThread.IsBackground = true;
            //Set the Priority of the thread.
            objThread.Priority = ThreadPriority.AboveNormal;
            //Start the thread.
            objThread.Start(command);
        }
        catch (ThreadStartException objException)
        {
            // Log the exception
        }
        catch (ThreadAbortException objException)
        {
            // Log the exception
        }
        catch (Exception objException)
        {
            // Log the exception
        }
    }

Upvotes: 2

Adil B
Adil B

Reputation: 16806

The System.Diagnostics.Process class has a method called WaitForExit() which will wait for its launched process to exit before continuing and then will return its return code.

Try creating a batch file with your commands and then running the batch file via the Process class. What happens if you use Process.WaitForExit(); after you call Process.Start(processInfo); ? Is there a return code from process.WaitForExit() at all?

Upvotes: 0

Related Questions