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 don't comment here if:
1) You have a query about, or a bug report for, one of my programs or libraries. Most of my posts contain a link to the relevant repository where there will be an issue tracker you can use.
2) You have a query about any 3rd party programs I feature, please address them to the developer(s) - there will be a link in the post.
3) You're one of the tiny, tiny minority who are aggressive or abusive - in the bin you go and reported you will be!
Thanks