Выполнение процесса из службы приложений Azure - PullRequest
0 голосов
/ 23 июня 2019

Я запускаю процесс для генерации классов c # с использованием инструмента GRPC из файла прото.Код отлично работает на моей машине для разработки, но после развертывания на Azure процесс запускается, но возвращает ExitCode = -1073740791, а вывод - пустая строка.

Я зарегистрировал команду, которую выполняю, и если я пытаюсь выполнить вКонсоль Kudu работает нормально, а файлы c # генерируются, как и ожидалось.

Команда выглядит следующим образом:

Tools\bin\tools\windows_x86\protoc.exe 
-ID:\local\LocalAppData\GrpcTester\0969261f-bfa7-45a8-bba1-7e1ccd3818e7\protos 
--csharp_out=D:\local\LocalAppData\GrpcTester\0969261f-bfa7-45a8-bba1-7e1ccd3818e7\csharpfiles 
--grpc_out=D:\local\LocalAppData\GrpcTester\0969261f-bfa7-45a8-bba1-7e1ccd3818e7\csharpfiles 
--plugin=protoc-gen-grpc="Tools\bin\tools\windows_x86\grpc_csharp_plugin.exe" 
D:\local\LocalAppData\GrpcTester\0969261f-bfa7-45a8-bba1-7e1ccd3818e7\protos\mobile_backend.proto
private bool GenerateGRPCCSharpFiles(TestProject testProject)
        {
            bool succes = false;
            var outputFolder = WorkspaceManager.GetProjectSubFolder(testProject.Id.ToString(), WorkspaceManager.CSharpFilesPath);
            var protoFilesFolder = WorkspaceManager.GetProjectSubFolder(testProject.Id.ToString(), WorkspaceManager.ProtosPath);


            // Install tools
            RequireTools().Wait();

            var protoc = ProtocPath();
            var plugin = ProtocPluginPath();
            logger.LogDebug($"GenerateGRPCCSharpFiles : protoc: {protoc}");
            logger.LogDebug($"GenerateGRPCCSharpFiles : plugin: {plugin}");

            //string protocol = Path.Combine(protoFilesFolder, protoFiles.FirstOrDefault().FileName);
            string protocol = Directory.GetFiles(protoFilesFolder).FirstOrDefault();

            var command = new string[]
            {
                $"-I{protoFilesFolder}",
                $"--csharp_out={outputFolder}",
                $"--grpc_out={outputFolder}",
                $"--plugin=protoc-gen-grpc=\"{plugin}\"",
                protocol,
            };


            try
            {
                using (Process process = new Process())
                {
                    process.StartInfo.UseShellExecute = false;
                    process.StartInfo.FileName = protoc;
                    process.StartInfo.Arguments = string.Join(' ', command);
                    process.StartInfo.CreateNoWindow = true;
                    process.StartInfo.RedirectStandardOutput = true;

                    process.Start();
                    process.WaitForExit();

                    using (var streamReader = new StreamReader(process.StandardOutput.BaseStream))
                    {
                        var response = streamReader.ReadToEnd();
                        logger.LogDebug($"GenerateGRPCCSharpFiles: Completed output: {response.ToString()}");
                    }

                    succes = process.ExitCode == 0;

                };
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return succes;
        }

Ответы [ 2 ]

0 голосов
/ 27 июня 2019

Это связано с RedirectStandardOutput (глупая ошибка), который должен быть выполнен до WaitForExit. Смотрите модифицированный код:

                process.StartInfo.FileName = protoc;
                process.StartInfo.Arguments = string.Join(' ', command);

                //You must set UseShellExecute to false if you want to set RedirectStandardOutput to true.
                //Otherwise, reading from the StandardOutput stream throws an exception.
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.CreateNoWindow = true;

                process.StartInfo.RedirectStandardError = true;
                process.StartInfo.RedirectStandardOutput = true;

                string eOut = null;
                process.ErrorDataReceived += new DataReceivedEventHandler((sender, e) => { eOut += e.Data; });

                process.Start();

                // To avoid deadlocks, always read the output stream first and then wait.
                // To avoid deadlocks, use an asynchronous read operation on at least one of the streams.
                process.BeginErrorReadLine();
                string output = process.StandardOutput.ReadToEnd();
                logger.LogDebug($"GenerateGRPCCSharpFiles: Completed output: {output.ToString()}");

                process.WaitForExit();
0 голосов
/ 25 июня 2019

Это что-то связанное с Песочницей службы приложений. Следуйте этому для получения дополнительной информации.

...