Golang中无法通过C#调用可执行文件但手动CMD可以运行的问题

Golang中无法通过C#调用可执行文件但手动CMD可以运行的问题 大家好,

希望大家一切安好,注意保持健康。

我现在正为此事焦头烂额,头发都快掉光了。问题如下:

1.) 我已经构建并安装了一个Go可执行文件,称之为 “xray.exe”,它位于我的 C:\User\Go\Bin 目录中。

我可以在Windows命令提示符中毫无问题地打开该目录并运行它,就像这样… 可执行文件名 < “输入文件路径” > “输出文件路径” xray.exe < "C:\file Input path\FileIn.txt" > "D:\File Out Path\FileOutput.txt"

简单来说,我正在尝试通过一个C#项目来运行这个可执行文件(目的是自动化处理大量文件的"繁重工作")。我尝试过(在C#中)直接使用Process运行exe,或者间接地尝试通过C#中的CMD来运行它。但我无论如何都无法让它正常工作。我只能推测或猜测,这可能与正确格式化process.info字段以及如何正确模拟传递参数有关。另外,我不确定是否应该使用这些"<“和”>"符号,这些符号在我手动打开命令窗口运行时似乎是必须使用的。

请帮帮我。提前感谢您的帮助。

祝好,保重。 此致, -S


更多关于Golang中无法通过C#调用可执行文件但手动CMD可以运行的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

你好 Fineol,

感谢你的热心帮助!

关于 ProcessStartInfo.Arguments 属性,这正是我尝试使用的。我只是不知道如何格式化 Args。例如,那个可执行文件期望什么(以我的例子为例),我是否需要包含 <>?可执行文件是否通过空格来解析参数字符串,因此标准输入和输出字符串(如果包含空格)必须用引号括起来?如果我必须传递 <>,它们是否只有在两边都用空格分隔时才会被识别,比如 " < " 等等?

我只是想为可执行程序正确地格式化参数,并模仿我如何从 CMD 提示符手动操作,或者至少是可执行程序如何看到它以及它期望的格式。

有什么想法吗?

再次感谢! -S

更多关于Golang中无法通过C#调用可执行文件但手动CMD可以运行的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


通常,Go程序从键盘读取标准输入,并将标准输出写入控制台。<> 命令分别表示重定向标准输入和标准输出。通过使用它们,您将用文件“C:\file Input path\FileIn.txt”的内容替代键盘输入,并将输出写入“D:\File Out Path\FileOutput.txt”。

此时,您的问题变成了一个C# / .NET问题,而不是Go问题。您可以通过查阅微软关于 ProcessStartInfo.RedirectStandardInput 属性和 ProcessStartInfo.RedirectStandardOutput 属性的文档来寻求帮助。

或者,您可以修改您的Go程序,从程序参数中获取输入和输出文件的名称,然后直接打开这些文件。请参阅 os.Args。在这种情况下,要从C#提供这些参数,您需要使用 ProcessStartInfo.Arguments 属性。

这是一个典型的进程启动参数传递问题。在C#中直接使用 <> 重定向符号是行不通的,因为这些是命令行解释器(CMD)的功能,而不是可执行文件本身的参数。

以下是几种解决方案:

方案1:通过CMD执行(推荐)

using System.Diagnostics;

public void RunXrayViaCmd(string inputPath, string outputPath)
{
    ProcessStartInfo startInfo = new ProcessStartInfo
    {
        FileName = "cmd.exe",
        Arguments = $"/c xray.exe < \"{inputPath}\" > \"{outputPath}\"",
        WorkingDirectory = @"C:\User\Go\Bin",
        UseShellExecute = false,
        CreateNoWindow = true,
        RedirectStandardOutput = false,
        RedirectStandardError = false
    };
    
    using (Process process = Process.Start(startInfo))
    {
        process.WaitForExit();
    }
}

方案2:直接使用Process的重定向功能

using System.Diagnostics;
using System.IO;

public void RunXrayDirect(string inputPath, string outputPath)
{
    ProcessStartInfo startInfo = new ProcessStartInfo
    {
        FileName = @"C:\User\Go\Bin\xray.exe",
        WorkingDirectory = @"C:\User\Go\Bin",
        UseShellExecute = false,
        CreateNoWindow = true,
        RedirectStandardInput = true,
        RedirectStandardOutput = true
    };
    
    using (Process process = Process.Start(startInfo))
    using (StreamWriter sw = process.StandardInput)
    using (StreamReader sr = process.StandardOutput)
    {
        // 读取输入文件内容并写入标准输入
        string inputContent = File.ReadAllText(inputPath);
        sw.Write(inputContent);
        sw.Close();
        
        // 读取输出并写入文件
        string outputContent = sr.ReadToEnd();
        File.WriteAllText(outputPath, outputContent);
        
        process.WaitForExit();
    }
}

方案3:如果xray.exe支持文件路径参数

如果xray.exe支持直接传递文件路径作为参数(而不是通过重定向),可以这样调用:

public void RunXrayWithArgs(string inputPath, string outputPath)
{
    ProcessStartInfo startInfo = new ProcessStartInfo
    {
        FileName = @"C:\User\Go\Bin\xray.exe",
        Arguments = $"\"{inputPath}\" \"{outputPath}\"",
        WorkingDirectory = @"C:\User\Go\Bin",
        UseShellExecute = false,
        CreateNoWindow = true
    };
    
    using (Process process = Process.Start(startInfo))
    {
        process.WaitForExit();
    }
}

方案4:使用PowerShell

using System.Management.Automation;

public void RunXrayViaPowerShell(string inputPath, string outputPath)
{
    using (PowerShell ps = PowerShell.Create())
    {
        ps.AddScript($"cd 'C:\\User\\Go\\Bin'; .\\xray.exe < '{inputPath}' > '{outputPath}'");
        ps.Invoke();
    }
}

关键点说明:

  1. <> 是CMD的重定向操作符,不是程序参数
  2. 方案1最接近你的手动CMD操作方式
  3. 确保C#程序有足够的权限访问输入/输出文件路径
  4. 如果xray.exe在系统PATH中,可以省略完整路径

建议先用方案1测试,因为它最接近你手动操作的方式。如果遇到权限问题,可以尝试以管理员身份运行C#程序。

回到顶部