Delphi Выполнение командной строки - PullRequest
1 голос
/ 03 декабря 2010

Я пытаюсь запустить команду командной строки из моего приложения Delphi.

ShellExecute(Form1.Handle, 
             'open', 
             'cmd.exe',
             'icacls "C:\ProgramData\My Program\File" /grant Users:F',
             nil,
             SW_NORMAL);

Примечание. Сама команда работает отлично.

Однако, когда я запускаю этот код вDelphi Я получаю всплывающее окно команд, но команда, которую я хочу выполнить, не запускается и даже не появляется в окне команд.

Есть идеи относительно того, что мне не хватает?

Ответы [ 3 ]

3 голосов
/ 03 декабря 2010

Командной строке нужно что-то перед ней.

/ c - запустит

/ k - заставит его работать и не исчезнет после завершения

2 голосов
/ 03 декабря 2010

Какую ОС вы используете? Я уверен, что такая команда требует повышения прав на любой платформе Windows после XP.

Вот код, который я использую для повышения процесса под Vista / Windows 7

uses
  Windows, ShellAPI, Registry;

type
  TExecuteFileOption = (
    eoHide,
    eoWait,
    eoElevate
  );
  TExecuteFileOptions = set of TExecuteFileOption;

...

function IsUACActive: Boolean;
var
  Reg: TRegistry;
begin
  Result := FALSE;

  if CheckWin32Version(6, 0) then
  begin
    Result := FALSE;

    Reg := TRegistry.Create;
    try
      Reg.RootKey := HKEY_LOCAL_MACHINE;

      if Reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System') then
      begin
        if (Reg.ValueExists('EnableLUA')) and (Reg.ReadBool('EnableLUA')) then
          Result := TRUE;
      end;
    finally
      FreeAndNil(Reg);
    end;
  end;
end;

function ExecuteFile(Handle: HWND; const Filename, Paramaters: String; Options: TExecuteFileOptions): Integer;
var
  ShellExecuteInfo: TShellExecuteInfo;
  ExitCode: DWORD;
begin
  Result := -1;

  ZeroMemory(@ShellExecuteInfo, SizeOf(ShellExecuteInfo));
  ShellExecuteInfo.cbSize := SizeOf(TShellExecuteInfo);
  ShellExecuteInfo.Wnd := Handle;
  ShellExecuteInfo.fMask := SEE_MASK_NOCLOSEPROCESS;

  if (eoElevate in Options) and (IsUACActive) then
    ShellExecuteInfo.lpVerb := PChar('runas');

  ShellExecuteInfo.lpFile := PChar(Filename);

  if Paramaters <> '' then
    ShellExecuteInfo.lpParameters := PChar(Paramaters);

  // Show or hide the window
  if eoHide in Options then
    ShellExecuteInfo.nShow := SW_HIDE
  else
    ShellExecuteInfo.nShow := SW_SHOWNORMAL;

  if ShellExecuteEx(@ShellExecuteInfo) then
    Result := 0;

  if (Result = 0) and (eoWait in Options) then
  begin
    GetExitCodeProcess(ShellExecuteInfo.hProcess, ExitCode);

    while (ExitCode = STILL_ACTIVE) and
          (not Application.Terminated) do
    begin
      sleep(50);

      GetExitCodeProcess(ShellExecuteInfo.hProcess, ExitCode);
    end;

    Result := ExitCode;
  end;
end;
2 голосов
/ 03 декабря 2010

Вам не нужно создавать оболочку для запуска такой команды. Это исполняемый файл консоли, и вы можете запустить его напрямую с помощью CreateProcess (). Вызывать оболочку просто означает вызвать исполняемый файл (cmd.exe) и заставить его вызывать другой более или менее так же, как вы бы вызвали его напрямую. Вы просто тратите время на создание двух процессов вместо одного. ИМХО, это плохая практика программирования и просто показывает, что вызывающая сторона не имеет ни малейшего представления о том, как работает Windows;

...