Process.Start 无法正确运行批处理文件

Posted

技术标签:

【中文标题】Process.Start 无法正确运行批处理文件【英文标题】:Process.Start cannot run batch file properly 【发布时间】:2019-12-02 05:25:03 【问题描述】:

我正在尝试使用 C# 运行批处理文件

用于测试的批处理文件包含

msg * Test

如果我手动运行它就可以了。

然后我用下面的代码来运行这个.bat文件

filePath = full path to batch file

var startInfo = new ProcessStartInfo

    Arguments = "/C \"" + filePath + "\"",
    FileName = "cmd.exe",
    UseShellExecute = true
;
Process p = Process.Start(startInfo);

它不起作用 ->

cannot find msg

我做错了什么?

附:不应更改批处理文件。

【问题讨论】:

从 C# 运行时,msg 在上下文中是否可用?是在同一个目录下还是在你的PATH 环境变量中? @Neijwiert 如何检查?即使我将完整的文件路径放到 msg.exe 中,它也不起作用 检查您的 Windows PATH 环境变量并检查Environment.CurrentDirectory 【参考方案1】:

问题是文件(msg.exe)在不同操作系统版本(32bit/64bit)中的位置

我想这会有所帮助How can I execute msg.exe by C# in windows?

已编辑: 它工作正常 -

class Program

    static void Main(string[] args)
    
        int ExitCode;

        try
        
            var returnedMsgPath = string.Empty;

            if (LocateMsgExe(out returnedMsgPath))
            
                var startInfo = new ProcessStartInfo()
                
                    FileName = returnedMsgPath,
                    Arguments = @"* /v Hello",
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true
                ;

                var p = Process.Start(startInfo);
                p.WaitForExit();
                // *** Read the streams ***
                string output = p.StandardOutput.ReadToEnd();
                string error = p.StandardError.ReadToEnd();

                ExitCode = p.ExitCode;

                MessageBox.Show("output >>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
                MessageBox.Show("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
                MessageBox.Show("ExitCode: " + ExitCode.ToString(), "ExecuteCommand");
                p.Close();
            
            else
            
                MessageBox.Show("Not found");
            
        
        catch (Exception ex)
        
            MessageBox.Show(ex.Message);
        
    

    public static bool LocateMsgExe(out string returnedMsgPath)
    
        returnedMsgPath = null;
        string[] msgPaths = new string[]  Environment.ExpandEnvironmentVariables(@"%windir%\system32\msg.exe"),
                                 Environment.ExpandEnvironmentVariables(@"%windir%\sysnative\msg.exe") ;

        foreach (string msgPath in msgPaths)
        
            if (File.Exists(msgPath))
            
                returnedMsgPath = msgPath;
                return true;
            
        

        return false;
    

【讨论】:

据我了解,它正在运行一个批处理文件,而程序不知道其中有什么。问题是它在资源管理器中启动批处理时有效,但不是通过代码。 你看我的评论了吗?我知道您发布的解决方案有效,但它是针对不同的问题。 Msg 只是用来测试的。它也不适用于其他命令。 用“ping”或“echo”或其他什么代替“msg”有什么问题? @VadymPolshcha 如果 msg 在测试用例中不起作用,其他东西也不起作用。这就是使用 msg.exe 的重点【参考方案2】:

可能需要一些授权,你可以试试下面的代码:

static void ExecuteCommand(string command)

    int exitCode;
    ProcessStartInfo processInfo;
    Process process;

    processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
    processInfo.CreateNoWindow = true;
    processInfo.Domain = "domain"; // Your own domain
    processInfo.UserName = "userName"; // Your own user name
    System.Security.SecureString s = new System.Security.SecureString();
    s.AppendChar('p'); // Your own password
    s.AppendChar('a');
    s.AppendChar('s');
    s.AppendChar('s');
    s.AppendChar('w');
    s.AppendChar('o');
    s.AppendChar('r');
    s.AppendChar('d');
    processInfo.Password = s;
    processInfo.UseShellExecute = false;
    // *** Redirect the output ***
    processInfo.RedirectStandardError = true;
    processInfo.RedirectStandardOutput = true;

    process = Process.Start(processInfo);
    process.WaitForExit();

    // *** Read the streams ***
    // Warning: This approach can lead to deadlocks, see Edit #2
    string output = process.StandardOutput.ReadToEnd();
    string error = process.StandardError.ReadToEnd();

    exitCode = process.ExitCode;

    Console.WriteLine("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : 
 output));
    Console.WriteLine("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : 
 error));
    Console.WriteLine("ExitCode: " + exitCode.ToString(), "ExecuteCommand");
    process.Close();


static void Main()

    ExecuteCommand(@"C:\displayMsg.bat");
   

您可以在控制面板>>用户帐户>>管理用户帐户中检查您的域

参考来源:source

【讨论】:

谢谢!有用!但是如何让它在不询问密码的情况下在其他电脑上运行呢? 您需要以管理员身份运行,因此需要管理【参考方案3】:

试试这个方法: 批处理文件:

set "msg=%SystemRoot%\System32\msg.exe"
if not exist "%msg%" set "msg=%SystemRoot%\Sysnative\msg.exe"
"%msg%" * Hello 

代码:

string sFile = <full path to batch file>;
 Process.Start("cmd.exe", "/c " + sFile);

【讨论】:

感谢您的回答,但是如何在不更改批处理文件的情况下运行它? msg 命令只是一个例子 例如-如果将msg.exe复制到批处理文件目录,则无需手动指定路径

以上是关于Process.Start 无法正确运行批处理文件的主要内容,如果未能解决你的问题,请参考以下文章

是否有任何与 Process.Start 等效的异步?

当我调用 process.start() 时,Python 多处理进程只会停止我的代码运行

Process.Start() 未启动 .exe 文件(手动运行时有效)

Process.Start 打开资源管理器

识别 C# Process.Start() 运行的可执行文件的崩溃

C# Process.Start 在批处理文件中弄乱了 URI