【问题标题】:Process.Start cannot run batch file properlyProcess.Start 无法正确运行批处理文件
【发布时间】: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

标签: c# batch-file process environment-variables processstartinfo


【解决方案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复制到批处理文件目录,则无需手动指定路径
猜你喜欢
  • 2014-09-16
  • 1970-01-01
  • 2018-10-01
  • 2018-04-21
  • 1970-01-01
  • 2019-03-17
  • 2014-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多