I have the following code:
// Fetch Local App Data folder path.
PWSTR localAppData = (PWSTR) malloc(128);
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppData);
// Find out the absolute path to chrome.exe
stringstream ss;
ss << localAppData << "/Google/Chrome/Application/chrome.exe";
The result of stringstreamer's .str()
is 008F6788/Google/Chrome/Application/chrome.exe
, which is wrong.
I can't seem to get stringstreamer to work, neither do strcat or wcsncat due to type incompatibilities.
How do I cast this PWSTR to string?
Microsoft says:
typedef wchar_t* LPWSTR, *PWSTR;
So let's get that horrid nonsense out of your testcase, and lose the C rubbish:
// Fetch Local App Data folder path.
wchar_t* localAppData = new wchar_t[128];
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppData);
stringstream ss;
ss << localAppData << "/Google/Chrome/Application/chrome.exe";
delete[] localAppData;
There is a serious flaw here.
SHGetKnownFolderPath
actually sets the value of the pointer you give it to point to memory that it allocated. Your code has a memory leak, and my last snippet frees the memory subtly wrongly.
Let's fix that by reading the documentation:
ppszPath [out]
Type: PWSTR*
When this method returns, contains the address of a pointer to a null-terminated Unicode string that specifies the path of the known folder. The calling process is responsible for freeing this resource once it is no longer needed by calling CoTaskMemFree. The returned path does not include a trailing backslash. For example, "C:\Users" is returned rather than "C:\Users\".
// Fetch Local App Data folder path.
wchar_t* localAppData = 0;
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppData);
stringstream ss;
ss << localAppData << "/Google/Chrome/Application/chrome.exe";
CoTaskMemFree(static_cast<void*>(localAppData));
Now, on with the show.
The syntax issue with your code is that localAppData is a wchar_t
, but normal stringstream
s work on char
.
Fortunately, there is a wide-char variant called wstringstream
that uses wchar_t
instead.
(Note that this means your literal will have to be built out of wchar_t
s, too, using the L
string literal prefix.)
And now the final code:
// Fetch Local App Data folder path.
wchar_t* localAppData = 0;
SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppData);
wstringstream ss;
ss << localAppData << L"/Google/Chrome/Application/chrome.exe";
CoTaskMemFree(static_cast<void*>(localAppData));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With