【问题标题】:How to call an external program with parameters?如何调用带参数的外部程序?
【发布时间】:2010-10-03 22:04:12
【问题描述】:

我想在我的代码中调用一个 Windows 程序,并在代码本身中确定参数。

我不是要调用外部函数或方法,而是要调用 WinXP 环境中的实际 .exe 或批处理/脚本文件。

C 或 C++ 将是首选语言,但如果使用任何其他语言(ASM、C#、Python 等)更容易做到这一点,请告诉我。

【问题讨论】:

    标签: c++ c winapi external-application


    【解决方案1】:

    当您调用 CreateProcess()、System() 等时,请确保将文件名字符串(包括命令程序文件名)用双引号括起来,以防文件名和/或完全限定路径包含空格否则文件名路径的部分将被命令解释器解析为单独的参数。

    system("\"d:some path\\program.exe\" \"d:\\other path\\file name.ext\"");
    

    对于 Windows,建议使用 CreateProcess()。它的设置比较混乱,但您可以更好地控制进程的启动方式(如 Greg Hewgill 所述)。为了快速和肮脏,您还可以使用 WinExec()。 (system() 可移植到 UNIX)。

    启动批处理文件时,您可能需要使用 cmd.exe(或 command.com)启动。

    WinExec("cmd \"d:some path\\program.bat\" \"d:\\other path\\file name.ext\"",SW_SHOW_MINIMIZED);
    

    (或SW_SHOW_NORMAL,如果您希望显示命令窗口)。

    Windows 应该在系统 PATH 中找到 command.com 或 cmd.exe,因此 in 不需要完全限定,但如果您想确定可以使用 CSIDL_SYSTEM 组成完全限定的文件名(不要只需使用 C:\Windows\system32\cmd.exe)。

    【讨论】:

    • 这些是对未来可能的障碍和一般性澄清的绝妙提示。非常感谢。
    【解决方案2】:

    C++ 示例:

    char temp[512];
    sprintf(temp, "command -%s -%s", parameter1, parameter2);
    system((char *)temp);
    

    C# 示例:

        private static void RunCommandExample()
        {
            // Don't forget using System.Diagnostics
            Process myProcess = new Process();
    
            try
            {
                myProcess.StartInfo.FileName = "executabletorun.exe";
    
                //Do not receive an event when the process exits.
                myProcess.EnableRaisingEvents = false;
    
                // Parameters
                myProcess.StartInfo.Arguments = "/user testuser /otherparam ok";
    
                // Modify the following to hide / show the window
                myProcess.StartInfo.CreateNoWindow = false;
                myProcess.StartInfo.UseShellExecute = true;
                myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
    
                myProcess.Start();
    
            }
            catch (Exception e)
            {
                // Handle error here
            }
        }
    

    【讨论】:

      【解决方案3】:

      我认为您正在寻找 Windows API 中的 CreateProcess 函数。实际上有一系列相关的电话,但这会让你开始。这很容易。

      【讨论】:

      • 好吧,它不像使用 system() 那样简单,但至少存在这样的解决方案!感谢您最强烈的建议和链接。
      【解决方案4】:

      执行此操作的最简单方法之一是使用system() 运行时库函数。它采用单个字符串作为参数(比CreateProcess! 少得多的参数)并像在命令行上键入一样执行它。 system() 还会自动等待进程完成后再返回。

      还有一些限制:

      • 您对已启动进程的标准输入和标准输出的控制较少
      • 当其他进程正在运行时,您不能做任何其他事情(例如决定杀死它)
      • 您无法获取其他进程的句柄以便以任何方式查询它

      运行时库还提供了一系列 exec* 函数(execlexeclpexecleexecvexecvp,或多或少),它们源自 Unix 传统并提供更多控制整个过程。

      在最低级别,在 Win32 上,所有进程都由CreateProcess 函数启动,这为您提供了最大的灵活性。

      【讨论】:

      • 这绝对是我认为我一直在寻找的东西......但是这些限制很难克服......如果设计可以使用它,我可能会这样做。感谢您提供此信息!
      【解决方案5】:

      简单的c++示例(搜索几个网站后找到)

      #include <bits/stdc++.h>
      #include <cassert>
      #include <exception>
      #include <iostream>
      
      int main (const int argc, const char **argv) {
      try {
          assert (argc == 2);
          const std::string filename = (const std::string) argv [1];
          const std::string begin = "g++-7 " + filename;
          const std::string end = " -Wall -Werror -Wfatal-errors -O3 -std=c++14 -o a.elf -L/usr/lib/x86_64-linux-gnu";
          const std::string command = begin + end;
          std::cout << "Compiling file using " << command << '\n';
      
          assert (std::system ((const char *) command.c_str ()) == 0);
          std::cout << "Running file a.elf" << '\n';
          assert (std::system ((const char *) "./a.elf") == 0);
      
          return 0; }
      catch (std::exception const& e) { std::cerr << e.what () << '\n'; std::terminate (); }
      catch (...) { std::cerr << "Found an unknown exception." << '\n'; std::terminate (); } }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-29
        • 1970-01-01
        • 2012-09-10
        • 1970-01-01
        • 2012-03-08
        • 2014-07-19
        • 2011-11-10
        • 2013-08-14
        相关资源
        最近更新 更多