Shell commands

I should do get the files of a directory in a stringlist or something like that.
I did not find any Delphi function to do that. So
I wrote dos a batch file and execute it from my app.
with the winexec command. There would be no problem for me If dos application closes when my main application closed.
I run it like this
winexec('blabla', SW_HIDE)
When I press Ctrl+Alt+Del I see winoldapp
If I execute batch file several times inside my application then the number of winoldappsincereasing and leading the system to low resource problem
First of all
How can I get directory list with a windows funtion (without a shell program)
Then How can I get rid of winoldapps when I shell a command.
Because I will use a shell batch file other than getting directory.

Helps will be appreciated
Thanks in advance
guvencumAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
rwilson032697Connect With a Mentor Commented:
For 1, here's an example from my SiteSplicer code, to load all DLLs, as you can see, adding the names to a stringlist is trivial:

constructor TSSPluginList.Create;

var
  Handle : THandle;
  Search : TSearchRec;
  I : integer;
  NPlugInsFunc : TPluginNumPluginsFunc;
  Res : Integer;

begin
// Load the plugins into the list. We assume that the plugins reside in the
// <ApplicationPath>\plugins directory

  try
    Res := FindFirst(ExtractFileDir(Application.Exename) + '\Plugins\*.dll', faAnyFile, Search);
    if res = 0 then
      repeat
        Handle := LoadLibrary(PChar(Search.Name));
        NPlugInsFunc := GetProcAddress(Handle, TPluginNumPluginsFuncName);
        if assigned(NPlugInsFunc) then
          for I := 1 to NPlugInsFunc do
            try
              Add(TSSPlugIn.Create(Handle, I));
            except
              ShowMessage(format('Failed to access functions for plugin %s', [Search.Name]));
              Break;
            end
        else
          ShowMessage(format('Could not load plugin %s', [Search.Name]));
      until FindNext(Search) <> 0;
  finally
    FindClose(Search);
  end;
end;

For 2, you can do this to create the process running the command. When you quit your application you can use TerminateProcess to kill of any remaining programs.

unit runThread_;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
  ExtCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen}
  public
    { Public-Deklarationen}
  end;

var Form1 : TForm1 = nil;

implementation

{$R *.DFM}

const unitName = 'runThread_.';

type TRunThread = class(TThread)
  private
    processHandle : cardinal;
    processReady  : boolean;
    waitingThread : cardinal;
    procedure Execute; override;
  end;

procedure TRunThread.Execute;
begin
  WaitForSingleObject(processHandle,INFINITE);   // This call does not return, unless copy is stopped
  processReady:=true;                            // Set "processReady" flag for main thread
  PostThreadMessage(waitingThread,WM_NULL,0,0);  // Wake up main thread
                                                 // If you call Application.HandleMessage (see below) in the
                                                 // main thread, the main thread is sleeping the most time in
                                                 // winAPI "waitMessage". So we send a "dummy" message in order
                                                 // to let the main thread return from Application.HandleMessage
end;

procedure TForm1.Button1Click(Sender: TObject);
var si  : TStartupInfo;
    pi  : TProcessInformation;
    dw1 : dword;
begin
  enabled:=false;
  caption:='start copy...';
  ZeroMemory(@si,sizeOf(si)); si.cb:=sizeOf(si);
  si.dwFlags:=STARTF_USESHOWWINDOW; si.wShowWindow:=SW_HIDE;
  if CreateProcess(nil,'c:\command.com /c copy c:\autoexec.bat c:\test.bat >c:\output.txt',nil,nil,false,0,nil,nil,si,pi) then begin
    caption:='copy started...';
    with TRunThread.Create(true) do         // create the thread object, but do not start it now...
      try
        processHandle:=pi.hProcess;         // tell the thread what process it has to watch
        processReady:=false;                // flag for the loop (see below)
        waitingThread:=GetCurrentThreadID;  // the current threadID for the wakeup message (see above)
        caption:='wait for copy...';
        Resume;                             // now all information is prepared; so let's start the thread
        repeat
          Application.HandleMessage;        // message loop
        until Application.Terminated or processReady;  // continue with normal program when either the
                                                       // started process has stopped or our program is closed
        caption:='copy stopped...';
      finally Free end;
    GetExitCodeProcess(pi.hProcess,dw1);
    CloseHandle(pi.hThread); CloseHandle(pi.hProcess); // Never forget to close handles...
    caption:='ready... (exitCode='+IntToStr(dw1)+')';
  end else caption:='could not start copy...';
  enabled:=true;
end;


Cheers,

Raymond.
0
 
RBertoraCommented:
Why didn't you use a FileListBox ?
this is a component in
the win3.1 component pallette, you
can use this in combination with DirectroyListbox, DriveCombobox and FilterCombobox.

Filelistbox is effectively a stringlist of files in a directory..

Rob ;-)
0
 
RBertoraCommented:
Although Ray has given you the best and prooven solution to launching and terminating dos box.
Rob ;-)
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
simonetCommented:
Following...®
0
 
rwilson032697Commented:
Here's my FindFirst code above in a nicer form for you...

Procedre GetFileList(const FileList : TStringList);

var
  Search : TSearchRec;
  Res : Integer;

begin
  FileList.Clear;
  try
    Res := FindFirst(ExtractFileDir(Application.Exename) + '*.*', faAnyFile, Search);
    if res = 0 then
      repeat
        FileList.Add(Searc.name);
      until FindNext(Search) <> 0;
  finally
    FindClose(Search);
  end;
end;

Cheers,

Raymond.
0
 
rwilson032697Commented:
Make that:

        FileList.Add(Search.name);

:o)

Raymond.
0
 
LischkeCommented:
..additionally, never call FindClose if FindFirst returns with a value <> 0 or your application may hang occasionally under WInNT.

Ciao, Mike
0
 
rwilson032697Commented:
And with that warning in mind :-)

Procedre GetFileList(const FileList : TStringList);

var
  Search : TSearchRec;
  Res : Integer;

begin
  FileList.Clear;
  Res := FindFirst(ExtractFileDir(Application.Exename) + '*.*', faAnyFile, Search);
  if res = 0 then
    try
      repeat
        FileList.Add(Searc.name);
      until FindNext(Search) <> 0;
    finally
      FindClose(Search);
    end;
end;

Cheers,

Raymond.
0
 
LischkeCommented:
perfect :-)
0
All Courses

From novice to tech pro — start learning today.