Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обращение к консоли.Перенаправление вывода, Захват консоли по индентификатору. 
:(
    Опции темы
maleziv
Дата 9.7.2012, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 16.11.2010

Репутация: нет
Всего: нет



Доброго времени суток.
Существует проблема: необходимо связаться с консолью  по ее идентификатору (в данном примере это командная строка).  Затем необходимо передать в консоль команды (например, dir) и получить выполнение этой команды в текстовый файл. 
В коде снизу я захватываю консоль по ее идентификатору и в цикле передаю команду dir, выполнение команды отображается в консоли, но мне необходимо вывести это в текстовый файл. После этого необходимо передать в эту открытую консоль  другую команду и результат  вывести в этот же открытый файл.
Пожалуйста, подскажите, как  это сделать?

P/S: Консоль всегда запущена, запускать программным путем ее не нужно. Идентификатор известен. Можно ли передавать в консоль команды целиком, а не при помощи цикла?


Код

procedure TForm1.Button1Click(Sender: TObject);
var
  Window,Panel,Group,Button:hwnd;
  i: Integer;
  s, ss: string;
   p:PChar;
begin
Window:=FindWindow(nil, 'Администратор: Командная строка');
 p:=StrAlloc(20);
if Window <> 0 then
   begin
     s := 'dir';
     for i := 1 to Length(s) do
     begin
       SendMessage(Window, WM_CHAR, Word(s[i]), 0);
        sleep(100);
        end;
    PostMessage(Window, WM_KEYDOWN, VK_RETURN, 0);
   end;


Это сообщение отредактировал(а) maleziv - 9.7.2012, 18:37

Присоединённый файл ( Кол-во скачиваний: 8 )
Присоединённый файл  cmd.png 35,13 Kb
PM MAIL   Вверх
Ne1tr1n0
Дата 10.7.2012, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 1.3.2009

Репутация: 2
Всего: 8



PM MAIL   Вверх
maleziv
Дата 24.7.2012, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 16.11.2010

Репутация: нет
Всего: нет



Цитата(maleziv @ 9.7.2012,  18:13)
Доброго времени суток.
Существует проблема: необходимо связаться с консолью  по ее идентификатору (в данном примере это командная строка).  Затем необходимо передать в консоль команды (например, dir) и получить выполнение этой команды в текстовый файл. 
В коде снизу я захватываю консоль по ее идентификатору и в цикле передаю команду dir, выполнение команды отображается в консоли, но мне необходимо вывести это в текстовый файл. После этого необходимо передать в эту открытую консоль  другую команду и результат  вывести в этот же открытый файл.
Пожалуйста, подскажите, как  это сделать?

P/S: Консоль всегда запущена, запускать программным путем ее не нужно. Идентификатор известен. Можно ли передавать в консоль команды целиком, а не при помощи цикла?


Код

procedure TForm1.Button1Click(Sender: TObject);
var
  Window,Panel,Group,Button:hwnd;
  i: Integer;
  s, ss: string;
   p:PChar;
begin
Window:=FindWindow(nil, 'Администратор: Командная строка');
 p:=StrAlloc(20);
if Window <> 0 then
   begin
     s := 'dir';
     for i := 1 to Length(s) do
     begin
       SendMessage(Window, WM_CHAR, Word(s[i]), 0);
        sleep(100);
        end;
    PostMessage(Window, WM_KEYDOWN, VK_RETURN, 0);
   end;

Разобрался. Кому интересно код приложен. Но выявилась проблема программа работает только начиная с Win XP.
На Win  2000 фунция  AttachConsole(mProcessID) не работает  smile  .
Подскажите плиз как реализовать для 2000 го?

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
   const
   _WIN32_WINNT = $0501;
type
TAttachConsole = function (dwProcessId: DWORD): LongBOOL stdcall;
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  AttachConsole: TAttachConsole;
  mProcessID, Wnd, Hcwnd, chRead: Cardinal;
  BufInfo: _CONSOLE_SCREEN_BUFFER_INFO;
  lpCh: PChar;
  Coord: _COORD;
  i: Integer;
  p:string;
   s, ss: string;
implementation

{$R *.dfm}
function OpenFile(var fLog: TextFile; const LogFileName: String;
   const IsErase: Boolean = False): Boolean;
var
   TmpStr: String;
begin

   AssignFile(fLog, LogFileName);
   Result := IOResult = 0;
   if Result then begin
      if IsErase or (not FileExists (LogFileName)) then
         Rewrite(fLog)
      else
         Append(fLog);
      Result := IOResult = 0;
   end;

end;

function WriteLnStr(const fLog: TextFile; const fStr: string): boolean;

begin
{$I-}
   Writeln (fLog, fStr);
   Result := IOResult = 0;
   if Result then begin
         // { Flush(fLog); }
        Flush(System.Input); // {System.Output}
      Result := IOResult = 0;
   end;
{$I+}
end;

procedure CloseFile(var fLog: TextFile);
begin

  Flush(fLog);
  System.CloseFile(fLog);

end;


function StrFile(const fStr, fFileName: String;
   const IsErase: Boolean = False): Boolean;
var
   fLog: TextFile;
begin
   Result := OpenFile(fLog, fFileName, IsErase);
   if Result then begin
      try
         Result := WriteLnStr(fLog, fStr);
      finally
         CloseFile(fLog);
      end;
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
@AttachConsole := GetProcAddress(GetModuleHandle('kernel32.dll'), 'AttachConsole');

 Wnd := FindWindow(nil, 'Command Prompt'); 

  GetWindowThreadProcessId(Wnd, @mProcessID); // получаем по хэндлу окна ИД процесса, чтобы прицепиться к консоли

if Wnd <> 0 then
   begin
     s := 'dir';
     for i := 1 to Length(s) do
     begin
       SendMessage(Wnd, WM_CHAR, Word(s[i]), 0);
    
        end;
   
    PostMessage(Wnd, WM_KEYDOWN, VK_RETURN, 0);
     sleep(1000);
   end;



if Wnd <> 0 then
   begin
     s := 'dir';
     for i := 1 to Length(s) do
     begin
       SendMessage(Wnd, WM_CHAR, Word(s[i]), 0);
      //  sleep(100);
        end;
     // Simulate Return Key.
    PostMessage(Wnd, WM_KEYDOWN, VK_RETURN, 0);
     sleep(100);
   end;

 if AttachConsole(mProcessID) then begin 
    Hcwnd:=GetStdHandle(STD_OUTPUT_HANDLE);  
    GetConsoleScreenBufferInfo (Hcwnd, BufInfo); 
   GetMem(lpCh, (BufInfo.dwMaximumWindowSize.Y*BufInfo.dwMaximumWindowSize.X));//Процедура GetMem пытается получить указанные в BufInfo.dwMaximumWindowSize.Y*BufInfo.dwMaximumWindowSize.X байт памяти
      try
      for i:=0 to BufInfo.dwMaximumWindowSize.Y+100 do begin
         Coord.X := 0;
         Coord.Y := i;
         ReadConsoleOutputCharacter(Hcwnd, lpCh, BufInfo.dwMaximumWindowSize.X, Coord, chRead);

         StrFile(lpCh, ChangeFileExt('C:\1', '.txt'), False); 
      end;
    finally
     FreeMem(lpCh, BufInfo.dwMaximumWindowSize.Y*BufInfo.dwMaximumWindowSize.X);
    end;

  end;


 end;



end.


Добавлено через 7 минут и 56 секунд
Цитата(Ne1tr1n0 @ 10.7.2012,  14:41)
Это не подойдет? http://delphiworld.narod.ru/base/console_to_memo.html

Спасибо.
Пример конечно хороший.
Но в нем реализован запуск конкретнойконсоли, а не захват ее по идентификатору. Необходимо осуществить захват заголовка консоли,передать в нее команды и записать результат выполнения в файл. 
PM MAIL   Вверх
beard42
  Дата 2.10.2012, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 16.7.2009

Репутация: нет
Всего: нет



Цитата(Ne1tr1n0 @ 10.7.2012,  14:41)
Это не подойдет? http://delphiworld.narod.ru/base/console_to_memo.html

Странно, но у меня этот код не работает. Delphi 2010, Win7 32bit.
Вызывает Access Violation на CreateProcess.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0695 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.