使用Process.Start作为另一个用户在asp.net mvc应用程序上运行.bat文件

时间:2012-05-13 14:32:35

标签: asp.net asp.net-mvc iis-7 iis-7.5

我正在尝试使用Process.Start运行批处理文件

我正在使用以下代码:

Process myProcess = new Process();
myProcess.StartInfo.FileName = "D:\\test.bat";
myProcess.StartInfo.UserName = "user";
var strPass = new SecureString();

for (int i = 0; i < strUserPass.Length; i++)
    {
        strPass.AppendChar(strUserPass[i]);
    }
strPass.MakeReadOnly();

myProcess.StartInfo.Password = strPass;
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardInput = true;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.RedirectStandardError = true;

myProcess.Start();

我正在使用ASP.NET MVC 3和IIS 7.5

当我在本地计算机(Windows 7)上运行此代码时,它运行正常。

当我在我的服务器(Windows Server 2008 R2)上运行此代码时,它不起作用。进程启动但未执行批处理文件,并且该进程没有任何StandardOutput或StandardError。我无法获得任何信息,也没有错误。

如果我没有指定任何UserName和密码,它可以在我的服务器上运行。批处理文件使用我的网络服务帐户执行。

我真的需要使用特定的用户名执行该过程。

你知道为什么它不起作用吗?

---编辑:Microsoft支持发现了解释

由于Windows Vista和会话隔离,服务和用户应用程序在不同的会话中执行。

Windows不允许使用其他凭据执行从会话到另一个会话的进程。该过程将使用会话的默认凭据(AppPool凭证)执行。

更多信息herehere

1 个答案:

答案 0 :(得分:0)

您是否尝试过myProcess.StartInfo.CreateNoWindow = true;

我曾经找到过这段伟大的代码(我猜这里的SO)对我来说很好用:

    private bool RunProcess(string executableProgram, string arguments, int timeOut)
    {
        bool Result = false;
        int exitCode = 0;

        using (Process process = new Process())
        {
            process.StartInfo.FileName = executableProgram;
            process.StartInfo.Arguments = arguments;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

            StringBuilder output = new StringBuilder();
            StringBuilder error = new StringBuilder();

            using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
            using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
            {
                process.OutputDataReceived += (sender, e) =>
                {
                    if (e.Data == null)
                    {
                        outputWaitHandle.Set();
                    }
                    else
                    {
                        output.AppendLine(e.Data);
                    }
                };
                process.ErrorDataReceived += (sender, e) =>
                {
                    if (e.Data == null)
                    {
                        errorWaitHandle.Set();
                    }
                    else
                    {
                        error.AppendLine(e.Data);
                    }
                };

                process.Start();

                process.BeginOutputReadLine();
                process.BeginErrorReadLine();

                if (process.WaitForExit(timeOut) && outputWaitHandle.WaitOne(timeOut) && errorWaitHandle.WaitOne(timeOut))
                {
                    exitCode = process.ExitCode;
                    Result = (exitCode == 0);
                }
                else
                {
                    // Timed out.
                    Result = false;
                }
            }

            if (!string.IsNullOrEmpty(output.ToString()))
            {
                Logger.Info(output.ToString());
            }
            if (!string.IsNullOrEmpty(error.ToString()))
            {
                Logger.Error(error.ToString());
            }

        }
        return (Result);
    }