转换为exe的批处理文件中的退出代码在由Process.Start()调用时不返回0

时间:2014-10-29 19:50:11

标签: c# batch-file

要点: 一个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转换器的错吗?

1 个答案:

答案 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#程序应该能够正确读取代码。

(立即保存该值可确保批处理文件中稍后的其他语句(也可能影响错误级别值)不会干扰您返回正确的退出代码。)