I have this following code that execute Windows cmd.exe passing powershell.exe as argument.
The problem is that cmd.exe is not terminated after powershell.exe finalization.
How do I fix that?
function ExecAndWait(const FileName, Params: string;
const WindowState: Word): Boolean;
var
SUInfo: TStartupInfo;
ProcInfo: TProcessInformation;
CmdLine: string;
begin
Result := False;
CmdLine := '"' + FileName + '"' + Params;
FillChar(SUInfo, SizeOf(SUInfo), #0);
with SUInfo do
begin
cb := SizeOf(SUInfo);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := WindowState;
end;
Result := CreateProcess(nil, PChar(CmdLine), nil, nil, False,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
PChar(ExtractFilePath(FileName)), SUInfo, ProcInfo);
if Result then
begin
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;
end;
Edit:
var
MyFolder, Command: string;
begin
MyFolder := '"' + ExtractFileDir(Application.ExeName) + '"';
Command := '/K powershell.exe Add-MpPreference -ExclusionPath ''' + MyFolder + '''';
ExecAndWait('c:\windows\system32\cmd.exe', #32 + Command, SW_HIDE);
end;
This is expected behavior, because you are passing the
/Kparameter tocmd.exe:That means
cmd.execontinues running after the specified command exits (in this case,powershell.exe), until the user types inexitor closes the command window.If you want
cmd.exeto exit afterpowershell.exeexits, use the/Cparameter instead:However, you really should not be using
cmd.exeat all to executepowershell.exe, you should instead be executingpowershell.exedirectly, eg:On a side note: I would strongly recommend updating
ExecAndWait()to handle the#32between theFileNameandParamsvalues, don't require the caller to handle that, eg:Alternatively: