Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];

Вниз

Редирект консольного вывода   Найти похожие ветки 

 
бывший   (2005-07-20 11:22) [40]

ага, ща изменю приоритет и попробую поменять пайпы местами...


 
Ботвин Дмитрий   (2005-07-20 11:24) [41]

Таймаут на всякий случай увеличь со 100 для начала до 500


 
бывший   (2005-07-20 11:28) [42]

priority = idle - получил наверный дескриптор 6, о котором говорил Digitman. бррр... я запутался.

смена пайпов местами, как я и ожидал - не дала результатов. редиректа нету.


 
Digitman ©   (2005-07-20 11:29) [43]


> бывший   (20.07.05 11:22) [40]
> ага, ща изменю приоритет и попробую поменять пайпы местами...


это уже становится анекдотичным - попробую то, попробую сё, попробую третье , пятое, десятое .. авось, мол, заработает ..

"А Вы их дустом не пробовали ?"(с)

нет бы поставить точку останова в теле поточной ф-ции да пройти пошагово - давным-давно уж причину нашел бы)


 
бывший   (2005-07-20 11:31) [44]

поставил таймаут в 1000 - заработало (not idle приоритет) =) но редиректит реально 20% от всей информации и то только в период инициализации сервера. дальше перестает редиректить =(


 
бывший   (2005-07-20 11:33) [45]

Digitman ©   (20.07.05 11:29) [43]
гы ) да ладно, уже нашли траблу вроде... щас бы понять кто кому и почему мешает...


 
Ботвин Дмитрий   (2005-07-20 11:34) [46]

Тогда Priority := tpIdle засунь в Execute первой строкой.
Быть не может, что бы это вызывало исключение.


 
Digitman ©   (2005-07-20 11:40) [47]


> поставил таймаут в 1000 - заработало


вот дался тебе этот тайм-аут !

не нужны тут никакие тайм-авуты вообще)

стартуешь первый поток, в нем :

- создаешь пайп,
- стартуешь свой сервер,
- стартуешь второй поток c параметром - хэндлом пайпа
- следишь за сервером
- как только сервер завершится (или будет принудительно снят) закрываешь пайп

второй поток, получив параметром хэндл пайпа, просто в цикле читает из пайпа, пока не получит 6-й ошибки


 
бывший   (2005-07-20 11:43) [48]

ага, ща засуну =) самому уже смешно. короче привожу сравнительный анализ:

лог сервера без моего редиректа:

14:34:17:M:Loading address cache ... skipped.
OS version 5.1.2600 (Service Pack 2) platform 2
14:34:18:U: *** ****** win32 console release multithread
14:34:18:M:Config file scripts/defines.scp loaded, 0 sections done.
14:34:18:M:Config file scripts/***.conf loaded, 5 sections done.
14:34:18:M:Spells loaded, max=23702
14:34:18:M:WorldSafeLocs loaded, total=99
14:34:18:M:AreaTable loaded, total=1043
14:34:18:M:WorldMapArea loaded, total=50
14:34:18:M:Talents loaded, total=430
14:34:18:M:Taxinodes loaded, total=76
14:34:18:M:Taxipathes loaded, total=223
14:34:18:M:Taxipathnodes loaded, total=8400
14:34:18:M:EmotesText loaded, total=169
14:34:18:M:Factions loaded, total=175
14:34:18:M:FactionTemplates loaded, total=274
14:34:18:M:DurabilityCosts loaded, total=100
14:34:18:M:MapCache inited, 41 maps.
14:34:18:M:water.dat loaded, 19241 recs.
14:34:18:M:Config file scripts/classes.scp loaded, 58 sections done.
14:34:18:M:classes.scp stat tables loaded.
14:34:18:M:File scripts/items.scp, max 19326, total 11809 sections.
14:34:18:M:Config file scripts/gameobjects.scp loaded, 7608 sections done.
14:34:18:M:Config file scripts/specific_loots.scp loaded, 6 sections done.
14:34:18:M:Config file scripts/loottemplates.scp loaded, 4191 sections done.
14:34:18:M:Config file scripts/creatures_missing_models.scp loaded, 533 sections
done.
14:34:18:M:Config file scripts/creatures.scp loaded, 7887 sections done.
14:34:18:M:File scripts/spellcost.scp, max 117925, total 18352 sections.
14:34:18:M:File scripts/area/area_gm.scp, max 802004, total 215 sections.
14:34:18:M:File scripts/area/area_poi.scp, max 802004, total 69 sections.
14:34:18:M:File scripts/area/area_quest.scp, max 802004, total 7 sections.
14:34:18:M:File scripts/areatriggers.scp, max 802004, total 618 sections.
14:34:18:M:File scripts/quests.scp, max 13131312, total 3234 sections.
14:34:18:M:File scripts/pages.scp, max 2606, total 671 sections.
14:34:18:M:File scripts/qdbtexts.scp, max 13101560, total 5298 sections.
14:34:18:M:File scripts/npctext.scp, max 13101560, total 6726 sections.
14:34:23:M:Patching ... #569 ... #56E ... #568 ... <WS> ... <SN> ... <MOTD> ...
<FCKSTF> ... #57 ... #61 ... #63 ... #62 ... #67 ... done.
14:34:23:M:Saving address cache ... done.
[*** Plugin] v0.6.2 Loading database ...
[*** Plugin] TCLTool : Loading Quests Definitions ...
[*** Plugin] TCLTool : Loading Quests Definitions ... OK
[*** Plugin] TCLTool : Loading NPC Definitions ...
[*** Plugin] TCLTool : Loading NPC Definitions ... OK
[*** Plugin] TCLTool : Compiling NPCs ...
[*** Plugin] TCLTool : Compiling NPCs ... OK
[*** Plugin] Loading frase Database ...
[*** Plugin] Loading frase Database ... OK
[*** Plugin] Loading Spell Database  ...
[*** Plugin] Loading Spell Database ... OK
[*** Plugin] Loading Global configuration  ...
[*** Plugin] Loading Global configuration ... OK
[*** Plugin] Loading User configuration  ...
[*** Plugin] User configuration not found ! (It"s OK)
[*** Plugin] Loading Temporary Pool  ...
[*** Plugin] Temporary Pool not found ! (It"s OK)
[*** Plugin] Loaded OK
14:34:18:M:TCL:Init... done. 726 files loaded.( If error occured ->  )
14:34:18:M:Main thread started.
14:34:18:M:Loading guilds...
14:34:18:M:done.
14:34:18:M:Loading world...
14:34:18:M:Rehashing.
14:34:18:M:done.
14:34:18:M:Loading PP...
14:34:18:M:done, 328995 ppoints.
14:34:49:M:WS:Socket opened TCP port 8085
14:34:49:M:HS:Socket opened TCP port 8080
14:34:49:M:RS:Socket opened TCP port 3724

а вот редирект полученный мною:

14:37:30:M:Loading config file wel_server.conf ... done.
14:37:30:M:Loading address cache ... skipped.
14:37:34:M:Patching ... #569 ... #56E ... #568 ... <WS> ... <SN> ... <MOTD> ... <FCKSTF> ... #57 ... #61 ... #63 ... #62 ... #67 ... done.
14:37:34:M:[PavkaM Plugin] v0.6.2 Loading database ...
[*** Plugin] TCLTool : Loading Quests Definitions ...
[*** Plugin] TCLTool : Loading Quests Definitions ... OK
[*** Plugin] TCLTool : Loading NPC Definitions ...
[*** Plugin] TCLTool : Loading NPC Definitions ... OK
[*** Plugin] TCLTool : Compiling NPCs ...
[*** Plugin] TCLTool : Compiling NPCs ... OK
[*** Plugin] Loading frase Database ...
[*** Plugin] Loading frase Database ... OK
[*** Plugin] Loading Spell Database  ...
[*** Plugin] Loading Spell Database ... OK
[*** Plugin] Loading Global configuration  ...
[*** Plugin] Loading Global configuration ... OK
[*** Plugin] Loading User configuration  ...
[*** Plugin] User configuration not found ! (It"s OK)
[*** Plugin] Loading Temporary Pool  ...
[*** Plugin] Temporary Pool not found ! (It"s OK)
[*** Plugin] Loaded OK


 
Digitman ©   (2005-07-20 12:00) [49]


> короче привожу сравнительный анализ


мог бы и еще короче

мне, к примеру, этот "анализ" ни о чем не говорит, да и не анализ это никакой, а просто констатация фактов


 
бывший   (2005-07-20 12:03) [50]

сорри, ну я констатацию фактов и имел в виду. извините, ей богу. (


 
alpet ©   (2005-07-20 12:07) [51]

бывший   (20.07.05 12:03) [50]
1. Какой статус выполнения ReadFile (GetLastError) в случаях считывания и не считывания данных.
2. Может попробывать ReadConsoleOutput?


 
бывший   (2005-07-20 12:11) [52]

alpet ©   (20.07.05 12:07) [51]

2. ReadConsoleOutput? енто что? F1 не помог (
1. гляну ща...

что можете сказать относительно столь кривого редиректа? каким образом сервер может выводить на консоль минуя редирект? странно все это очень (


 
Ботвин Дмитрий   (2005-07-20 12:20) [53]

Если тебе нужна эта непонятная инфа, может проще перенаправить
консоль в файл, например:

ping 192.168.28.200 > c:\123.txt

и непарится с редиректом :-)))


 
alpet ©   (2005-07-20 12:24) [54]

бывший   (20.07.05 12:11) [52]

The ReadConsoleOutput function reads character and color attribute data from a rectangular block of character cells in a console screen buffer, and the function writes the data to a rectangular block at a specified location in the destination buffer.

Прототип есть в Delphi/Source/Rtl/Win/Windows.pas.

Я для эмуляции ввода с клавиатуры использую подобную ей функцию WriteConsoleInput (si.hStdInput...) Работает нормально с консольными и DOS прогами. Эта функция соотвественно должна работать с STARTUPINFO.hStdOutput.


 
бывший   (2005-07-20 13:15) [55]

Ботвин Дмитрий   (20.07.05 12:20) [53]
=) нужен real-time )ибо то что я показал - есть всего лишь  процесс инициализации сервера (загрузка данных, открытие портов), далее следует коннект клиентов, работа с ними и т.д. - все это надо парсить в real-time и определенным образом реагировать на события.

alpet ©   (20.07.05 12:24) [54]
спасибо. буду смотреть.

Digitman ©   (20.07.05 11:40) [47]
спасибо, буду иметь в виду.

и все-таки кто как думает - почему редирект не полный? это остался последний вопрос )


 
alpet ©   (2005-07-20 13:21) [56]

бывший   (20.07.05 13:15) [55]
Неполный видимо потому, что твоя программа считывает не все данные из пайпа, что может быть следствием того что они туда не все попадают, или какой-нибудь ошибки в программе. Статус выполнения ReadFile мы так и неувидели.


 
alpet ©   (2005-07-20 13:35) [57]

Потом добавление результата у тебя происходит как-то странно на мой взгляд:
   
Line := "";
...
Line := Line + Buffer;
...
uMain.MainForm.richLog.Lines.Add(Line);

Это по идее приводит к разбиению строк.
Попробуй так (строки должны получаться нормально):

with uMain.MainForm.richLog do
 Text := Text + Buffer;


 
Ботвин Дмитрий   (2005-07-20 13:36) [58]

Через перенаправление тоже будет реалтайм. Запускаешь в основном
потоке перенаправление, а во втором читаешь. Попробуй с тем же
пингом с параметром -t, а текстовым редактором открывай созданный файл и смотри как в него добавляются строки :-)))


 
alpet ©   (2005-07-20 13:41) [59]

В MSDN приведен пример с пайпами. Вот кусочек его (чтение из пайпа в stdout):

for (;;)
  {
     if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead,
        NULL) || dwRead == 0) break;
     if (! WriteFile(hSaveStdout, chBuf, dwRead, &dwWritten, NULL))
        break;
  }

Единственно что заметно в отличии от предлагаемых программ - размер буфера (BUFSIZE) = 4096.


 
Slym ©   (2005-07-20 14:02) [60]

А где start.hStdError?
у консоли 1 вход и 2! выхода
Без перенаправления выходы указывают в одно место, перенаправляешь ты только hStdOutput, а hStdError?
Перенаправь hStdError тудаже (в hStdOutput)


 
Slym ©   (2005-07-20 14:04) [61]

А прога у тебя не запускаться может от того что hStdError=0


 
Slym ©   (2005-07-20 14:09) [62]

Коряво но работает:

type
 TConsoleThread=class(TThread)
 private
   FCMD:string;
   FCloseHandles:boolean;
   FStdIn:TStrings;
   FStdOut:TStrings;
   FExitCode:DWord;
 protected
   procedure Execute;override;
 public
   constructor Create(const CMD:string;Commands:TStrings;CloseHandles:boolean=false);reintroduce;
   destructor Destroy; override;
   property ExitCode:DWord read FExitCode;
   property StdOut:TStrings read FStdOut;
 end;

implementation
uses SysUtils;

{ TConsole }

constructor TConsoleThread.Create(const CMD:string;Commands:TStrings;CloseHandles:boolean=false);
var i:integer;
begin
 FCMD:=CMD;
 FCloseHandles:=CloseHandles;
 FStdIn:=TStringList.Create;
 FStdOut:=TStringList.Create;
 if assigned(Commands) then
 begin
   FStdIn.BeginUpdate;
   try
     for I:= 0 to Commands.Count - 1 do
       FStdIn.AddObject(Commands[I]+#13#10, Commands.Objects[I]);
   finally
     FStdIn.EndUpdate;
   end;
 end;

 inherited Create(false);
end;

destructor TConsoleThread.Destroy;
begin
 FStdIn.Free;
 FStdOut.Free;
 inherited;
end;

procedure TConsoleThread.Execute;
var
 sa:TSecurityAttributes;
 si:TStartupInfo;
 pi:TProcessInformation;
 ChildStdInWr,ChildStdoutRd:THandle;
 ChildStdoutWr,ChildStdInRd:THandle;
 Tmp1,Tmp2:THandle;
 buffer:Pointer;
 bytesRead:DWORD;
 p:PChar;
begin
 ChildStdInWr:=0;ChildStdoutRd:=0;
 ChildStdoutWr:=0;ChildStdInRd:=0;
 Tmp1:=0;Tmp2:=0;
 sa.nLength:=sizeof(TSecurityAttributes);
 sa.bInheritHandle:=true;
 sa.lpSecurityDescriptor:=nil;
 try
   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;
   if ChildStdoutRd<>0 then
     if CloseHandle(ChildStdoutRd) then
       ChildStdoutRd:=0;
   if ChildStdinWr<>0 then
     if CloseHandle(ChildStdinWr) then
       ChildStdinWr:=0;
   ChildStdoutRd:=Tmp1;Tmp1:=0;
   ChildStdinWr:=Tmp2;Tmp2:=0;

   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,PChar(FCMD),nil,nil,true,CREATE_NEW_CONSOLE,nil,nil,si,pi) then
     RaiseLastOSError;
   while not Terminated do
   begin
     if WaitForSingleObject(pi.hProcess,0)=WAIT_OBJECT_0 then
     begin
       GetExitCodeProcess(pi.hProcess,FExitCode);
       CloseHandle(pi.hProcess);
       CloseHandle(pi.hThread);
       Terminate;
     end;
     PeekNamedPipe(ChildStdoutRd,nil,0,nil,@bytesRead,nil);
     if bytesRead>0 then
     begin
       GetMem(buffer,bytesRead+1);
       try
         if not ReadFile(ChildStdoutRd,buffer^,bytesRead,bytesRead,nil) then
           RaiseLastOSError;
         PChar(buffer)[bytesRead]:=#0;
         OemToChar(buffer,buffer);
         FStdOut.Append(PChar(buffer));
       finally
         FreeMem(buffer);
       end;
     end;
     while FStdIn.Count>0 do
     begin
       p:=PChar(FStdIn[0]);
       CharToOem(p,p);
       if not WriteFile(ChildStdinWr,p^,Length(FStdIn[0]),bytesRead,nil) then
         RaiseLastOSError;
       FStdIn.Delete(0);
     end;
     if FCloseHandles and (ChildStdinWr<>0) then
       if CloseHandle(ChildStdinWr) then
         ChildStdinWr:=0;
   end;
 finally
   if ChildStdoutRd<>0 then CloseHandle(ChildStdoutRd);
   if ChildStdoutWr<>0 then CloseHandle(ChildStdoutWr);
   if ChildStdinRd<>0 then CloseHandle(ChildStdinRd);
   if ChildStdinWr<>0 then CloseHandle(ChildStdinWr);
   if Tmp1<>0 then CloseHandle(Tmp1);
   if Tmp2<>0 then CloseHandle(Tmp2);
 end;
end;


 
бывший   (2005-07-21 10:12) [63]

проверил пример Slym"a: результат тот же! редирект не полностью. значит дело не в StdError (

@alpet ©   (20.07.05 12:07) [51]
по поводу статуса ReadFile - везде все путем. проверка сама собой получилась (см. пример Slym"a):
if not ReadFile(ChildStdoutRd,buffer^,bytesRead,bytesRead,nil) then
          RaiseLastOSError;

исключения не было.


 
Ботвин Дмитрий   (2005-07-21 10:48) [64]

Последнее, что могу предложить:
1. Задать ReadBuffer = 4096;

2. Поправь цикл:
repeat
  Apprunning := WaitForSingleObject(ProcessInfo.hProcess, 30000);
  ReadFile(ReadPipe, Buffer[0],
  ReadBuffer, BytesRead, nil);
  Buffer[BytesRead] := #0;
  OemToAnsi(Buffer, Buffer);
  AMemo.Text := AMemo.text + string(Buffer);
  Application.ProcessMessages;
until (Apprunning <> WAIT_TIMEOUT) or (Apprunning <>WAIT_OBJECT_0);


 
бывший   (2005-07-21 15:26) [65]

буду смотреть, спасибо.

еще остался вариант с редиректом в файл (хотя думаю будет тоже самое), кстати, вопрос относительно console.exe > 1.txt - разве такое на всех консолях срабатывает? по-моему консоль должна "уметь" обрабатывать сей ключ. он же не универсален?

ну и вариант с ReadConsoleOutput [alpet]



Страницы: 1 2 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.59 MB
Время: 0.011 c
14-1123822737
syte_ser78
2005-08-12 08:58
2005.09.11
почему так долго под ХР одупляется сидюк?


14-1124218935
Defunct
2005-08-16 23:02
2005.09.11
"www.delphimaster.ru" и "delphimaster.ru"


1-1124701636
Laymer
2005-08-22 13:07
2005.09.11
QuickReport


14-1123689907
kamerer
2005-08-10 20:05
2005.09.11
Документация по компонентам VCL


14-1124259182
REA
2005-08-17 10:13
2005.09.11
1C защита





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский