【问题标题】:IIS hosted WCF service executing Git commands hangs执行 Git 命令的 IIS 托管 WCF 服务挂起
【发布时间】:2014-11-27 21:21:30
【问题描述】:

我写了一个 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();

参数是:克隆https://github.com/XXXX/YYYY

或者:克隆 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));

【问题讨论】:

    标签: git wcf iis


    【解决方案1】:

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

    公共接口 IProcessRunner { 无效开始(字符串工作目录,字符串文件名,字符串参数); bool CompletedWithSuccess(); 字符串 GetStandardOutput(); 字符串 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();
        }
    }
    

    【讨论】:

    • 老实说,我实际上最终完全放弃了这个解决方案,并找到了一种更清洁的方法来解决我的问题,其中不包括 Git 命令 :)。但我已经发布了跑步者作为对其他人的帮助。
    猜你喜欢
    • 2022-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多