简体   繁体   English

尝试在C#/ ASP.NET / IIS 7.5 / Win7环境中调用可执行的命令提示符

[英]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. 在服务器上,我试图打开命令提示符并调用将文件转换为PDF的可执行文件。 For this I am using the PDFCreator open source program. 为此,我正在使用PDFCreator开源程序。

In C# I am calling with this code: 在C#中,我使用以下代码进行调用:

    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. 此PDFCreator.exe的作用是调用另一个程序,即Autodesk Design Review,它将打开,使用PDF驱动程序将其打印为PDF,然后保存文件。 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). 因此,我进入了PDFCreator和Design Review文件夹/可执行文件,并授予了对NETWORK,NETWORK SERVICE,IIS_WPG,IIS_IUSRS和ASP.NET Machine帐户的完全访问权限(意识到这可能是一个安全线程,但是一旦我找出了问题)。 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. 应该注意的是,我可以使用上面的第一个命令更改目录,然后在PDFCreator和Design Review文件夹中都创建一个“ test123”文件夹。 Seems I am getting close here, any ideas? 看来我正在靠近,有什么想法吗?

SteveCalPoly and Val Akkapeddi comments are very interesting. SteveCalPoly和Val Akkapeddi的评论非常有趣。
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
        }
    }

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. System.Diagnostics.Process类具有一个名为WaitForExit()的方法,该方法将等待其启动的进程退出后再继续,然后将返回其返回代码。

Try creating a batch file with your commands and then running the batch file via the Process class. 尝试使用命令创建一个批处理文件,然后通过Process类运行该批处理文件。 What happens if you use Process.WaitForExit(); 如果使用Process.WaitForExit()会发生什么? after you call Process.Start(processInfo); 调用Process.Start(processInfo)之后; ? Is there a return code from process.WaitForExit() at all? 根本没有来自process.WaitForExit()的返回码吗?

Perhaps the errors are going to the StandardError stream and so you never see them? 也许错误将进入StandardError流,所以您再也看不到它们了?

Also, why not call PDFCreator.exe directly instead of via cmd.exe? 另外,为什么不直接通过cmd.exe而不是直接调用PDFCreator.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();

Found out the issue over at serverfault. 在serverfault发现问题所在。 The app I was calling needs to open another app on the desktop and then print to PDF. 我正在调用的应用程序需要在桌面上打开另一个应用程序,然后打印为PDF。 IIS cannot open programs on the desktop unless set in the services --> service name --> log on tab. 除非在services --> service name --> log选项卡中进行设置,否则IIS无法在桌面上打开程序。

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. 不幸的是,我正在调用的应用程序不在“服务”面板中,因此我目前再次陷入困境,但至少我知道这不是C#问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM