问题
The following code utilizes CreateProcess
to run commands with environmental variables. Here, it tries to run notepad %APPDATA%\test.txt
.
If I run notepad %APPDATA%\test.txt
directly within Windows' CMD
, %APPDATA% will be expanded. However, the environmental variable can not be expanded when executed by CreateProcess
. Could you help to comment on the reason and the workaround? Any comment will be appreciated!


program TestConsole2;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils;
var
I: Integer;
ProgramName: String;
StartInfo : TStartupInfo;
ProcInfo : TProcessInformation;
CreateOK : Boolean;
begin
try
FillChar(StartInfo, SizeOf(StartInfo), #0);
FillChar(ProcInfo, SizeOf(ProcInfo), #0);
StartInfo.cb := SizeOf(StartInfo);
ProgramName := 'NOTEPAD %APPDATA%\test.txt';
CreateOK := CreateProcess(
nil, PChar(ProgramName), nil, nil, True, 0, nil, nil, StartInfo, ProcInfo);
if CreateOK then WaitForSingleObject(ProcInfo.hProcess, INFINITE);
Readln(ProgramName);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
回答1:
Call ExpandEnvironmentStrings to expand environment variables.
When you use cmd.exe, it performs the expansion for you. CreateProcess does not so you will need to do it before calling CreateProcess. Alternatively you could use ShellExecute which will expand environment strings.
Your current code does not meet the contract of CreateProcess. The second parameter must be a pointer to modifiable memory. You can get away with this if you are using the ANSI API but when targetting Unicode you code is liable to fail. Pass a pointer to modifiable memory rather than a pointer to a literal. If you added a call to expand the environment variables then you would end up with a modifiable string.
Finally, it looks like you are just trying to open a text file. Why force the user to view it in Notepad? My default editor for text files is not Notepad. I'd loath any program that forced Notepad on me. Instead let the shell open the file in the user's preferred editor. Call ShellExecute, use 'open' as the verb and pass the text file name as the file name parameter. On the other hand, perhaps you know all this and this is just example code. If so, please just ignore this advice.
来源:https://stackoverflow.com/questions/9890746/how-to-use-or-expand-environment-variables-in-a-command-instantiated-by-createpr