web-dev-qa-db-ja.com

パラメータを使用して外部プログラムを呼び出す方法は?

コード内で決定されたパラメーターを使用して、コード内でWindowsプログラムを呼び出したいのですが。

外部の関数やメソッドを呼び出すのではなく、WinXP環境内の実際の.exeまたはバッチ/スクリプトファイルを呼び出します。

CまたはC++が推奨される言語ですが、これが他の言語(ASM、C#、Pythonなど)でより簡単に実行できる場合はお知らせください。

27
Will

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を見つける必要があるため、完全修飾である必要はありませんが、確実にしたい場合は、 CSIDL_SYSTEMを使用して完全修飾ファイル名を作成できます。 (単にC:\ Windows\system32\cmd.exeを使用しないでください)。

28
Roger Nelson

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
        }
    }
11
Rorzilla

Windows APIで CreateProcess 関数を探していると思います。実際には関連する通話のファミリーがありますが、これで開始できます。とても簡単です。

8

これを行う最も簡単な方法の1つは、system()ランタイムライブラリ関数を使用することです。単一の文字列をパラメーターとして受け取り(CreateProcess!よりもパラメーターがはるかに少ない)、コマンドラインで入力した場合と同じように実行します。 system()は、プロセスが終了するまで自動的に待機してから戻ります。

制限もあります:

  • 起動されたプロセスのstdinおよびstdoutを制御する能力が低下する
  • 他のプロセスの実行中は(他のプロセスを強制終了するなど)何もできません
  • 何らかの方法でクエリを実行するために、他のプロセスへのハンドルを取得することはできません

ランタイムライブラリは、exec*関数のファミリー(execlexeclpexecleexecvexecvp、多かれ少なかれ)UNIXの遺産から派生し、プロセスをより詳細に制御できます。

最下位レベルでは、Win32では、すべてのプロセスがCreateProcess関数によって起動され、最も柔軟性が高くなります。

5
Greg Hewgill

簡単なc ++の例(いくつかのWebサイトを検索した後に見つかりました)

#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 (); } }
0
EnzoGuerra