【发布时间】:2017-11-10 17:13:20
【问题描述】:
背景
我正在编写一个 .NET Core 命令行应用程序作为构建系统的 CLI。构建系统的这一部分涉及从类库生成 NuGet 包。我正在使用ProcessStartInfo.cs 和Process.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}:\n{exception.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 $ 与我的版本......跛脚酱!
标签: c# asp.net .net windows .net-core