用线程调用外部程序的时候,运行时报错Access Violation at address 0045E712 in  module 'a.exe'.
Read of address 00000000.帮助上说;EAccessViolation is raised when an applicationDereferences a nil (Delphi) or NULL (C++) pointer.
Writes to memory reserved for executable code.
Attempts to access a memory address for which there is no virtual memory allocated to the application.我觉得是没有给程序分配内存
大家看看该怎么办

解决方案 »

  1.   

    Unit1
    procedure TForm1.IntegratClick(Sender: TObject);
    Const
      Prog = 'a.exe';
      ProgEnd = 'The termination of Preint.';
    Var
      ExitCode : Dword;
      FileName,Result: String;
      Restr : TStrings;begin
      ExitCode := 0;
      FileName := XmPath + '\' + XmName;
      CommandLine := Prog + ' ' + '"' + FileName + '"' ;
      Dir := XmPath;
      If (Dir = '') then
      begin
        save1Click(Sender);
        Dir :=XmPath;
      End;
      MemoDisplay.Clear ;  Mediavar.Clear;
      MediaVar.Strings[0] := CommandLine;
      MediaVar.Strings[1] := Dir;
      RunDosThread.Resume ;
      MediaVar.Free ;  Result := 'Blank testing';
      Restr := TStringList.Create ;
      Restr.Add(Result);
      MemoDisplay.Lines := Restr;
      MemoDisPlay.Lines.Append(ProgEnd);
      MemoDisPlay.Lines.Append('');
      Restr.Free ;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
        MemoDisplay.Clear;
        MemoDisplay.ReadOnly := True;
          RunDosThread:=TRunDosThread.Create(True);
    end;
    ==========================
    Unit2procedure TRunDosThread.Execute;
    var
      Cmdl,dr:string;
      ExitCd:Dword;
    begin
       cmdl := Form1.MediaVar[0];
       dr   := Form1.MediaVar[1];
       ExitCd :=0;
       { Place thread code here }
       If(Terminated)then exit;   RunDOS(Cmdl, Dr, ExitCd);
    end;procedure TRunDosThread.CheckResult (b: Boolean);
    begin
      if not b then
        Raise Exception.Create(SysErrorMessage(GetLastError));
    end;function  TRunDosThread.RunDOS (const  CommandLine,Dir: String; ExitCode :Dword): String;
    var
      HRead,HWrite:THandle;
      StartInfo:TStartupInfo;
      ProceInfo:TProcessInformation;
      b:Boolean;
      sa:TSecurityAttributes;
      inS:THandleStream;
      sRet:TStrings;
    begin
      Result := '';
      FillChar(sa,sizeof(sa),0);
      //设置允许继承,否则在NT和2000下无法取得输出结果
      sa.nLength := sizeof(sa);
      sa.bInheritHandle := True;
      sa.lpSecurityDescriptor := nil;
      b := CreatePipe(HRead,HWrite,@sa,0);
      CheckResult(b);  FillChar(StartInfo,SizeOf(StartInfo),0);
      StartInfo.cb := SizeOf(StartInfo);
      StartInfo.wShowWindow := SW_HIDE;
      //使用指定的句柄作为标准输入输出的文件句柄,使用指定的显示方式
      StartInfo.dwFlags := STARTF_USESTDHANDLES+STARTF_USESHOWWINDOW;
      StartInfo.hStdError := HWrite;
      StartInfo.hStdInput := GetStdHandle(STD_INPUT_HANDLE);//HRead;
      StartInfo.hStdOutput := HWrite;  b := CreateProcess(Nil,//lpApplicationName: PChar
            PChar(CommandLine), //lpCommandLine: PChar
            nil, //lpProcessAttributes: PSecurityAttributes
            nil, //lpThreadAttributes: PSecurityAttributes
            True, //bInheritHandles: BOOL
            CREATE_NEW_CONSOLE,
            nil,
            PChar(Dir),
            StartInfo,
            ProceInfo );  CheckResult(b);
      WaitForSingleObject(ProceInfo.hProcess,INFINITE);
      GetExitCodeProcess(ProceInfo.hProcess,ExitCode);
    //   GetExitCodeProcess(ProceInfo.hProcess,ExitCode);
      inS := THandleStream.Create(HRead);
      if inS.Size>0 then
      begin
        sRet := TStringList.Create;
        sRet.LoadFromStream(inS);
        Result := sRet.Text;
        sRet.Free;
      end;
      inS.Free;
      CloseHandle(HRead);
      CloseHandle(HWrite);
    end;
      

  2.   

    不使用线程就可以
    但是别人推荐使用
    http://community.csdn.net/Expert/topic/4502/4502833.xml?temp=.4399378