从ASP.NET启动流程 - 为什么流程会立即死亡?

时间:2011-11-09 06:50:24

标签: c# asp.net process

我正在尝试从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;
}

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

通过这种方式,您可以通过为Web进程提供比实际需要更多的权限来让您自己陷入危及您机器的境地。

你可以想象,如果你在网络进程中所做的事情是可能的,那么攻击就有很多可能来提升机器的权限。

答案 2 :(得分:0)

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

使用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();