Articles   Members Online: 3
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
How to use another option to execute system commands Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
12-Oct-02
Category
System
Language
Delphi 3.x
Views
84
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			 Author: Fernando Silva

When you want to execute some command you just call WinExec. But if you want to 
execute some system command like 'dir *.*' or even execute an old DOS application, 
WinExec by itself just doesn't give all you want.

Answer:

The solution here it's by running your commands trought the COMSPEC. This is, 
COMPSPEC it's an environment variable that on Windows NT and 2000 returns the path 
to CMD.EXE and on Windows 9x returns the path to COMMAND.COM.

While I tested all this article code with Windows 2000 it can probably run also in 
Windows 9x (I think).
If you go to 'Command Prompt' and write the following you'll get a description of a 
various number of options that you can use to run a command (or a batch of commands 
in a single command line):

Starts a new instance of the Windows 2000 command interpreter

CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
    [[/S] [/C | /K] string]

/C      Carries out the command specified by string and then terminates
/K      Carries out the command specified by string but remains
/S      Modifies the treatment of string after /C or /K (see below)
/Q      Turns echo off
/D      Disable execution of AutoRun commands from registry (see below)
/A      Causes the output of internal commands to a pipe or file to be ANSI
/U      Causes the output of internal commands to a pipe or file to be
        Unicode
/T:fg   Sets the foreground/background colors (see COLOR /? for more info)
/E:ON   Enable command extensions (see below)
/E:OFF  Disable command extensions (see below)
/F:ON   Enable file and directory name completion characters (see below)
/F:OFF  Disable file and directory name completion characters (see below)
/V:ON   Enable delayed environment variable expansion using c as the
        delimiter. For example, /V:ON would allow !var! to expand the
        variable var at execution time.  The var syntax expands variables
        at input time, which is quite a different thing when inside of a FOR
        loop.
/V:OFF  Disable delayed environment expansion.

Note that multiple commands separated by the command separator '&&' are accepted 
for string if surrounded by quotes.  Also, for compatibility reasons, /X is the 
same as /E:ON, /Y is the same as /E:OFF and /R is the same as /C.  Any other 
switches are ignored.

If /C or /K is specified, then the remainder of the command line after the switch 
is processed as a command line, where the following logic is used to process quote 
(") characters:

    1.  If all of the following conditions are met, then quote characters
        on the command line are preserved:

        - no /S switch
        - exactly two quote characters
        - no special characters between the two quote characters,
          where special is one of: &<>()@^|
        - there are one or more whitespace characters between the
          the two quote characters
        - the string between the two quote characters is the name
          of an executable file.

    2.  Otherwise, old behavior is to see if the first character is
        a quote character and if so, strip the leading character and
        remove the last quote character on the command line, preserving
        any text after the last quote character.

If /D was NOT specified on the command line, then when CMD.EXE starts, it
looks for the following REG_SZ/REG_EXPAND_SZ registry variables, and if
either or both are present, they are executed first.

    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun

        and/or

    HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun

Command Extensions are enabled by default.  You may also disable extensions for a 
particular invocation by using the /E:OFF switch.  You can enable or disable 
extensions for all invocations of CMD.EXE on a machine and/or user logon session by 
setting either or both of the following REG_DWORD values in the registry using 
REGEDT32.EXE:

    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\EnableExtensions

        and/or

    HKEY_CURRENT_USER\Software\Microsoft\Command Processor\EnableExtensions

to either 0x1 or 0x0.  The user specific setting takes precedence over the machine 
setting.  The command line switches take precedence over the registry settings.

The command extensions involve changes and/or additions to the following
commands:

    DEL or ERASE
    COLOR
    CD or CHDIR
    MD or MKDIR
    PROMPT
    PUSHD
    POPD
    SET
    SETLOCAL
    ENDLOCAL
    IF
    FOR
    CALL
    SHIFT
    GOTO
    START (also includes changes to external command invocation)
    ASSOC
    FTYPE

To get specific details, type commandname /? to view the specifics.

Delayed environment variable expansion is NOT enabled by default.  You can enable 
or disable delayed environment variable expansion for a particular invocation of 
CMD.EXE with the /V:ON or /V:OFF switch.  You can enable or disable completion for 
all invocations of CMD.EXE on a machine and/or user logon session by setting either 
or both of the following REG_DWORD values in the registry using REGEDT32.EXE:

    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\DelayedExpansion

        and/or

    HKEY_CURRENT_USER\Software\Microsoft\Command Processor\DelayedExpansion

to either 0x1 or 0x0.  The user specific setting takes precedence over the machine 
setting.  The command line switches take precedence over the registry settings.

If delayed environment variable expansion is enabled, then the exclamation
character can be used to substitute the value of an environment variable
at execution time.

File and Directory name completion is NOT enabled by default.  You can enable or 
disable file name completion for a particular invocation of CMD.EXE with the /F:ON 
or /F:OFF switch.  You can enable or disable completion for all invocations of 
CMD.EXE on a machine and/or user logon session by setting either or both of the 
following REG_DWORD values in the registry using REGEDT32.EXE:

    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\CompletionChar
    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\PathCompletionChar

        and/or

    HKEY_CURRENT_USER\Software\Microsoft\Command Processor\CompletionChar
    HKEY_CURRENT_USER\Software\Microsoft\Command Processor\PathCompletionChar

with the hex value of a control character to use for a particular function (e.g.  
0x4 is Ctrl-D and 0x6 is Ctrl-F).  The user specific settings take precedence over 
the machine settings.  The command line switches take precedence over the registry 
settings.

If completion is enabled with the /F:ON switch, the two control characters used are 
Ctrl-D for directory name completion and Ctrl-F for file name completion.  To 
disable a particular completion character in the registry, use the value for space 
(0x20) as it is not a valid control character.

Completion is invoked when you type either of the two control characters.  The 
completion function takes the path string to the left of the cursor appends a wild 
card character to it if none is already present and builds up a list of paths that 
match.  It then displays the first matching path.  If no paths match, it just beeps 
and leaves the display alone.  Thereafter, repeated pressing of the same control 
character will cycle through the list of matching paths.  Pressing the Shift key 
with the control character will move through the list backwards.  If you edit the 
line in any way and press the control character again, the saved list of matching 
paths is discarded and a new one generated.  The same occurs if you switch between 
file and directory name completion.  The only difference between the two control 
characters is the file completion character matches both file and directory names, 
while the directory completion character only matches directory names.
If file completion is used on any of the built in directory commands (CD, MD or RD) 
then directory completion is assumed.

The completion code deals correctly with file names that contain spaces or other 
special characters by placing quotes around the matching path.
Also, if you back up, then invoke completion from within a line, the text to the 
right of the cursor at the point completion was invoked is discarded.

and it's this option that will let you run commands without the disadvantage of 
using batch files.

With this article you'll also have an attached project sample containing an unit 
(SysCommand.pas) that implements a small component. The best thing you can do it's 
look at the attached sample, anyway here it is a small test sample:

1   var
2     FSysCommand: TSysCommand;
3   
4   begin
5     FSysCommand := TSysCommand.Create(Self);
6     FSysCommand.WhenDone := cwdRemain;
7     FSysCommand.WindowTitle := 'This is a test';
8     FSysCommand.BkColor := cclBtWhite;
9     FSysCommand.FgColor := cclLtRed;
10    FSysCommand.CmdsList.Add('echo Now I will list your windows directory files.');
11    FSysCommand.CmdsList.Add('pause');
12    FSysCommand.CmdsList.Add('dir "c:\windows\*.*" /s');
13    FSysCommand.Execute;
14  
15    as you can see, it's easy and simple to run a batch of commands throught the
16      Command Prompt.
17  
18    = = SysCommand.pas = =
19  
20  unit SysCommand;
21  // by Fernando J.A. Silva (magico@galaxycorp.com)   2001/08/24
22  
23  interface
24  uses
25    Classes;
26  
27  type
28    TCmdWhenDone = (
29      cwdClose { /C or /R },
30        // Carries out the command specified by string and then terminates
31      cwdRemain { /K } // Carries out the command specified by string but remains
32      );
33  
34    TCmdAutoRunCmds = (
35      carDefault,
36      carDisable { /D } // Disable execution of AutoRun commands from registry
37      );
38    // if carDisable was NOT specified, then when the command is launched, it
39    //    looks for the following REG_SZ/REG_EXPAND_SZ registry variables, and if
40    //    either or both are present, they are executed first.
41    //
42    //  HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
43    //     and/or
44    //  HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun
45  
46    TCmdOutputType = (
47      cotANSI { /A },
48        // Causes the output of internal commands to a pipe or file to be ANSI
49      cotUnicode { /U } // Causes the output of internal commands to a pipe or file 
50  to be Unicode
51      );
52  
53    TCmdColor = (cclNone, cclBlack {0}, cclBlue {1}, cclGreen {2}, cclAqua {3}, cclRed
54      {4},
55      cclPurple {5}, cclYellow {6}, cclWhite {7}, cclGray {8}, cclLtBlue {9},
56      cclLtGreen {A}, cclLtAqua {B}, cclLtRed {C}, cclLtPurple {D}, cclLtYellow {E},
57      cclBtWhite {F});
58  
59    TCmdExtensions = (
60      cexDefault,
61      cexON, {/E:ON or /X } // Enable command extensions
62      cexOFF {/E:OFF or /Y } // Disable command extensions
63      );
64    // Command Extensions are enabled by default.  You may also disable extensions
65    //    for a particular invocation by using the cexOFF. You can enable or disable
66    //    extensions for all invocations of CMD.EXE on a machine and/or user logon
67    //    session by setting either or both of the following REG_DWORD values in the
68    //    registry using REGEDT32.EXE:
69    //
70    //  HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\EnableExtensions
71    //     and/or
72    //  HKEY_CURRENT_USER\Software\Microsoft\Command Processor\EnableExtensions
73    //
74    //    to either 0x1 or 0x0.  The user specific setting takes precedence over
75    //    the machine setting.  The command line switches take precedence over the
76    //    registry settings.
77  
78    TSysCommand = class(TComponent)
79    private
80      FOutputType: TCmdOutputType;
81      FAutoRunCmds: TCmdAutoRunCmds;
82      FCmdExtensions: TCmdExtensions;
83      FWhenDone: TCmdWhenDone;
84      FBkColor: TCmdColor;
85      FFgColor: TCmdColor;
86      FWindowTitle: string;
87  
88      FCmdsList: TStringList;
89  
90      function GetParamsString: string;
91      procedure GetInternalCmdsList(var AList: TStringList);
92      function GetCommandsString: string;
93    public
94      constructor Create(AOwner: TComponent); override;
95      destructor Destroy; override;
96      function Execute: Boolean;
97    published
98      property OutputType: TCmdOutputType read FOutputType write FOutputType;
99      property AutoRunCmds: TCmdAutoRunCmds read FAutoRunCmds write FAutoRunCmds;
100     property CmdExtensions: TCmdExtensions read FCmdExtensions write FCmdExtensions;
101     property WhenDone: TCmdWhenDone read FWhenDone write FWhenDone;
102     property BkColor: TCmdColor read FBkColor write FBkColor;
103     property FgColor: TCmdColor read FFgColor write FFgColor;
104     property WindowTitle: string read FWindowTitle write FWindowTitle;
105 
106     property CmdsList: TStringList read FCmdsList write FCmdsList;
107   end;
108 
109 implementation
110 
111 uses
112   Windows,
113   SysUtils;
114 
115 const
116   FStrWhenDone: array[0..1] of string = ('
117   FStrAutoRun: array[0..1] of string = ('', ' /D');
118   FStrOutType: array[0..1] of string = (' /A', ' /U');
119   FStrColors: array[0..16] of string = ('', '0', '1', '2', '3', '4', '5', '6', '7',
120     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
121   FStrUseExt: array[0..2] of string = ('', ' /E:ON', ' /E:OFF');
122 
123 constructor TSysCommand.Create(AOwner: TComponent);
124 begin
125   inherited Create(AOwner);
126   FOutputType := cotANSI;
127   FAutoRunCmds := carDefault;
128   FCmdExtensions := cexDefault;
129   FWhenDone := cwdClose;
130   FBkColor := cclNone;
131   FFgColor := cclNone;
132   WindowTitle := '';
133   FCmdsList := TStringList.Create;
134 end;
135 
136 destructor TSysCommand.Destroy;
137 begin
138   inherited Destroy;
139   FCmdsList.Destroy;
140 end;
141 
142 function TSysCommand.GetParamsString: string;
143 // Returns a string containing the parameters to be passed to 'COMSPEC'
144 begin
145   Result := '';
146   Result := Result + FStrOutType[Ord(FOutputType)];
147   Result := Result + FStrAutoRun[Ord(FAutoRunCmds)];
148   Result := Result + FStrUseExt[Ord(FCmdExtensions)];
149   Result := Result + FStrWhenDone[Ord(FWhenDone)];
150 end;
151 
152 procedure TSysCommand.GetInternalCmdsList(var AList: TStringList);
153 begin
154   // Clean string list
155   AList.Clear;
156   // Insert all commands
157   if FWindowTitle <> '' then
158     AList.Add('TITLE ' + FWindowTitle);
159   if (FBkColor <> cclNone) and (FFgColor <> cclNone) then
160     AList.Add('COLOR ' + FStrColors[Ord(FBkColor)] + FStrColors[Ord(FFgColor)]);
161 end;
162 
163 function TSysCommand.GetCommandsString: string;
164 // Return a string with internal commands and user commands
165 var
166   FList: TStringList;
167   idx: Integer;
168   s: string;
169 
170 begin
171   s := '';
172 
173   // Get internal command list as string
174   FList := TStringList.Create;
175   GetInternalCmdsList(FList);
176   for idx := 0 to FList.Count - 1 do
177     s := s + FList.Strings[idx] + ' && ';
178   // Concat with user commands list
179   for idx := 0 to FCmdsList.Count - 1 do
180     s := s + FCmdsList.Strings[idx] + ' && ';
181   // Delete last &&
182   Delete(s, Length(s) - 3, 4);
183 
184   // Return commands string
185   Result := '"' + s + '"';
186 end;
187 
188 function TSysCommand.Execute: Boolean;
189 var
190   FCmd: string;
191   FExec: string;
192 
193 begin
194   // get name and path of command processor
195   FCmd := GetEnvironmentVariable('COMSPEC');
196 
197   FExec := FCmd + ' ' + GetParamsString + ' ' + GetCommandsString;
198   Result := WinExec(PChar(FExec), SW_SHOWNORMAL) > 31;
199 end;
200 
201 end.


Note: The TSysCommand probably can be extended to support Linux Terminal Mode.
It would be a fine addition and a good reason to use this component in a application.

			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC