要点: 一个c#app应该在发送之前调用gpg.exe来加密文件。在测试中,我们发现了一个gpg始终失败的计算机配置。
我的目标是创建一个封装批处理文件,该文件调用GPG但将命令行args打印到输出文件,并让我们的应用程序调用它。
用于调用命令的C#代码:
public static int StartProcess(string command, string arguments, int waitForProcess)
{
ProcessStartInfo startInfo = null;
if (string.IsNullOrEmpty(arguments))
startInfo = new ProcessStartInfo(command);
else
startInfo = new ProcessStartInfo(command, arguments);
startInfo.CreateNoWindow = true;
startInfo.ErrorDialog = false;
startInfo.UseShellExecute = false;
Process p = new Process();
p.StartInfo = startInfo;
p.Start();
请注意,我无法控制系统所期望的文件名,因为这是生产代码:我们期望命令为C:\ Program Files \ gnupg \ gpg。
我将真正的gpg.exe重命名为gpg2.exe,并创建了一个批处理文件(除非相关,否则请忽略可怕的批处理代码。它应该是一个快速诊断而非强大的解决方案):
@echo off
ECHO %* > "C:\Program Files\GNU\GnuPG\gpgoutput.txt"
"C:\Program Files\GNU\GnuPG\gpg2" %1 %2 %3 %4 %5 %6 %7 %8 %9 >> gpgoutput.txt
if ERRORLEVEL 1 echo 1 >> gpgoutput.txt
if ERRORLEVEL 0 echo 0 >> gpgoutput.txt
if ERRORLEVEL 2 echo 2 >> gpgoutput.txt
exit /b 0
原来p.Start()会抛出错误而无法找到批处理文件。所以,我下载了bat_to_exe_converter来将bat文件转换为exe格式。我将文件保存为GPG.exe
流程流现在应该是C#app调用'gpg.exe'>调用gpg2.exe并记录变量/退出代码。
这个代码从命令提示符运行正常但是从c#app调用时,退出代码是9211,我可以看到没有创建gpgoutput.txt文件,暗示它实际上并没有运行'gpg.exe “
为什么上述代码不能从我的C#应用程序中正确执行?我唯一的想法是,它必须以某种方式与权限或目录相关。
编辑:我尝试手动设置命令到C:\ Program Files \ gnupg \ gpg.bat,代码工作正常。这个问题似乎是由 a)如果只查找C:\ Program Files \ gnupg \ gpg并且文件保存为gpg.bat,则会出现错误“系统找不到指定的文件” b)如果我将批处理转换为gpg.exe,系统可以找到该文件,但是退出代码为~9200。这是exe转换器的错吗?
答案 0 :(得分:1)
首先,我不会使用batch-file-converted-to-exe。所有这一切都会让事情变得更难。
其次,您应该能够使用Process运行批处理文件。将ProcessStartInfo.UseShellExecute
设置为true
后,我希望它能够正常工作"。但即使是这样,你应该能够执行命令行解释器,因为" cmd.exe / c ..." " ..."是执行批处理文件的完整命令。如果你仍然遇到问题,你可能会问这个问题。
最后,就您的包装批处理文件而言,最明显的问题是您使用exit /b 0
将退出代码显式设置为0。如果要返回gpg2.exe进程的退出代码,则需要在运行gpg2.exe(例如set EXITCODE=%errorlevel%
)后立即保存,然后在退出批处理文件时使用该值(例如{ {1}})。
如果从批处理文件返回进程的实际退出代码,那么C#程序应该能够正确读取代码。
(立即保存该值可确保批处理文件中稍后的其他语句(也可能影响错误级别值)不会干扰您返回正确的退出代码。)