【发布时间】:2019-09-10 07:43:31
【问题描述】:
我正在将一些 C# 代码移植到 Windows 上的 Dart 中,但在 Dart 将命令行参数传递给进程的方式存在令人沮丧的差异上浪费了几个小时。
这是被移植的 C# 代码的一部分,它执行得很好:
var startInfo = new ProcessStartInfo("C:\\Program Files\\Inkscape\\inkscape.exe", "--file=\"C:\\Users\\Kent\\test.svg\" --export-png=\"C:\\Users\\Kent\\test.png\" --export-width=100 --export-area-page")
{
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
};
var process = Process.Start(startInfo);
process.WaitForExit();
if (process.ExitCode != 0)
{
var stdout = process.StandardOutput.ReadToEnd();
var stderr = process.StandardError.ReadToEnd();
Console.WriteLine(stdout);
Console.WriteLine(stderr);
}
正确运行会生成一个输出 PNG 文件。但是,Dart 等价物不会:
final inkscapeResult = await Process.run(
r'C:\Program Files\Inkscape\inkscape.exe',
[
'--file="C:\\Users\\Kent\\test.svg"',
'--export-png="C:\\Users\\Kent\\test.png"',
'--export-width=100',
'--export-area-page',
],
);
final exitCode = inkscapeResult.exitCode;
if (exitCode != 0) {
writeError(inkscapeResult.stdout);
writeError(inkscapeResult.stderr);
}
相反,进程以代码1 退出,程序输出:
** (inkscape.exe:5604): WARNING **: 17:30:09.785: Can't open file: "C:\Users\Kent\test.svg" (doesn't exist)
** (inkscape.exe:5604): WARNING **: 17:30:09.785: Can't open file: "C:\Users\Kent\test.svg" (doesn't exist)
** (inkscape.exe:5604): WARNING **: 17:30:09.785: Specified document "C:\Users\Kent\test.svg" cannot be opened (does not exist or not a valid SVG file)
众所周知,Inkscape 在命令行上执行时有点挑剔,但我读过的建议是简单地传递完整路径,我正在这样做。
我发现,如果我避免争论,它会起作用:
final inkscapeResult = await Process.run(
r'C:\Program Files\Inkscape\inkscape.exe --file="C:\\Users\\Kent\\test.svg" --export-png="C:\\Users\\Kent\\test.png" --export-width=100 --export-area-page',
[],
);
所以我推断 Dart 一定是在做一些 Inkscape 不喜欢的论点。我设法使用 Process Explorer 捕捉到它,它具有以下命令行:
"C:\Program Files\Inkscape\inkscape.exe" "--file=\"C:\Users\Kent\test.svg\"" "--export-png=\"C:\Users\Kent\test.png\"" --export-width=100 --export-area-page
如果我直接从命令行运行它,我不会得到任何输出,但图像也不会生成,所以大概它以同样的方式失败了。将此与 C# 代码生成的命令行进行比较:
"C:\Program Files\Inkscape\inkscape.exe" --file="C:\Users\Kent\test.svg" --export-png="C:\Users\Kent\test.png" --export-width=100 --export-area-page
Dart 将每个单独的参数用引号括起来,而 C# 不是(尽管 C# 的 API 甚至不分隔单独的参数)。这在某种程度上破坏了 Inkscape 的解析器。
谁错了?我、Dart、C# 还是 Inkscape?
【问题讨论】:
-
似乎只有当命令行参数本身包含双引号时,Dart 才会添加周围的双引号。例如:
'--file=C:\\Users\\Kent\\test.svg'.
标签: c# windows dart command-line