Delphi 7: how to execute shell command and check the result?

前端 未结 6 425
一整个雨季
一整个雨季 2021-01-01 08:28

I\'m using Delphi 7 and can\'t predict the target version of Windows.

I need to create a database (probably MySql, but might be something else) and define some table

6条回答
  •  灰色年华
    2021-01-01 08:55

    I saved this from a newsgroup post a long time ago; I don't know who originall wrote it, though.

    This code allows you to run a DOS application and capture it's output in a TMemo. You can then pull what you need out of the memo with a little trial and error parsing the lines.

    procedure TFMainForm.RunDosInMemo(const DosApp: String; AMemo: TRichEdit);
    const
      ReadBuffer = 2400;
    var
      Security : TSecurityAttributes;
      StdInPipeR, StdInPipeW : THandle;
      StdOutPipeR, StdOutPipeW : THandle;
      StartInfo : TStartUpInfo;
      ProcessInfo : TProcessInformation;
      Buffer : PByte;
      BytesAvailable, BytesRead : DWord;
      sDosApp: String;
      sData: RawByteString;
    begin
      sDosApp := DosApp;
      UniqueString(sDosApp);
    
      with Security do begin
        nLength := SizeOf(TSecurityAttributes);
        bInheritHandle := True;
        lpSecurityDescriptor := nil;
      end;
    
      if CreatePipe(StdInPipeR, StdInPipeW, @Security, 0) then
      try
    
        SetHandleInformation(StdInPipeW, HANDLE_FLAG_INHERIT, 0);
        if CreatePipe(StdOutPipeR, StdOutPipeW, @Security, 0) then
        try
          SetHandleInformation(StdOutPipeR, HANDLE_FLAG_INHERIT, 0);
          GetMem(Buffer, ReadBuffer);
          try
            ZeroMemory(@StartInfo, SizeOf(StartInfo));
            StartInfo.cb := SizeOf(StartInfo);
            StartInfo.hStdOutput := StdOutPipeW;
            StartInfo.hStdInput := StdInPipeR;
            StartInfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
            StartInfo.wShowWindow := SW_HIDE;
    
            if CreateProcess(nil, 
                             PChar(sDosApp), 
                             nil, 
                             nil, 
                             True, 
                             NORMAL_PRIORITY_CLASS, 
                             nil, 
                             nil, 
                             StartInfo, 
                             ProcessInfo) then
              try
                while WaitForSingleObject(ProcessInfo.hProcess, 500) <> WAIT_TIMEOUT do
                  Application.ProcessMessages;
                while PeekNamedPipe(StdOutPipeR, nil, 0, nil, BytesAvailable, nil) do 
                begin
                  if BytesAvailable < 1 then 
                    Break;
                  if BytesAvailable > ReadBuffer then 
                    BytesAvailable := ReadBuffer;
                  if not ReadFile(StdOutPipeR, 
                                  Buffer[0], 
                                  BytesAvailable, 
                                  BytesRead, 
                                  nil) then 
                    Break;
                  SetString(sData, PAnsiChar(Buffer), BytesRead);
                  // assign an appropriate codepage for the output data:
                  // 0 for default Ansi, 1252 or 20157 for ASCII, 1200 for 
                  // Unicode, etc...
                  SetCodePage(sData, ...);
                  // this is faster and more efficient than reading/writing the 
                  // Text property directly...
                  AMemo.SelStart := AMemo.GetTextLen;
                  AMemo.SelLength := 0;
                  AMemo.SelText := sData;
                end;
              finally
                CloseHandle(ProcessInfo.hThread);
                CloseHandle(ProcessInfo.hProcess);
              end;
          finally
            FreeMem(Buffer);
          end;
        finally
          CloseHandle(StdOutPipeR);
          CloseHandle(StdOutPipeW);
        end;
      finally
        CloseHandle(StdInPipeR);
        CloseHandle(StdInPipeW);
      end;
    end;
    

提交回复
热议问题