Форум: "Основная";
Текущий архив: 2007.05.13;
Скачать: [xml.tar.bz2];
ВнизУправление другой программой Найти похожие ветки
← →
Леонид (2007-03-14 17:39) [0]Помогите: Я из формы Делфи запускаю DOS-программу, которая требует ввести имя файла, затем Ентер, имя второго файла, Ентер... На этом она закрывается. Как сделать автоматический ввод имен файлов в DOS-программу и нажатие клвиши Ентер, и по завершении DOS-программы передать управление обратно Делфи?
← →
Desdechado © (2007-03-14 17:58) [1]ShellExecute
Если эта программа поддерживает ввод из стандарного потока ввода, то в командной строке пишешьproga.exe << имя1 имя2
← →
Леонид (2007-03-14 20:41) [2]Не помогло надо сделать програмно, так чтобы proga.exe думала что набирают на клавиатуре
← →
zdm © (2007-03-14 20:45) [3]а можно глупый вопрос? а чо та прога делает? может её проще реализовать в коде твоей-же делфевой проги?
← →
Леонид (2007-03-14 20:52) [4]К сожелению код написан на фортране 77, и исходников нет, реализовать с помощью Delphi не возможно, программа совершает термо-гидравлический расчет имользуя множество алгоритмов, а также совершаеь расчет систем диф уравнений.
← →
RASkov (2007-03-14 20:59) [5]> [4] Леонид (14.03.07 20:52)
Если она(программа на фортране) не понимает параметров(ключей) командной строки, то наверное нельзя....
← →
zdm © (2007-03-14 21:01) [6]
> Леонид (14.03.07 20:52) [4]
такая терада даже профи собъет с ног ;) была-б она виндовая, с конкретным имененем "окна" , можно было-бы по имени окна отловить(FindWindow) , а досковую.... тока [1].. А мож тада просто написать отдельную прогу с индивидуальным именем, которая вызовет методом ShellExecute или WinExec её, но вызвать её будет твоя прога. Т.е твоя прога вызывает прогу которая вызовет досовскую прогу, но её ты во всяком случае сможешь контролировать
← →
zdm © (2007-03-14 21:02) [7]а по моему рильная мысля
← →
Desdechado © (2007-03-14 21:04) [8]> Не помогло
Как делал?
← →
zdm © (2007-03-14 21:06) [9]
> Desdechado © (14.03.07 21:04) [8]
> > Не помоглоКак делал?
ни как, просто пока писал мысли в слух шли, может и не реализуемо, ща попробую, если получится, обязательно отпишусь... хотя мож и бред всё это.
← →
zdm © (2007-03-14 21:08) [10]пока не начал изврощаться, АВТОР, а у досовской "формы" есть заголовок?
← →
zdm © (2007-03-14 21:10) [11]я просто подумал, а вот это уже не бред, что вызывается-то не просто "cmd" с запущеной прогой, а рильная прога, значит её окно имеет имя, а его можжно отловить
← →
Servelat © (2007-03-14 22:18) [12]> proga.exe << имя1 имя2
Чего-то я не пойму как "<<" работает, у меня его тот же телнет не понимает. По задумке, в телнет должна передаватся команда quit :)
C:\>telnet << quit
Непредвиденное появление: <<.
Сам я при отладке собственных досовских прог, чтобы не вбивать данные вручную всегда пользовался вариантом с одним "<" :) Так работает:C:\>telnet < 1.txt
Добро пожаловать в программу-клиент Microsoft Telnet
Символ переключения режима: "CTRL+]"
Microsoft Telnet> Microsoft Telnet>
C:\>
где в файле 1.txt написано просто одно слово "quit", телнет запустился и благополучно закрылся.
В случае [0] можно опять же создать текстовый файл с именами нужных двух файлов, которые должны быть переданы программе, и вызывать тем же ShellExecute.
Можно еще попробовать создать два временных файла (CreateFile + FILE_ATTRIBUTE_TEMPORARY or FILE_FLAG_DELETE_ON_CLOSE) (смысл в том, чтобы файлы по возможности были в оперативе и не сохранялись на диск), которые передать в качестве TStartupInfo.hStdOutput и TStartupInfo.hStdInput в функцию CreateProcess. А дальше читать из одного и писать в другой нужные тебе команды, имена файлов, или чего там нужно этой досовской проге. Этот вариант значительно сложнее в реализации, но (ИМХО) более гибок, заодно можно поймать что там выводит эта прога в консоль.
PS
> Я из формы Делфи запускаю DOS-программу
Довольно странная фраза, как это вы из формы что-то запускаете... :)
← →
S@shka © (2007-03-14 23:26) [13]Если я правильно понял смысл вопроса ... то вот что тебе поможет....
Консоль, которая поможет управлять вводом/выводом
unit admin;
interface
uses Windows, Classes, syncobjs, SysUtils;
type
TConsole=class(TThread)
private
FWnd:THandle;
FMsg:Cardinal;
pi:TProcessInformation;
ChildStdInWr,ChildStdoutRd:THandle;
FCS:TCriticalSection;
FCommandList:TStringList;
procedure CreateConsole;
protected
procedure Execute;override;
public
constructor Create(AWnd:THandle; AMsg:Cardinal);reintroduce;
procedure AddCommand(s:string);
destructor Destroy; override;
end;
implementation
{ TConsole }
constructor TConsole.Create(AWnd:THandle; AMsg:Cardinal);
begin
FWnd:=AWnd;
FMsg:=AMsg;
FCS:=TCriticalSection.Create;
FCommandList:=TStringList.Create;
FreeOnTerminate := True;
inherited Create(false);
Log ("================= Started Ok. ====================",0);
end;
procedure TConsole.AddCommand(s:string);
begin
FCS.Enter;
try
FCommandList.Add(s+#13#10);
finally
FCS.Leave;
end;
end;
procedure TConsole.Execute;
var
buffer:Pointer;
bytesRead:DWORD;
begin
CreateConsole;
while not Terminated do
begin
sleep(200);
PeekNamedPipe(ChildStdoutRd,nil,0,nil,@bytesRead,nil);
//Read from
if bytesRead>0 then
begin
GetMem(buffer,bytesRead+1);
try
if not ReadFile(ChildStdoutRd,buffer^,bytesRead,bytesRead,nil) then
RaiseLastOSError;
PChar(buffer)[bytesRead]:=#0;
//Log (PChar (buffer),1);
SendMessage(FWnd,FMsg,Integer(PChar(buffer)),0);
finally
FreeMem(buffer);
end;
end;
//Write to
FCS.Enter;
try
while FCommandList.Count>0 do
begin
// Log (FCommandList[0],0);
if not WriteFile(ChildStdinWr,PChar(FCommandList[0])^,Length(FCommandList[0]),bytesRead ,nil) then
RaiseLastOSError;
FCommandList.Delete(0);
end;
finally
FCS.Leave;
end;
end; // while
end;
procedure TConsole.CreateConsole;
var
sa:TSecurityAttributes;
si:TStartupInfo;
// pi:TProcessInformation;
comSpec:PChar;
bufLen:DWORD;
ChildStdoutWr, ChildStdInRd, Tmp1, Tmp2:THandle;
begin
sa.nLength:=sizeof(TSecurityAttributes);
sa.bInheritHandle:=true;
sa.lpSecurityDescriptor:=nil;
if not CreatePipe(ChildStdoutRd, ChildStdoutWr, @sa, 0) then
RaiseLastOSError;
if not CreatePipe(ChildStdinRd, ChildStdinWr, @sa, 0) then
RaiseLastOSError;
if not DuplicateHandle(GetCurrentProcess(), ChildStdoutRd, GetCurrentProcess(), @Tmp1, 0, False, DUPLICATE_SAME_ACCESS) then
RaiseLastOSError;
if not DuplicateHandle(GetCurrentProcess(), ChildStdinWr, GetCurrentProcess(), @Tmp2, 0, False, DUPLICATE_SAME_ACCESS) then
RaiseLastOSError;
CloseHandle(ChildStdoutRd);
CloseHandle(ChildStdinWr);
ChildStdoutRd:=Tmp1;
ChildStdinWr:=Tmp2;
bufLen:=GetEnvironmentVariable("ComSpec",nil,0);
GetMem(comSpec,bufLen);
GetEnvironmentVariable("ComSpec",comSpec,bufLen);
GetStartupInfo(si);
si.cb:=sizeof(TStartupInfo);
si.dwFlags:=STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
si.hStdInput:=ChildStdInRd;
si.hStdOutput:=ChildStdOutWr;
si.hStdError:=ChildStdOutWr;
si.wShowWindow:=SW_HIDE;
if not CreateProcess(nil,comSpec,nil,nil,true,CREATE_NEW_CONSOLE,nil,nil,si,pi) then
RaiseLastOSError;
end;
destructor TConsole.Destroy;
begin
FCommandList.Free;
FCS.Free;
if not TerminateProcess(PI.hProcess,0) then RaiseLastOSError;
end;
end.
← →
S@shka © (2007-03-14 23:30) [14]var
C : TConsole;
...
c := TConsole.Create(Handle,WM_USER+1);
C.AddCommand ("MyCommand.exer"); // Ну вообщем что хочешь выполнить
Плюс у тебя есть
procedure TFrom1.MyConsoleAnswer (var T : TMessage); message WM_USER + 1;
...
procedure TFrom1.MyConsoleAnswer (var T : TMessage);
var
P : PChar;
t : String;
begin
p:=PChar(Msg.wParam);
OemToCharBuff(p,p,length(p));
// P - содержит то что написала твоя прога в буфер ввода/вывода
end;
← →
Леонид (2007-03-15 22:17) [15]Servelat - Спосибо первый метод сработал, в принцепе для этого проекта больше не надо.
S@shka © - Данный метод опробую но надругой подобной задачи.
ВСЕМ СПОСИБО ВЫРУЧИЛИ.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2007.05.13;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.046 c