.Net Core 命令行应用程序 | Process.Start() 在某些机器上运行,但在其他机器上不运行

Posted

技术标签:

【中文标题】.Net Core 命令行应用程序 | Process.Start() 在某些机器上运行,但在其他机器上不运行【英文标题】:.Net Core Command Line App | Process.Start() runs on some machines but not others 【发布时间】:2017-11-10 17:13:20 【问题描述】:

背景

我正在编写一个 .NET Core 命令行应用程序作为构建系统的 CLI。构建系统的这一部分涉及从类库生成 NuGet 包。我正在使用ProcessStartInfo.csProcess.cs 调用nuget.exe 来发出打包命令(nuget.exe 位置在系统中PATH)。

注意:我不能使用 dotnet CLI 进行打包,因为类库不是 .NET Core 项目,所以请不要说“你为什么不直接使用 dotnet pack

堆栈

C# .NET Core(我的 CLI) C# .NET 4.5(类库) Thoughtworks GoCD(构建服务器) Windows Server 2016(构建服务器操作系统) Windows 10(本地计算机操作系统)

问题

我面临的问题是,在我的个人机器上,当我运行构建系统 CLI 时,一切正常;但是,当我的构建服务器运行它时,该进程似乎试图启动,但随后退出而不抛出异常或返回任何类型的退出代码。两个帐户(我在本地计算机上的帐户和运行构建服务器的帐户)都是本地管理员帐户。


代码

Cmd.cs(执行进程)

public static class Cmd

    public static int Execute(string filename, string arguments)
    
        var startInfo = new ProcessStartInfo
        
            CreateNoWindow = true,
            FileName = filename,
            Arguments = arguments,
        ;

        using (var process = new Process  StartInfo = startInfo )
        
            try
            
                process.Start();
                process.WaitForExit(30000);
                return process.ExitCode;
            

            catch (Exception exception)
            
                if (!process.HasExited)
                
                    process.Kill();
                

                Console.WriteLine($"Cmd could not execute command filename arguments:\nexception.Message");
                return (int)ExitCode.Exception;
            
        
    

Package.cs(使用 Cmd.cs)

// Some code before this

// The below three variables are generated/provided and are made up here for show
var version = "1.0.0";
var package = $"MyLib.version";
var projectPath = "C:\Some\Made\Up\Path";
///////////

// Real code
var tempPath = $"Path.Combine(Path.GetTempPath(), "NugetPackages")";
var packagePath = Path.Combine(tempPath, package);

if (!Directory.Exists(tempPath))

    try
    
        Directory.CreateDirectory(tempPath);
    

    catch (Exception exception)
    
        Console.WriteLine($"Could not create directory in user temp file: exception.Message");
        return (int) ExitCode.FilePermission;
    


var filename = "nuget.exe";
var arguments = $"pack -Version version -OutputDirectory tempPath -properties Configuration=Release projectPath";
var exitCode = Cmd.Execute(filename, arguments);

if (exitCode != 0)

    Console.WriteLine($"Process failed to execute and exited with exit code: exitCode");
    return exitCode;


Console.WriteLine($"package built successfully");

// Some code after this

【问题讨论】:

您需要获取 nuget.exe 输出以检查错误,因为您隐藏了进程窗口,您应该重定向 StandardOutput 并读取结果。此外,可能是该过程花费了超过 30 秒并且您没有等待它,以调试删除 WaitForExit 的超时。 好点,我看了一下,似乎相同版本的 NuGet.exe 在 Windows 10 Pro 和 Windows Server 2016 上的行为不同......不知道为什么,但在 Windows 10 Pro 上我可以使用 -Version 标记替换 .nuspec 中的 $version$ 令牌,但在 Windows Server 2016 中,我不能这样做,必须创建一个新令牌(例如 $package$)并使用 -properties 开关替换 $package $ 与我的版本......跛脚酱! 【参考方案1】:

我修改了我的代码以显示所有窗口输出,并且似乎相同版本的 NuGet.exe 在 Windows 10 Pro 与 Windows Server 2016 上的行为不同......不知道为什么,但在 Windows 10 Pro 上我可以使用 -版本标记替换 .nuspec 中的 $version$ 令牌,但在 Windows Server 2016 中,我不能这样做,必须使用不同的令牌(例如 $package$)并使用 -properties 开关将 $package$ 替换为我的版本...蹩脚的酱汁!

所以,而不是:

nuget.exe pack -Version 1.0.0 -OutputDirectory C:\Somewhere -properties Configuration=Release MyLib

我必须使用

nuget.exe pack -OutputDirectory C:\Somwhere -properties "Configuration=Release;package=1.0.0" MyLib

【讨论】:

以上是关于.Net Core 命令行应用程序 | Process.Start() 在某些机器上运行,但在其他机器上不运行的主要内容,如果未能解决你的问题,请参考以下文章

如何从命令行运行 .NET Core 控制台应用程序

将数组作为命令行参数传递给 Asp.Net Core

.Net Core 命令行应用程序 | Process.Start() 在某些机器上运行,但在其他机器上不运行

使用命令行如何在 ASP.NET 中首先从 DB 搭建脚手架 - 而不是 ASP.NET Core MVC?

.NET Core系列 : 1.NET Core 环境搭建和命令行CLI入门

.Net Core App - 命令行格式异常