这个程序为什么不能在Win2000下正确执行?请各位赐教!(200分)

  • 主题发起人 主题发起人 delred
  • 开始时间 开始时间
D

delred

Unregistered / Unconfirmed
GUEST, unregistred user!
unit MainFrm;

interface

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

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

var
; Form1: TForm1;

implementation

{$R *.dfm}

{---------------------------CreateDOSProcessRedirected--------------------------
;Description ; ;: executes a (DOS!) app defined in the CommandLine parameter
; ; ; ; ; ; ; ; ; redirected to take input from InputFile (optional) and give
; ; ; ; ; ; ; ; ; output to OutputFile
;Result ; ; ; ; : True on success
;Parameters ; ; : CommandLine : the command line for app, including full path
; ; ; ; ; ; ; ; ; InputFile ; : the ascii file where from the app takes input,
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;empty if no input needed/required.
; ; ; ; ; ; ; ; ; OutputFile ;: the ascii file to which the output is redirected
; ; ; ; ; ; ; ; ; ErrMsg ; ; ;: additional error message string. Can be empty
;Error checking : YES
;Target ; ; ; ; : Delphi 2, 3, 4, 6
;Author ; ; ; ; : Theodoros Bebekis, email bebekis@otenet.gr
;Notes ; ; ; ; ;:
;Example call ; : CreateDOSProcessRedirected('C:/MyDOSApp.exe',
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;'C:/InputPut.txt',
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;'C:/OutPut.txt',
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;'Please, record this message')
-------------------------------------------------------------------------------}
function CreateDOSProcessRedirected(const CommandLine, InputFile, OutputFile,
; ;ErrMsg :string): boolean;
const
; ROUTINE_ID = '[function: CreateDOSProcessRedirected]';
var
; OldCursor ; ; : TCursor;
; pCommandLine ;: array[0..MAX_PATH] of char;
; pInputFile,
; pOutPutFile ; : array[0..MAX_PATH] of char;
; StartupInfo ; : TStartupInfo;
; ProcessInfo ; : TProcessInformation;
; SecAtrrs ; ; ;: TSecurityAttributes;
; hAppProcess,
; hAppThread,
; hInputFile,
; hOutputFile ; : THandle;
begin
; Result := FALSE;

; { check for InputFile existence }
; if (InputFile <> '') and (not FileExists(InputFile)) then
; ; raise Exception.CreateFmt(ROUTINE_ID + #10 + #10 +
; ; ; ;'Input file * %s *' + #10 +
; ; ; ;'does not exist' + #10 + #10 +
; ; ; ;ErrMsg, [InputFile]);

; hAppProcess := 0;
; hAppThread := 0;
; hInputFile := 0;
; hOutputFile := 0;

; { save the cursor }
; OldCursor ; ; := Screen.Cursor;
; Screen.Cursor := crHourglass;

; try
; ; { copy the parameter Pascal strings to null terminated strings }
; ; StrPCopy(pCommandLine, CommandLine);
; ; StrPCopy(pInputFile, InputFile);
; ; StrPCopy(pOutPutFile, OutputFile);

; ; { prepare SecAtrrs structure for the CreateFile calls. ;This SecAttrs
; ; ; structure is needed in this case because we want the returned handle to
; ; ; be inherited by child process. This is true when running under WinNT.
; ; ; As for Win95, the parameter is ignored. }
; ; FillChar(SecAtrrs, SizeOf(SecAtrrs), #0);
; ; SecAtrrs.nLength ; ; ; ; ; ; ;:= SizeOf(SecAtrrs);
; ; SecAtrrs.lpSecurityDescriptor := nil;
; ; SecAtrrs.bInheritHandle ; ; ; := TRUE;

; ; if InputFile <> '' then
; ; begin
; ; ; { create the appropriate handle for the input file }
; ; ; hInputFile := CreateFile(
; ; ; ; ;pInputFile, ; ; ; ; ; ; ; ; ; ; ; ; ;{ pointer to name of the file }
; ; ; ; ;GENERIC_READ or GENERIC_WRITE, ; ; ; { access (read-write) mode }
; ; ; ; ;FILE_SHARE_READ or FILE_SHARE_WRITE, { share mode }
; ; ; ; ;@SecAtrrs, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to security attributes }
; ; ; ; ;OPEN_ALWAYS, ; ; ; ; ; ; ; ; ; ; ; ; { how to create }
; ; ; ; ;FILE_ATTRIBUTE_NORMAL
; ; ; ; ;or FILE_FLAG_WRITE_THROUGH, ; ; ; ; ;{ file attributes }
; ; ; ; ;0); ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; { handle to file with attrs to copy }

; ; ; { is hInputFile a valid handle? }
; ; ; if hInputFile = INVALID_HANDLE_VALUE then
; ; ; ; raise Exception.CreateFmt(ROUTINE_ID + #10 + ;#10 +
; ; ; ; ; ;'WinApi function CreateFile returned an invalid handle value' + #10 +
; ; ; ; ; ;'for the input file * %s *' + #10 + #10 +
; ; ; ; ; ; ErrMsg, [InputFile]);
; ; end else
; ; ; { we aren't using an input file }
; ; ; hInputFile := 0;

; ; { create the appropriate handle for the output file }
; ; hOutputFile := CreateFile(
; ; ; ;pOutPutFile, ; ; ; ; ; ; ; ; ; ; ; ; { pointer to name of the file }
; ; ; ;GENERIC_READ or GENERIC_WRITE, ; ; ; { access (read-write) mode }
; ; ; ;FILE_SHARE_READ or FILE_SHARE_WRITE, { share mode }
; ; ; ;@SecAtrrs, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to security attributes }
; ; ; ;CREATE_ALWAYS, ; ; ; ; ; ; ; ; ; ; ; { how to create }
; ; ; ;FILE_ATTRIBUTE_NORMAL
; ; ; ;or FILE_FLAG_WRITE_THROUGH, ; ; ; ; ;{ file attributes }
; ; ; ;0 ); ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; { handle to file with attrs to copy }

; ; { is hOutputFile a valid handle? }
; ; if hOutputFile = INVALID_HANDLE_VALUE then
; ; ; raise Exception.CreateFmt(ROUTINE_ID + #10 + ;#10 +
; ; ; ; ;'WinApi function CreateFile returned an invalid handle value' ;+ #10 +
; ; ; ; ;'for the output file * %s *' + #10 + #10 +
; ; ; ; ;ErrMsg, [OutputFile]);

; ; { prepare StartupInfo structure }
; ; FillChar(StartupInfo, SizeOf(StartupInfo), #0);
; ; StartupInfo.cb ; ; ; ; ;:= SizeOf(StartupInfo);
; ; StartupInfo.dwFlags ; ; := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
; ; StartupInfo.wShowWindow := SW_HIDE;
; ; StartupInfo.hStdOutput ;:= hOutputFile;
; ; StartupInfo.hStdInput ; := hInputFile;

; ; { create the app }
; ; Result := CreateProcess(
; ; ; ;NIL, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to name of executable module }
; ; ; ;pCommandLine, ; ; ; ; ; ; ; ; ;{ pointer to command line string }
; ; ; ;NIL, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to process security attributes }
; ; ; ;NIL, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to thread security attributes }
; ; ; ;TRUE, ; ; ; ; ; ; ; ; ; ; ; ; ;{ handle inheritance flag }
; ; ; ;HIGH_PRIORITY_CLASS, ; ; ; ; ; { creation flags }
; ; ; ;NIL, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to new environment block }
; ; ; ;NIL, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to current directory name }
; ; ; ;StartupInfo, ; ; ; ; ; ; ; ; ; { pointer to STARTUPINFO }
; ; ; ;ProcessInfo); ; ; ; ; ; ; ; ; ;{ pointer to PROCESS_INF }

; ; { wait for the app to finish its job and take the handles to free them later }
; ; if Result then
; ; begin
; ; ; WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
; ; ; hAppProcess ;:= ProcessInfo.hProcess;
; ; ; hAppThread ; := ProcessInfo.hThread;
; ; end else
; ; ; raise Exception.Create(ROUTINE_ID + #10 + ;#10 +
; ; ; ; ;'Function failure' ;+ #10 + ;#10 + ErrMsg);

; finally
; ; { close the handles
; ; ; Kernel objects, like the process and the files we created in this case,
; ; ; are maintained by a usage count.
; ; ; So, for cleaning up purposes we have to close the handles
; ; ; to inform the system that we don't need the objects anymore }
; ; if hOutputFile <> 0 then
; ; ; CloseHandle(hOutputFile);
; ; if hInputFile <> 0 then
; ; ; CloseHandle(hInputFile);
; ; if hAppThread <> 0 then
; ; ; CloseHandle(hAppThread);
; ; if hAppProcess <> 0 then
; ; ; CloseHandle(hAppProcess);
; ; { restore the old cursor }
; ; Screen.Cursor:= OldCursor;
; end;
end; ; ;{ CreateDOSProcessRedirected }

procedure TForm1.Button1Click(Sender: TObject);
begin
; CreateDOSProcessRedirected('test.exe','','temp.dat','');
end;

end.
 
这是一个有关DOS重定向的问题,在Win98下可以正确执行。但是在Win2000下只能生成一个
空白文件不能捕捉到应用程序的输出结果。
关键函数是CreateDOSProcessRedirected。
本人对正确回答此问题者将以200分重谢。
 
我试了一下,可以呀!不过我不是用你的,是从别的地方拷的,你看看不什么不同
我用rar.exe试的。
function CreateDOSProcessRedirected(const CommandLine, InputFile, OutputFile, ErrMsg :string):boolean;
const
; ROUTINE_ID = '[function: CreateDOSProcessRedirected ]';
var
; OldCursor ; ; : TCursor;
; pCommandLine ;: array[0..MAX_PATH] of char;
; pInputFile,
; pOutPutFile ; : array[0..MAX_PATH] of char;
; StartupInfo ; : TStartupInfo;
; ProcessInfo ; : TProcessInformation;
; SecAtrrs ; ; ;: TSecurityAttributes;
; hAppProcess,
; hAppThread,
; hInputFile,
; hOutputFile ; : THandle;
begin

; Result := False;

; { check for InputFile existence }
; if not FileExists(InputFile)
; then
; ; raise Exception.CreateFmt(ROUTINE_ID ; ; ; ; ;+ #10 + ;#10 +
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 'Input file * %s *' + #10 +
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 'does not exist' ; ;+ #10 + ;#10 +
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ErrMsg, [InputFile]);

; { save the cursor }
; OldCursor ; ; := Screen.Cursor;
; Screen.Cursor := crHourglass;

; { copy the parameter Pascal strings to null terminated strings }
; StrPCopy(pCommandLine, CommandLine);
; StrPCopy(pInputFile, InputFile);
; StrPCopy(pOutPutFile, OutputFile);

; TRY

; ; { prepare SecAtrrs structure for the CreateFile calls
; ; ; This SecAttrs structure is needed in this case because
; ; ; we want the returned handle can be inherited by child process
; ; ; This is true when running under WinNT.
; ; ; As for Win95 the documentation is quite ambiguous }
; ; FillChar(SecAtrrs, SizeOf(SecAtrrs), #0);
; ; SecAtrrs.nLength ; ; ; ; ; ; ;:= SizeOf(SecAtrrs);
; ; SecAtrrs.lpSecurityDescriptor := nil;
; ; SecAtrrs.bInheritHandle ; ; ; := True;

; ; { create the appropriate handle for the input file }
; ; hInputFile := CreateFile(
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;pInputFile, ; ; ; ; ; ; ; ; ; ; ; ; ; ;{ pointer to name of the file }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;GENERIC_READ or GENERIC_WRITE, ; ; ; ; { access (read-write) mode }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;FILE_SHARE_READ or FILE_SHARE_WRITE, ; { share mode }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;@SecAtrrs, ; ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to security attributes }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;OPEN_ALWAYS, ; ; ; ; ; ; ; ; ; ; ; ; ; { how to create }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;FILE_ATTRIBUTE_TEMPORARY, ; ; ; ; ; ; ;{ file attributes }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;0 ); ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; { handle to file with attributes to copy }


; ; { is hInputFile a valid handle? }
; ; if hInputFile = INVALID_HANDLE_VALUE
; ; then
; ; ; raise Exception.CreateFmt(ROUTINE_ID ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; + #10 + ;#10 +
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 'WinApi function CreateFile returned an invalid handle value' ;+ #10 +
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 'for the input file * %s *' ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;+ #10 + #10 +
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ErrMsg, [InputFile]);

; ; { create the appropriate handle for the output file }
; ; hOutputFile := CreateFile(
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; pOutPutFile, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to name of the file }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; GENERIC_READ or GENERIC_WRITE, ; ; ; ; { access (read-write) mode }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; FILE_SHARE_READ or FILE_SHARE_WRITE, ; { share mode }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; @SecAtrrs, ; ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to security attributes }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; CREATE_ALWAYS, ; ; ; ; ; ; ; ; ; ; ; ; { how to create }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; FILE_ATTRIBUTE_TEMPORARY, ; ; ; ; ; ; ;{ file attributes }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 0 ); ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; { handle to file with attributes to copy }

; ; { is hOutputFile a valid handle? }
; ; if hOutputFile = INVALID_HANDLE_VALUE
; ; then
; ; ; raise Exception.CreateFmt(ROUTINE_ID ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; + #10 + ;#10 +
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 'WinApi function CreateFile returned an invalid handle value' ;+ #10 +
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 'for the output file * %s *' ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; + #10 + #10 +
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ErrMsg, [OutputFile]);

; ; { prepare StartupInfo structure }
; ; FillChar(StartupInfo, SizeOf(StartupInfo), #0);
; ; StartupInfo.cb ; ; ; ; ;:= SizeOf(StartupInfo);
; ; StartupInfo.dwFlags ; ; := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
; ; StartupInfo.wShowWindow := SW_HIDE;
; ; StartupInfo.hStdOutput ;:= hOutputFile;
; ; StartupInfo.hStdInput ; := hInputFile;

; ; { create the app }
; ; Result := CreateProcess(nil, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to name of executable module }
; ; ; ; ; ; ; ; ; ; ; ; ; ; pCommandLine, ; ; ; ; ; ; ; ; ;{ pointer to command line string }
; ; ; ; ; ; ; ; ; ; ; ; ; ; nil, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to process security attributes }
; ; ; ; ; ; ; ; ; ; ; ; ; ; nil, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to thread security attributes }
; ; ; ; ; ; ; ; ; ; ; ; ; ; True, ; ; ; ; ; ; ; ; ; ; ; ; ;{ handle inheritance flag }
; ; ; ; ; ; ; ; ; ; ; ; ; ; CREATE_NEW_CONSOLE or
; ; ; ; ; ; ; ; ; ; ; ; ; ; REALTIME_PRIORITY_CLASS, ; ; ; { creation flags }
; ; ; ; ; ; ; ; ; ; ; ; ; ; nil, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to new environment block }
; ; ; ; ; ; ; ; ; ; ; ; ; ; nil, ; ; ; ; ; ; ; ; ; ; ; ; ; { pointer to current directory name }
; ; ; ; ; ; ; ; ; ; ; ; ; ; StartupInfo, ; ; ; ; ; ; ; ; ; { pointer to STARTUPINFO }
; ; ; ; ; ; ; ; ; ; ; ; ; ; ProcessInfo); ; ; ; ; ; ; ; ; ;{ pointer to PROCESS_INF }

; ; { wait for the app to finish its job and take the handles to free them later }
; ; if Result
; ; then
; ; ; begin
; ; ; ; WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
; ; ; ; hAppProcess ;:= ProcessInfo.hProcess;
; ; ; ; hAppThread ; := ProcessInfo.hThread;
; ; ; end
; ; else
; ; ; raise Exception.Create(ROUTINE_ID ; ; ; ; ;+ #10 + ;#10 +
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;'Function failure' ;+ #10 + ;#10 +
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;ErrMsg);

; FINALLY
; ; { close the handles
; ; ; Kernel objects, like the process and the files we created in this case,
; ; ; are maintained by a usage count.
; ; ; So, for cleaning up purposes we have to close the handles
; ; ; to inform the system that we don't need the objects anymore }
; ; if hOutputFile <> 0 then CloseHandle(hOutputFile);
; ; if hInputFile <> 0 then CloseHandle(hInputFile);
; ; if hAppThread <> 0 then CloseHandle(hAppThread);
; ; if hAppProcess <> 0 then CloseHandle(hAppProcess);
; ; { restore the old cursor }
; ; Screen.Cursor:= OldCursor;
; END;

end;
 
我实话实说,其实我的问题就是一个:用Delphi调用一个叫A51.exe的程序,使它的输出
结果能在Win2000和Win98下正常工作。可是老天爷就是不作美,这个A51.exe执行的时候
总会有这样那样的错误。(而调用其它DOS程序没有问题。)你的程序出现了这样的错误:
一个Message Box弹出,title是:16位MS-DOS出错;内容是:NTVDM出错,The handle
is invalid.意思大致就是这样。
它说的是不是NT的VDM(虚拟DOS机)有问题?到底是什么handle有了问题?只有您正确
回答了我这个问题,200分才能给你。而且请你注意,要按照我的题目给出答案,不要
又给出一个类似的程序,在我的程序上直接修改即可。
但是我不知道怎样才能把A51.exe
才能传给你。
请速答复。
 
zm30,请告诉我你的信箱。我想把A51.exe传到你的信箱里。
请放心,这不会是炸弹,也不会是木马等破坏性的程序,只是
一个DOS程序,功能是把一个汇编程序汇编成obj文件,关生成
相应的LST链表文件。所以,请你告诉我你的信箱。
 
我的邮箱是:qing_h@21cn.com
 
我试过了,确实不行,不过还有一个方法
你可以在A51.exe 参数1 ... 加上 > d:/aaa.txt
执行之后结果就在那个文件里了
 
当使用STARTF_USESTDHANDLES时
1、inputFile为''的时候 hInputFile=0 应该不行,你尝试使用一个存在的inputFile
2、STRATUPINFO.hStdError 也需要赋一个合法的Handle值
 
我已经看到了二位的帖子。
多谢两位的参与。
 
后退
顶部