0

I'm trying to open a picture using WinApi in c++, tried both createProcessW and createProcessA, my main problem was concatenating the strings that are used as cmdLine parameter. this is what iv'e got:

STARTUPINFOW process_startup_info{ 0 };
process_startup_info.cb = sizeof(process_startup_info); // setup size of strcture in bytes

PROCESS_INFORMATION process_info{ 0 };

wchar_t* s = L"\"C:\\Windows\\system32\\mspaint.exe\" ";
std::string s2 = pic.getPath();
// connecting strings here
if (CreateProcessW(NULL, /* string should be here */, NULL, NULL, TRUE, 0, NULL, NULL, &process_startup_info, &process_info))
{
    WaitForSingleObject(process_info.hProcess, INFINITE);
    CloseHandle(process_info.hProcess);
    CloseHandle(process_info.hThread);
}
1
  • 2
    You need to convert the path to the picture to a wide string before you can concatenate the two. Commented Mar 24, 2020 at 18:09

2 Answers 2

3

Try to use the same types everywhere for the command and the params if you can. Here I am using a wstring, concatenating a parameter to the command then casting it to LPWSTR for the CreateProcess method.

STARTUPINFOW process_startup_info{ 0 };
process_startup_info.cb = sizeof(process_startup_info); // setup size of strcture in bytes

PROCESS_INFORMATION process_info{ 0 };

std::wstring params = L"\"C:\\Windows\\system32\\mspaint.exe\" ";
params.append(L"\"C:\\Vroom Owl.png\"");

// connecting strings here
if (CreateProcessW(NULL, (LPWSTR)params.data(), NULL, NULL, TRUE, 0, NULL, NULL, &process_startup_info, &process_info))
{
    WaitForSingleObject(process_info.hProcess, INFINITE);
    CloseHandle(process_info.hProcess);
    CloseHandle(process_info.hThread);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Setting the project to multi-byte instead of Unicode will make CreateProcess() call CreateProcessA() instead of CreateProcessW(). It is actually better NOT to rely on the TCHAR macros. In this case, if you use std::wstring then you should call CreateProcessW() directly to match. Also note that using const_cast<LPWSTR>(params.c_str()) is technically undefined behavior, use params.data() (C++17 or later) or &params[0] (C++11 or later) instead (std::(w)string data was not guaranteed to be stored in sequential memory prior to C++11, but it usually was in practice).
@RemyLebeau I can get on board with that. I'll update my answer accordingly.
Don't cast away const-ness if you can help it. If your compiler has a data() method available but not a non-const version of it, using &[0] will work and no cast needed of it.
0

In include :

#include <sstream>

In code:

std::wstringstream wstringCmd;

std::wstring wstrExec = L"\"C:\\Windows\\system32\\mspaint.exe\" "; //<- wstring 
std::string strPic = pic.getPath(); //<- if getPath() return char  
// std::wstring wstrPic = pic.getPath();//<- if getPath() return wchar  

// you can combine as you like ...
wstringCmd << wstrExec.c_str() << strPic.c_str(); // or << wstrPic.c_str();
std::wstring wstrCommande= wstringCmd.str();

6 Comments

I'm confused by the strPic and wstrPic values here. The method calls are enclosed in double quotes. Surely that was an oversight.
Also, you can't stream a std::string or char* into a std::wstringstream, either. You would have to convert the std::string to std::wstring first
@NTDLS it was just to explain that we have "string" or L"string"
@RemyLebeau try it, if it doesn't work, we'll talk about it again
@Landstalker I did try it, and OK granted, << works for char* even when the stream is std::wstringstream, but it does not work for std::string. Also, you can't save a std::wstring from std::wstringstream.str() to a std::string.
|

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.