Delphi Executing command line command

I am trying to run a command-line command from inside my Delphi application.

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

Note: The command its self works perfectly.

However when I run this code in Delphi I get the command window popping up but the command I want to execute doesn't run or even appear in the command window.

Any idea as to what I am missing?

Answers


You have no need to create a shell to run such a command. It is console executable, and you can run it directly with CreateProcess(). Invoking a shell just mean to invoke an executable (cmd.exe) and have it invoke the other more or less the same way you would have invoked it directly. You just spend time creating two processes instead of one. IMHO that's a bad programing practice, and just shows the caller has not a clue on how Windows works ;)


Which OS are you using? I'm pretty sure a command like this requires elevation on any Windows platform after XP.

Here's the code I use for elevating a process under 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;

Need Your Help

How to update(in-place) the JSON document in couchbase?

couchbase

I want to add a field in an existing document in couchbase.

Android default email app can not be called in my situation, how to resolve?

android email

I know I can use android build in email app when I use the intent with ACTION_SEND, there is no problem for me. The problem comes after I defined the ACTION_SEND in my AndroidManifest.xml like foll...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.