Search code examples
c++windowswinapipaintcreateprocess

Open image with create process and ms paint


Hi i have task to open image with mspaint (microsoft paint) and do that with create process (windows.h)

how can i do that? i try :

STARTUPINFO info = { sizeof(info) };
    PROCESS_INFORMATION processInfo;
    std::string p = pic.getPath();
    if (CreateProcessA(LPCSTR(p),"C:\\Windows\\system32\\mspaint.exe", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
    {
        WaitForSingleObject(processInfo.hProcess, INFINITE);
        CloseHandle(processInfo.hProcess);
        CloseHandle(processInfo.hThread);
    }

and another thing , i need to close it with control c and make sure that my exe doesn't close how can i do that also?

thanks


Solution

  • Your parameters to CreateProcessA() are wrong.

    For one thing, you can't typecast a std::string to an LPCSTR (aka const char*) the way you are doing.

    And second, even if that compiled (which it shouldn't), you have the first 2 parameters backwards. You are passing the picture file path in the lpApplicationName parameter, and the mspaint path in the lpCommandLine parameter. As the documentation states:

    If both lpApplicationName and lpCommandLine are non-NULL, the null-terminated string pointed to by lpApplicationName specifies the module to execute, and the null-terminated string pointed to by lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C programmers generally repeat the module name as the first token in the command line.

    In other words, you are trying to execute the picture file as an application, which it is not. You need to execute mspaint instead, passing it the picture file as a command-line argument. In this case, it would be best to just use lpCommandLine by itself and ignore the lpApplicationName:

    The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space–delimited token in the lpCommandLine string.

    Try this instead:

    STARTUPINFOA info = { sizeof(info) };
    PROCESS_INFORMATION processInfo;
    std::string p = pic.getPath();
    std::string cmd = "C:\\Windows\\system32\\mspaint.exe \"" + p + "\"";
    if (CreateProcessA(NULL, const_cast<LPSTR>(cmd.c_str()), NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo))
    {
        WaitForSingleObject(processInfo.hProcess, INFINITE);
        CloseHandle(processInfo.hProcess);
        CloseHandle(processInfo.hThread);
    }
    

    As for closing the MSPaint process, you can't use CTRL-C for that. Instead, find the HWND that belongs to the MSPaint window, and then send it a WM_CLOSE or WM_QUIT message. CreateProcess() tells you the main thread ID of the spawned process, you can use EnumThreadWindows() to find all of the HWNDs that belong to that thread. And then use SendMessage() to send messages to them.