如何在应用程序中调用db2cmd,实现自动输入命令并读取输出内容?

时间:2022-09-02 15:51:05
各位好,我写了一个windows程序调用db2cmd.exe,通过程序对其输入输出,程序中使用管道函数createpipe+createprocess;
结果弹出db2cmd DOS窗口,但程序发出命令后db2cmd无响应,也无法读取他的输出内容;但是调用其他程序如cmd.exe等可以正常输入输出。
请高手帮忙解释这是什么原因,多谢了!

3 个解决方案

#1


你的代码是什么,执行什么操作

#2


谢谢斑竹关照!这是一段用delphi写的程序,想通过外部程序控制db2cmd输入,并读取输出。


ReadPipeIn, WritePipeIn,ReadPipeOut, WritePipeOut: THandle;

procedure Createpipe;
var 
  Security: TSecurityAttributes;
  start: TStartUpInfo;
begin
  Security.nlength := SizeOf(TSecurityAttributes);
  Security.binherithandle := true;
  Security.lpsecuritydescriptor := nil;
  {创建一个命名管道用来捕获console程序的输出}
  Createpipe(ReadPipeIn, WritePipeIn, @Security, 0);
  Createpipe(ReadPipeOut, WritePipeOut, @Security, 0);

  FillChar(Start, Sizeof(Start), #0);
  CreateProcess(nil,PChar('db2cmd.exe'),@Security,@Security,true,NORMAL_PRIORITY_CLASS,nil,nil,start,ProcessInf); 
end;
{向console程序输入}
procedure WriteToPipe(Pipe: THandle; Value: string);
var
  len: integer;
  BytesWrite: DWord;
  Buffer: PChar;
begin
  len := Length(Value) + 2;
  Buffer := PChar(Value + #13#10);
  WriteFile(Pipe, Buffer[0], len, BytesWrite, nil);
end;
{从console程序读取输出}
function ReadFromPipe(Pipe: THandle): string;
var
  Buffer: PChar;
  BytesRead: DWord;
begin
   Result := '';
   if GetFileSize(Pipe, nil) = 0 then Exit;
   Buffer := AllocMem(ReadBuffer + 1);
   repeat
       BytesRead := 0;
       ReadFile(Pipe, Buffer[0],
       ReadBuffer, BytesRead, nil);
        if BytesRead > 0 then begin
            Buffer[BytesRead] := #0;
            OemToAnsi(Buffer, Buffer);
            Result := Result+string(Buffer);
        end;
   until (GetFileSize(Pipe, nil) <= 0);
   FreeMem(Buffer);
end;

#3


测试了一下,貌似不行,你可以将要运行的命令写入BAT中,运行DB2命令
示例:
db2 connect to bras user bras using 888888 
db2 "export to D:\sqlldr\data\20091207\fhdgckfhz.del of del select * from BRAS.FHDGCKFHZ" 
db2 "export to D:\sqlldr\data\20091207\fhdgckmxz.del of del select * from BRAS.FHDGCKMXZ" 
db2 "export to D:\sqlldr\data\20091207\fhdkfhz.del of del select * from BRAS.FHDKFHZ" 
db2 connect reset 

这些写成一个bat文件,XXX.bat 

然后在命令行里直接执行 

db2cmd -i XXX.bat 

类似于MYSQL的命令行

#1


你的代码是什么,执行什么操作

#2


谢谢斑竹关照!这是一段用delphi写的程序,想通过外部程序控制db2cmd输入,并读取输出。


ReadPipeIn, WritePipeIn,ReadPipeOut, WritePipeOut: THandle;

procedure Createpipe;
var 
  Security: TSecurityAttributes;
  start: TStartUpInfo;
begin
  Security.nlength := SizeOf(TSecurityAttributes);
  Security.binherithandle := true;
  Security.lpsecuritydescriptor := nil;
  {创建一个命名管道用来捕获console程序的输出}
  Createpipe(ReadPipeIn, WritePipeIn, @Security, 0);
  Createpipe(ReadPipeOut, WritePipeOut, @Security, 0);

  FillChar(Start, Sizeof(Start), #0);
  CreateProcess(nil,PChar('db2cmd.exe'),@Security,@Security,true,NORMAL_PRIORITY_CLASS,nil,nil,start,ProcessInf); 
end;
{向console程序输入}
procedure WriteToPipe(Pipe: THandle; Value: string);
var
  len: integer;
  BytesWrite: DWord;
  Buffer: PChar;
begin
  len := Length(Value) + 2;
  Buffer := PChar(Value + #13#10);
  WriteFile(Pipe, Buffer[0], len, BytesWrite, nil);
end;
{从console程序读取输出}
function ReadFromPipe(Pipe: THandle): string;
var
  Buffer: PChar;
  BytesRead: DWord;
begin
   Result := '';
   if GetFileSize(Pipe, nil) = 0 then Exit;
   Buffer := AllocMem(ReadBuffer + 1);
   repeat
       BytesRead := 0;
       ReadFile(Pipe, Buffer[0],
       ReadBuffer, BytesRead, nil);
        if BytesRead > 0 then begin
            Buffer[BytesRead] := #0;
            OemToAnsi(Buffer, Buffer);
            Result := Result+string(Buffer);
        end;
   until (GetFileSize(Pipe, nil) <= 0);
   FreeMem(Buffer);
end;

#3


测试了一下,貌似不行,你可以将要运行的命令写入BAT中,运行DB2命令
示例:
db2 connect to bras user bras using 888888 
db2 "export to D:\sqlldr\data\20091207\fhdgckfhz.del of del select * from BRAS.FHDGCKFHZ" 
db2 "export to D:\sqlldr\data\20091207\fhdgckmxz.del of del select * from BRAS.FHDGCKMXZ" 
db2 "export to D:\sqlldr\data\20091207\fhdkfhz.del of del select * from BRAS.FHDKFHZ" 
db2 connect reset 

这些写成一个bat文件,XXX.bat 

然后在命令行里直接执行 

db2cmd -i XXX.bat 

类似于MYSQL的命令行