【发布时间】:2010-10-03 22:04:12
【问题描述】:
我想在我的代码中调用一个 Windows 程序,并在代码本身中确定参数。
我不是要调用外部函数或方法,而是要调用 WinXP 环境中的实际 .exe 或批处理/脚本文件。
C 或 C++ 将是首选语言,但如果使用任何其他语言(ASM、C#、Python 等)更容易做到这一点,请告诉我。
【问题讨论】:
标签: c++ c winapi external-application
我想在我的代码中调用一个 Windows 程序,并在代码本身中确定参数。
我不是要调用外部函数或方法,而是要调用 WinXP 环境中的实际 .exe 或批处理/脚本文件。
C 或 C++ 将是首选语言,但如果使用任何其他语言(ASM、C#、Python 等)更容易做到这一点,请告诉我。
【问题讨论】:
标签: c++ c winapi external-application
当您调用 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)。
【讨论】:
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
}
}
【讨论】:
我认为您正在寻找 Windows API 中的 CreateProcess 函数。实际上有一系列相关的电话,但这会让你开始。这很容易。
【讨论】:
执行此操作的最简单方法之一是使用system() 运行时库函数。它采用单个字符串作为参数(比CreateProcess! 少得多的参数)并像在命令行上键入一样执行它。 system() 还会自动等待进程完成后再返回。
还有一些限制:
运行时库还提供了一系列 exec* 函数(execl、execlp、execle、execv、execvp,或多或少),它们源自 Unix 传统并提供更多控制整个过程。
在最低级别,在 Win32 上,所有进程都由CreateProcess 函数启动,这为您提供了最大的灵活性。
【讨论】:
简单的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 (); } }
【讨论】: