0

I would like to display the contents of a directory using DOS commands from Delphi(7). Using Win10 - 64

The following program displays the DOS shell but does not display the directory contents. What is wrong with my code ?

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, shellapi;
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;

  implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var i : integer;
begin
   i := ShellExecute(Handle, nil, 'cmd.exe', PChar(' dir'), nil, SW_SHOW);
   caption := inttostr(i);
end;

end.
Ken White
  • 123,280
  • 14
  • 225
  • 444
user1530405
  • 447
  • 1
  • 8
  • 16
  • If your question is about Delphi, why isn't there a Delphi tag? And DOS died more than a decade ago, so you can't be running a DOS command (unless you're still running Windows XP or earlier). – Ken White Nov 02 '16 at 00:01
  • 2
    DOS as an OS is long dead, but `cmd.exe` as a command processor still exists in modern Windows versions. But the real question is, why use `cmd.exe` to get a directory listing instead of using a `FindFirst/Next()` loop, or a GUI component like `TDirectoryListBox` (or modern replacement). – Remy Lebeau Nov 02 '16 at 00:36

1 Answers1

5

Running your code on Windows 10 returns 2, which is ERROR_FILE_NOT_FOUND.

I got it to work, on both 32- and 64-bit target platforms, by changing it to this:

var
  ComSpec: string;
  retval: HINSTANCE;
begin
  ComSpec := GetEnvironmentVariable('comspec');
  retval := ShellExecute(Handle, nil, PChar(comspec), '/k dir', nil, SW_SHOW);
  if retval <= 32 then
    Caption := Format('Error, return value = %d', [retval])
  else
    Caption := 'Success';
end;

The /k says to run a new instance of cmd.exe and keep the window open. For more details, run cmd /? from a command prompt.

Note that the error handling of ShellExecute is very limited. If you wish to check for errors comprehensively then you must use ShellExecuteEx instead.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Ken White
  • 123,280
  • 14
  • 225
  • 444
  • 4
    Note that many of the error codes returned by `ShellExecute()` are not standard Win32 error codes. In this particular case, it happens that `ShellExecute()`'s error 2 does mean "file not found". If you need to rely on individual error codes, it is better to use `ShellExecuteEx()` instead, since it uses `GetLastError()` for reporting its error code. – Remy Lebeau Nov 02 '16 at 00:43