IIS托管的WCF服务执行Git命令挂起

时间:2014-04-25 14:14:32

标签: git wcf iis

我写了一个WCF服务,我在IIS中托管,到目前为止一直很好。

该服务在开发期间在我自己的帐户下运行(应用程序池是我的用户)。

服务执行git clone命令,如下所示:

        var process = new Process();
        process.StartInfo.WorkingDirectory = workingDirectory ?? _pathToRepository;
        process.StartInfo.FileName = _pathToGitExecutable;
        process.StartInfo.Arguments = command;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardInput = true;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        process.EnableRaisingEvents = true;

        process.OutputDataReceived += (sender, args) => Debug.WriteLine(args.Data);
        process.ErrorDataReceived += (sender, args) => Debug.WriteLine(args.Data);

        process.Start();

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

        process.WaitForExit();

参数是:clone https://github.com/XXXX/YYYY

或者:clone git@github.com:XXXX / YYYY

当我调用服务时(调试视图):

Cloning into 'YYYY'...

如果我检查路径,我可以看到预期的新目录(YYYY)和.git文件夹,但是没有其他事情发生。

如果我手动运行命令,它可以正常工作。

很可能该命令正在等待某些输入(用户/传递/其他),因为在模拟期间以其他方式从而导致IIS。一个Windows服务会,但我没办法告诉我,因为我没有得到任何关于StdErr / StdOut的反馈。

任何人都可以想到我可以前进并找出问题的方法吗?

更新

我尝试过HOME变量,但没有骰子:

        process.StartInfo.EnvironmentVariables.Remove("HOME");
        process.StartInfo.EnvironmentVariables.Add("HOME", System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile));

1 个答案:

答案 0 :(得分:0)

通过为进程包装器执行更“正确”和异步的实现来解决这个问题,如下所示:

公共接口IProcessRunner     {         void Start(string WorkingDirectory,string FileName,string Arguments);         bool CompletedWithSuccess();         string GetStandardOutput();         string GetStandardError();     }

public class ProcessRunner : IProcessRunner
{
    private readonly StringBuilder _standardOutput = new StringBuilder();
    private readonly StringBuilder _standardError = new StringBuilder();
    private readonly AutoResetEvent _standardOutputWaitHandle = new AutoResetEvent(false);
    private readonly AutoResetEvent _standardErrorWaitHandle = new AutoResetEvent(false);
    private int _processExitCode = -1;

    public void Start(string WorkingDirectory, string FileName, string Arguments)
    {
        var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                WorkingDirectory = WorkingDirectory,
                FileName = FileName,
                Arguments = Arguments,
                RedirectStandardError = true,
                RedirectStandardOutput = true,
                UseShellExecute = false,
                CreateNoWindow = true,
                WindowStyle = ProcessWindowStyle.Hidden,
            },
        };

        process.OutputDataReceived += process_OutputDataReceived;
        process.ErrorDataReceived += process_ErrorDataReceived;
        process.Start();
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        process.WaitForExit();
        _standardErrorWaitHandle.WaitOne(1000);
        _standardOutputWaitHandle.WaitOne(1000);

        _processExitCode = process.ExitCode;
    }

    private void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data == null)
        {
            _standardErrorWaitHandle.Set();
        }
        else
        {
            _standardError.AppendLine(e.Data);
        }
    }

    private void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data == null)
        {
            _standardOutputWaitHandle.Set();
        }
        else
        {
            _standardOutput.AppendLine(e.Data);
        }
    }

    public bool CompletedWithSuccess()
    {
        return _processExitCode == 0;
    }

    public string GetStandardOutput()
    {
        return _standardOutput.ToString();
    }

    public string GetStandardError()
    {
        return _standardError.ToString();
    }
}