34

I would like to call a windows program within my code with parameters determined within the code itself.

I'm not looking to call an outside function or method, but an actual .exe or batch/script file within the WinXP environment.

C or C++ would be the preferred language but if this is more easily done in any other language let me know (ASM, C#, Python, etc).

1

5 Answers 5

30

When you call CreateProcess(), System(), etc., make sure you double quote your file name strings (including the command program filename) in case your file name(s) and/or the fully qualified path have spaces otherwise the parts of the file name path will be parsed by the command interpreter as separate arguments.

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

For Windows it is recommended to use CreateProcess(). It has messier setup but you have more control on how the processes is launched (as described by Greg Hewgill). For quick and dirty you can also use WinExec(). (system() is portable to UNIX).

When launching batch files you may need to launch with cmd.exe (or command.com).

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

(or SW_SHOW_NORMAL if you want the command window displayed ).

Windows should find command.com or cmd.exe in the system PATH so in shouldn't need to be fully qualified, but if you want to be certain you can compose the fully qualified filename using CSIDL_SYSTEM (don't simply use C:\Windows\system32\cmd.exe).

Sign up to request clarification or add additional context in comments.

1 Comment

These are wonderful tips for possible future obstacles and general clarification. Thanks a lot.
11

C++ example:

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

C# example:

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

Comments

9

I think you are looking for the CreateProcess function in the Windows API. There are actually a family of related calls but this will get you started. It is quite easy.

1 Comment

Well, it's not as easy as using system() but at least such a solution exists! Thanks for the strongest suggestion and link.
8

One of the simplest ways to do this is to use the system() runtime library function. It takes a single string as a parameter (many fewer parameters than CreateProcess!) and executes it as if it were typed on the command line. system() also automatically waits for the process to finish before it returns.

There are also limitations:

  • you have less control over the stdin and stdout of the launched process
  • you cannot do anything else while the other process is running (such as deciding to kill it)
  • you cannot get a handle to the other process in order to query it in any way

The runtime library also provides a family of exec* functions (execl, execlp, execle, execv, execvp, more or less) which are derived from Unix heritage and offer more control over the process.

At the lowest level, on Win32 all processes are launched by the CreateProcess function, which gives you the most flexibility.

1 Comment

This is definitely what I thought I was looking for...but those limitations are pretty hard to get by...I might do it if the design will work with it. Thanks for this info!
0

simple c++ example (found after searching a few websites)

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.