Einzelnen Beitrag anzeigen

Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#10

AW: Seltsames Phänomen bei CMDs

  Alt 29. Apr 2015, 13:51
Mal so nebenbei: Wenn dieses Programm auf Kundenrechnern läuft, sollte man auf das MSDN-Library durchsuchenSetEnvironmentVariable vielleicht komplett verzichten (ich zumindest mag es nicht, wenn mir jemand ungefragt an globalen Einstellungen rumspielt ). Es gibt noch eine andere Lösung:
Delphi-Quellcode:
function CreateEnvironmentBlock(lpEnvironment: Pointer; hToken: THandle;
  bInherit: BOOL): BOOL; stdcall;
  external 'userenv.dll';
function DestroyEnvironmentBlock(lpEnvironment: Pointer): BOOL; stdcall;
  external 'userenv.dll';

procedure TForm5.Button1Click(Sender: TObject);
var
  Token: THandle;
  EnvironmentBlock: Pointer;
  EnvData: WideString;
  CurVar: PWideChar;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  if (OpenProcessToken(GetCurrentProcess, TOKEN_ALL_ACCESS, Token)) then
  try
    if (not CreateEnvironmentBlock(@EnvironmentBlock, Token, false)) then
      RaiseLastOSError;
    try
      EnvData := '';
      // Copy existing environment variables
      CurVar := EnvironmentBlock;
      repeat
        if (CurVar <> '') then
        begin
          EnvData := EnvData + CurVar + #0;
          CurVar := PWideChar(PByte(CurVar) + (Length(CurVar) + 1) * SizeOf(WideChar));
        end;
      until (CurVar = '');
      // Add new environment variables
      EnvData := EnvData + 'test=wuppdi' + #0;
      EnvData := EnvData + 'var2=DP' + #0;
      // Add termination char
      EnvData := EnvData + #0;
      // Start console with modified environment block
      FillChar(StartupInfo, SizeOf(StartupInfo), #0);
      StartupInfo.cb := SizeOf(StartupInfo);
      if (not CreateProcess('C:\Windows\System32\cmd.exe', nil, nil, nil, false,
        CREATE_UNICODE_ENVIRONMENT, @EnvData[1], nil, StartupInfo, ProcessInfo)) then
        RaiseLastOSError;
      try
        // ..
      finally
        CloseHandle(ProcessInfo.hProcess);
        CloseHandle(ProcessInfo.hThread);
      end;
    finally
      DestroyEnvironmentBlock(EnvironmentBlock);
    end;
  finally
    CloseHandle(Token);
  end;
end;
Hier habe ich mir den aktuellen EnvironmentBlock ausgelesen, kopiert und noch weitere Variablen angehangen. Dieser Block wird dann an MSDN-Library durchsuchenCreateProcess übergeben und gillt somit ausschließlich für die gestartete Konsoleninstanz.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat