Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.041 c
1-1173956279
ANikolay
2007-03-15 13:57
2007.05.13
Использование TidHTTP в OLE-объекте


15-1176723406
Yaros-hoi
2007-04-16 15:36
2007.05.13
Запрос по дате


4-1166032651
P@r@zit
2006-12-13 20:57
2007.05.13
Информатика


11-1159283659
Моторокер
2006-09-26 19:14
2007.05.13
Int2Str vs. IntToStr


2-1177092211
likenoother
2007-04-20 22:03
2007.05.13
цвет пикселя





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский