从 ASP.NET 启动进程 - 为啥进程会立即终止?

Posted

技术标签:

【中文标题】从 ASP.NET 启动进程 - 为啥进程会立即终止?【英文标题】:Starting a process from ASP.NET - Why does the process immediately die?从 ASP.NET 启动进程 - 为什么进程会立即终止? 【发布时间】:2011-11-09 06:50:23 【问题描述】:

我正在尝试从 ASP.NET C# 应用程序启动进程。我的应用程序通过进程自己的 API(这是第三方程序)与该进程通信。我只需要在某些情况下运行这个进程,所以我认为没有必要让它在服务器上持续运行,因此需要从我的应用程序启动进程。

我正在使用的进程设置为通过命令行参数以“不露面”模式运行,因此不需要在任何地方出现 GUI。在不提供太多信息的情况下,它对特定数据执行复杂的计算(数据从流程内部的外部源中提取,并且此数据不断更新)并通过 API 公开结果。我的应用程序通过传递 xml 格式的查询并接收类似格式的响应与此 API 进行通信。

我遇到的问题是启动进程工作正常,但它以 SYSTEM 用户身份运行进程。这是一个问题,因为我正在启动的进程已注册给特定用户,并且在以 SYSTEM 身份运行时以有限的“试用版”模式运行,而我需要的 API 无法按预期工作。因此,我打算以注册程序的特定用户身份运行。但是,当我为正确的用户添加登录信息时,该过程开始并立即退出... 有什么具体的方法我应该这样做吗?

以下是我无法正常工作的代码:

public static bool ProcessActive() 
    return Process.GetProcesses().Any(p => p.ProcessName.Equals("Process", StringComparison.InvariantCultureIgnoreCase));


public static void  StopProcess() 
    List<Process> processExists = Process.GetProcesses().Where(p => p.ProcessName.Equals("Process", StringComparison.InvariantCultureIgnoreCase)).ToList();

    foreach (Process p in processExists) 
        p.Kill();
    


public static bool StartProcess(bool stopIfStarted = false) 
    bool retVal = false;
    using (System.Security.SecureString password = new System.Security.SecureString()) 

        // Set up the variables required to run the process
        ProcessStartInfo pInfo = new ProcessStartInfo(@"C:\Program Files\Program\Program.exe");
        pInfo.Arguments = @"-arg1 -arg2";
        pInfo.WorkingDirectory = @"C:\Program Files\Program";
        pInfo.UserName = "username";
        pInfo.Domain = "DOMAIN";
        password.AppendChar('p');
        /* repeat for other password chars */
        pInfo.Password = password;
        pInfo.UseShellExecute = false;

        if (System.IO.File.Exists(pInfo.FileName)) 

            //Check if the process is already running
            bool processExists = ProcessActive();
            if (stopIfStarted && processExists) 
                StopProcess();
                processExists = ProcessActive();
            

            //if not, start it.
            if (!processExists) 
                StatusHelper.Log("Process isn't running. Starting process...");
                using (Process realProcess = Process.Start(pInfo)) 
                    processExists = ProcessActive();
                    System.Threading.Thread.Sleep(1000);
                    processExists = ProcessActive();
                    if (realProcess.HasExited) 
                        // Always gets here
                    
                    retVal = processExists;
                
            
        
    
    return retVal;

【问题讨论】:

你根本不应该从 ASP.NET 启动进程......因为 Vista MS 已经非常严格的安全性,所以 Windows 服务(IIS/ASP.NET 在这方面只是一个特殊的子类型)被限制做任何“类似桌面”的事情......请详细说明这是什么类型的过程(控制台或用户界面?它到底做了什么?等等)。 我在我的问题中添加了更多说明。该过程以一种“匿名”模式运行,没有 UI 和控制台输出。我通过基于 xml 的 API 与这个进程进行通信。 【参考方案1】:

我从 ASP .Net 4.0 开始进程的方法: 1. 实际启动进程的远程类(它在命令行中启动 Adob​​e Reader 以打印 PDF) 2. 系统托盘应用程序作为远程对象的主机 3. 在 .Net 2.0 和特定用户下运行的 Web 服务,作为远程​​对象的客户端 4. ASP .Net 4.0网站调用webservice方法

当一个进程从 ASP .Net 启动时,它“挂起”。我可以在任务管理器中看到它,但它什么也没做,所以这是我找到的唯一解决方案。您可以在控制台应用程序或 Windows 服务中托管远程对象。 WCF 将是另一个不错的远程处理选择,但我还没有尝试过。

【讨论】:

【参考方案2】:

它可能无法回答您的问题,但做这类事情的一种相当稳健的方式是,例如安装了使用正确凭据运行的 Windows 服务,并在 Web 服务器和服务之间进行一些通信,例如通过私人消息队列甚至一些 Web API。

这样,您就不会因为授予 Web 进程比它真正需要的更多的权利而使您的计算机陷入危险境地。

您可以想象,如果您在 Web 进程中所做的事情是可能的,那么攻击就有很多可能在机器上获得提升的权限。

【讨论】:

【参考方案3】:

我不知道设置进程用户权限的任何具体方法,但是您可以查看立即退出的原因是否在进程本身内部,例如由于权限受限而引发异常。

使用 StartInfo 获取流程输出流:

pInfo.StartInfo.RedirectStandardInput = true;
pInfo.StartInfo.RedirectStandardOutput = true;
pInfo.StartInfo.RedirectStandardError = true;
pInfo.StartInfo.ErrorDialog = false;

开始该过程后,您可以这样阅读:

StreamReader sOut = pInfo.StandardOutput;
StreamReader sError = pInfo.StandardError;
string standardResult = sOut.ReadToEnd();
string standardError = sError.ReadToEnd();

【讨论】:

我实际上尝试过并将结果记录到一个文件中,但没有任何输出......不过感谢您的建议。

以上是关于从 ASP.NET 启动进程 - 为啥进程会立即终止?的主要内容,如果未能解决你的问题,请参考以下文章

Asp.net 启动报错:ID为xx的进程当前未运行

在 ASP.NET 中以不同用户身份启动进程

从 ASP.NET 页面按钮启动 WPF 单击

ASP.NET - 为啥会突然找不到数据库文件?

使用 CreateProcessWithLogonW 从服务启动的进程立即终止

为啥我的 fork 子进程在我 fork 后立即退出?