Unicode environment blocks and CreateProcess
I've just been struggling with a Unicode conversion of some code that passes a custom environment block to a child process.
On Unicode Delphi compilers the code produces a Unicode environment block, and I'd done something like this...
procedure ExecProgWithUnicodeEnv(const ProgName: string; EnvBlock: Pointer); var SI: TStartupInfo; PI: TProcessInformation; SafeProgName: string; begin SafeProgName := ProgName; // workaround for read-only lpCommandLine UniqueString(SafeProgName); // param to CreateProcessW FillChar(SI, SizeOf(SI), 0); SI.cb := SizeOf(SI); CreateProcess( nil, PChar(ProgName), nil, nil, True, 0, EnvBlock, nil, SI, PI ); end;
If you're wandering about that UniqueString stuff, check out this post.
The assumption was that CreateProcessW would expect a Unicode environment block. Wrong! It actually still expects an ANSI block by default.
A dig around in the API docs revealed the answer: If you pass a Unicode environment block to CreateProcess in the lpEnvironment parameter you must also include CREATE_UNICODE_ENVIRONMENT in the dwCreationFlags parameter. So it's just a matter of changing
... CreateProcess( nil, PChar(ProgName), nil, nil, True, 0, EnvBlock, nil, SI, PI ); ...
to
... CreateProcess( nil, PChar(ProgName), nil, nil, True, CREATE_UNICODE_ENVIRONMENT, EnvBlock, nil, SI, PI ); ...
In the end, because my project guarantees a Unicode environment block if and only if it is compiled on a Unicode Delphi, I went for code similar to the following:
... {$IFDEF UNICODE} CreateFlags := CREATE_UNICODE_ENVIRONMENT; {$ELSE} CreateFlags := 0; {$ENDIF} CreateProcess( nil, PChar(SafeProgName), nil, nil, True, CreateFlags, EnvBlock, nil, SI, PI ); ...
You definately shouldn't use conditional compilation like this if there's a chance you'll be handling an ANSI environment block with a Unicode compile, or vice-versa.
There we have it, just one more thing to consider when porting code to Unicode.
And the code in question? It's part of the demo for my article "How to access environment variables".
Comments
Post a Comment
Comments are very welcome, but please be aware that I moderate all comments, so there will be a delay before your comment appears.
Advertising spam and the rare abusive, hateful or racist comments will be blocked and reported.
Finally, should you have a query about, or a bug report for, one of my programs or libraries please use the relevant issue tracker rather than posting a comment to report it.
Thanks