c# - 为什么 Dart 将进程参数包装在 C# 没有的引号中?
问题描述
我正在将一些 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?
解决方案
我认为最简单的方法是像这样拆分参数名称和参数值:
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',
]);
这样您就不必担心转义或引用参数。
推荐阅读
- python - Anaconda:ImportError:无法从“PIL”(matplotlib.pyplot)导入名称“_imaging”
- javascript - 从分配给映射对象键的数组中提取数组元素
- spring-boot - ThymeleafView:java.lang.IllegalArgumentException:需要属性“区域设置”
- excel - 如何用公式定义数字数组
- python - 无法更改一列中的分类数据(熊猫、机器学习)
- spring-boot - 如何正确模块化应用程序配置,以便测试(IT、datajpa、...)不会获取所有用于生产的内容
- r - 有没有办法在 R(或 ml3)的 recipes 包中对行(尤其是虚拟变量)进行分组
- powerbi - DAX 中的 IF 条件是在行上创建笛卡尔连接
- windows - 在 AD 中将组从一个用户复制到另一个用户,但一个特定组除外
- java - 如何从我的 Application 类中找出 onActivityResult 的结果?