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

Вниз

WriteConsoleInput   Найти похожие ветки 

 
Logo   (2005-05-31 08:47) [0]

Использую WriteConsoleInput.
Но почему то передается не буква "n", а буква "N".
И еще какой-то пробел после нее. Вместо Энтера знак равно.
Что может быть не так?
Еще не могу по русски писать в консоль.


 
Digitman ©   (2005-05-31 09:03) [1]


> Еще не могу по русски писать в консоль


Windows NT: This function uses either Unicode characters or 8-bit characters from the console"s current codepage. The console"s codepage defaults initially to the system"s OEM codepage. To change the console"s codepage, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.


 
Logo   (2005-05-31 09:07) [2]

я это читал сегодня в доках :)
только юзаю CharToOemBuff(@S[1],@S[1],Length(S));
чтобы передать ОЕМ строку.
Но не помогает. Видимо придется таки SetConsoleCP использовать.


 
Digitman ©   (2005-05-31 09:16) [3]


> не помогает


приведи полное конкретное содержимое s ДО и ПОСЛЕ CharToOemBuff


 
Logo   (2005-05-31 10:28) [4]

Хотим передать: s:="123абв";
потом  CharToOemBuff(@S[1],@S[1],Length(S));
Передаем:"123 Ўў" (попадает в memo1)
Консоль получает: "nm,= "
где копать?


 
alpet ©   (2005-05-31 10:50) [5]

Кто ж строки напрямую передает CharToOem.

function ChToOem (const s: string): string;
var p: array [0..255] of char;
begin
CharToOemBuff (PChar (s), p, Length (s) + 1); // + \0
result := p;
end;    


 
Digitman ©   (2005-05-31 11:07) [6]


> Logo   (31.05.05 10:28) [4]


> Хотим передать: s:="123абв";


> почему то передается не буква "n", а буква "N".


и где здесь "буква "n" ?


> Консоль получает: "nm,= "


скорей всего ты неверно передаешь данные строки на вход WriteConsoleInput , т.е. неверно формируешь INPUT_RECORD


> alpet ©   (31.05.05 10:50) [5]
> Кто ж строки напрямую передает CharToOem


все он правильно передает в CharToOem, не выдумывай


 
alpet ©   (2005-05-31 11:10) [7]

Пример консольного приложения в котором это все работает:

{$APPTYPE CONSOLE}
uses SysUtils, Windows;
function ChToOem (const s: string): string;
var p: array [0..255] of char;
begin
CharToOemBuff (PChar (s), p, Length (s) + 1); // + \0
result := p;
end;
procedure SendInputStr (const s: string);
var
   r: TInputRecord;
   n, num: dword;
   ss: string;
   hstdi: THandle;
begin
ss := ChToOem (s);
r.EventType := KEY_EVENT;
hstdi := GetStdHandle (STD_INPUT_HANDLE);
for n := 1 to Length (ss) do
with r.event do
 begin
  KeyEvent.bKeyDown := true;
  KeyEvent.AsciiChar := ss [n];
  KeyEvent.wRepeatCount := 0;
  KeyEvent.wVirtualKeyCode := 0;
  KeyEvent.wVirtualScanCode := 0;
  WriteConsoleInput (hstdi, r, 1, num);
  r.Event.KeyEvent.bKeyDown := false;
  WriteConsoleInput (hstdi, r, 1, num);
 end;
end;

begin
SendInputStr ("Test ");
SendInputStr ("Тест");
readln;
end.


 
alpet ©   (2005-05-31 11:12) [8]

2 Digitman
Ну да работать будет, только выглядит криво...


 
Digitman ©   (2005-05-31 11:34) [9]


> alpet ©   (31.05.05 11:12) [8]
> работать будет, только выглядит криво


да почему криво ?

на вкус и цвет, как известно, товарищей нет - кому удобней воспринимать PChar(AnsiStrVar), а кому и @AnsiStrVar[1] ..  компилятору же фиолетово)


 
alpet ©   (2005-05-31 13:15) [10]

Компилятору не фиолетово. При использовании приведении типа, код генерируется несколько другой, хотя разницы в результате и не наблюдается (только что 30% разница в быстродействии - приведение меньше времени занимает, но кому сейчас это интересно).


 
Digitman ©   (2005-05-31 13:47) [11]


> alpet ©   (31.05.05 13:15) [10]


о производительности речи не идет.


 
VMcL ©   (2005-05-31 14:16) [12]

>>alpet ©   (31.05.05 13:15) [10]

Если интересует быстродействие, то самый рулез приводить не к PChar, а к Pointer.

>>alpet ©   (31.05.05 10:50) [5]

Строк длинее 255 символов не бывает?

function StringToOEM(const S: AnsiString): AnsiString;
var
 Len: Integer;
begin
 Len := Length(S);
 SetLength(Result, Len);
 if Len > 0 then
   Win32Check(CharToOEM(PChar(S), PChar(Result)));
end;


 
alpet ©   (2005-05-31 14:48) [13]

VMcL ©   (31.05.05 14:16) [12]
1. Абсолютно с вами согласен. Быстрее на целых 0.2%
2. И тут верно, функция моя пригодна лишь только для ShortString переменных, длиной не более 255 символов.


 
Logo   (2005-06-14 13:43) [14]

2 alpet Help!
Твой пример действительно работает. Вызывается консоль и в ней пишется то, что туда засылается. Но вот когда вместо консоли подсовываю свою DOS программку, в нее начинает выводится какой то бред.

вот кусок вставленного кода в твой пример.
==== BEG ====
var
 SI: TStartupInfo;
 PI: TProcessInformation;

begin
 ZeroMemory(@SI, SizeOf(SI));
 si.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
 AllocConsole;
 CreateProcess(Nil, "proga.EXE", Nil, Nil, True, 0, Nil, Nil, SI, PI);
 Sleep(1000);
 SendInputStr ("Test ");
end.
==== END ====


 
alpet ©   (2005-06-14 14:09) [15]

Хм... А пример того что в консоли получается можно увидеть? И как та же программа (proga.exe) работает через echo или < перенаправления?

Пример файл 1.txt

echo start
dir
cd c:\windows

Если запустить cmd.exe < 1.txt он будет выполнять комманды файла так как если бы их вводил пользователь.


 
Logo   (2005-06-14 15:20) [16]

Прога здесь - http://botchallenge.com/u/RSAKEYS.EXE
Это что-то наподобие PGP.
Например, комманда: RSAKEYS.EXE -KG 512, котрую я вызываю.
потом запрашивает ID Пользователя. Надо ввести, например, Пупкин.
Затем пароль два раза одинаковый, затем нажатия произвольных кнопок. После чего должны появиться два файла pubkeys и seckeys.

Когда делаю перенаправлением ввода консоль виснет.


 
alpet ©   (2005-06-14 15:32) [17]

1. С этого надо было начинать.
2. Программа нормально получает логин и пару паролей, но затыкается когда дело доходит до произвольного текста. Собственно надо понять что она использует для оценки нажатия клавиши, возможно и не stdinput.

Попробуй после ввода логина и паролей отправлять символы, чередуя их с случайной задержкой:

for n := 1 to 100 do
begin
 WriteConsoleInput (...); // some char
 Sleep (random (100) + 100);
end;


 
Logo   (2005-06-15 06:22) [18]

Будешь смеяться, но я не могу корректно даже логин ей передать через WriteConsoleInput().

Через перенаправление ввода логин и первый пароль в нее попадают, второй тоже попадает но получаю сообщение о несовпадении пар паролей :( хотя в файле 1.txt они явно одинаковые

Одна из функций - объединение ключей после которого и надо нажимать лишь кнопку "N". После этого случайные символы не нужны но эффект тот же - зависон консоли.
Спасибо, что пытаешься помочь. Это редко бывает в наше время ;)


 
Logo   (2005-06-15 11:23) [19]

Попробовал создал в том же дельфи консольное приложение которое readln-ом получает данные. подставил вместо rsakeys.exe и все замечательно работает!
где копать? может сама прога что-то криво воспринимает?


 
alpet ©   (2005-06-15 11:43) [20]

C нажатиями клавиш через файл нечего передавать не удается, видимо используются функции для проверки соостояния клавы (kbhit ???) которые не обманываются с помощью перехвата ввода (можно попробывать SetKeyboardStatus, внедрив dll в пространство ntdvm процесса).

Вот какое содержимое файла 1.txt программа воспринимает в качестве логина и пары паролей.

login

password
password



 
Logo   (2005-06-22 07:51) [21]

будете смеяться, но не могу добиться передачи login и password через delphi приложение. Передаются не те символы которые посылаются.


 
alpet ©   (2005-06-22 10:32) [22]

Код представь пожайлуста весь.


 
Logo   (2005-06-23 06:55) [23]

Вот код. Он запускает прогу и выводит вместо 12345 пять букв A.

{$APPTYPE CONSOLE}
uses SysUtils, Windows;
var
 SI: TStartupInfo;
 PI: TProcessInformation;

function ChToOem (const s: string): string;
var p: array [0..255] of char;
begin
CharToOemBuff (PChar (s), p, Length (s) + 1);
result := p;
end;

procedure SendInputStr (const s: string);
var
  r: TInputRecord;
  n, num: dword;
  ss: string;
  hstdi: THandle;
begin
ss := ChToOem (s);
r.EventType := KEY_EVENT;
//hstdi := GetStdHandle (STD_INPUT_HANDLE);
for n := 1 to Length (ss) do
with r.event do
begin
 KeyEvent.bKeyDown := true;
 KeyEvent.AsciiChar := ss [n];
 KeyEvent.wRepeatCount := 0;
 KeyEvent.wVirtualKeyCode := 0;
 KeyEvent.wVirtualScanCode := 0;
 WriteConsoleInput (Si.hStdInput, r, 1, num);
 r.Event.KeyEvent.bKeyDown := false;
 WriteConsoleInput (Si.hStdInput, r, 1, num);
end;
end;

begin
ZeroMemory(@SI, SizeOf(SI));
si.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
AllocConsole;
CreateProcess(Nil, "C:\temp\rsa\RSAKEYS.EXE -kg 512", Nil, Nil, True, 0, Nil, Nil, SI, PI);
Sleep(1000);
SendInputStr ("12345");

Sleep(1000);
//  CloseHandle(PI.hThread);
//  CloseHandle(PI.hProcess);
//  FreeConsole;
end.


 
alpet ©   (2005-06-23 13:19) [24]

Блин, а задача интересной оказалось. Но как всегда помогло внимательное чтение справки. Вот держи и разбирай рабочий код, хотя я бы поискал для задачи исходники программы rsa.exe:
program redir;

{$APPTYPE CONSOLE}
uses Windows, Types, SysUtils;
var
SI: TStartupInfo;
PI: TProcessInformation;

function ChToOem (const s: string): string;
var p: array [0..255] of char;
begin
CharToOemBuff (PChar (s), p, Length (s) + 1);
result := p;
end;

procedure SendInputStr (const s: string);
var
 r: TInputRecord;
 n, num: dword;
 ss, ls: string;
 hstdi, hFile: THandle;
begin
ss := ChToOem (s);
ls := LowerCase (ss);
r.EventType := KEY_EVENT;
hFile := CreateFile ("con", GENERIC_WRITE, FILE_SHARE_WRITE, nil,
                        OPEN_ALWAYS, 0, 0);
//hstdi := GetStdHandle (STD_INPUT_HANDLE);
for n := 1 to Length (ss) do
with r.event do
begin
 if (ls [n] = ss [n]) then
    KeyEvent.dwControlKeyState := 0
 else
    KeyEvent.dwControlKeyState := SHIFT_PRESSED;
 KeyEvent.AsciiChar := ss [n];
 KeyEvent.UnicodeChar := WideChar (ss [n]);
 KeyEvent.wRepeatCount := 0;
  case ss [n] of
    #13, #10: KeyEvent.wVirtualKeyCode := VK_RETURN;
    #$30..#$39: KeyEvent.wVirtualKeyCode := ord (ss [n]);
    else KeyEvent.wVirtualKeyCode := ord (UpCase (ss [n]));
  end;
 KeyEvent.wVirtualScanCode := MapVirtualKey (KeyEvent.wVirtualKeyCode, 0);
 KeyEvent.bKeyDown := true;
 //WriteFile (hFile, ss [n], 1, num, nil);
 WriteConsoleInput (Si.hStdInput, r, 1, num);
 r.Event.KeyEvent.bKeyDown := false;
 WriteConsoleInput (Si.hStdInput, r, 1, num);
end;
CloseHandle (hFile);
end;

var n: dword;
begin
ZeroMemory(@SI, SizeOf(SI));
si.cb := sizeof (si);
si.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
// SetConsoleMode (si.hStdInput, ENABLE_PROCESSED_OUTPUT);
chdir ("C:\temp\rsa\");
CreateProcess(Nil, "C:\temp\rsa\RSAKEYS.EXE -kg 512 << con", Nil, Nil, True, 0, Nil, Nil, SI, PI);
// CreateProcess(Nil, "C:\Windows\system32\cmd.exe", Nil, Nil, True, 0, Nil, Nil, SI, PI);
Sleep (1000);
SendInputStr ("AfxName1234"#13);
Sleep (200);
FlushConsoleInputBuffer (si.hStdInput);
SendInputStr ("PWDUNIVERSAL"#13);
Sleep (200);
FlushConsoleInputBuffer (si.hStdInput);
SendInputStr ("PWDUNIVERSAL"#13);
Sleep (200);
FlushConsoleInputBuffer (si.hStdInput);
n := 0;
while (WaitForSingleObject (pi.hProcess, random (200) + 10) = WAIT_TIMEOUT) and
        (n < 10)  do
 begin
  SendInputStr ("QWERTY");
  inc (n);
 end;
 CloseHandle (pi.hProcess);
// WaitForSingleObject (pi.hProcess, INFINITE);
///TerminateProcess (pi.hProcess, 0); // not wait process
// FreeConsole;
// readln (input);
end.


 
alpet ©   (2005-06-23 13:20) [25]

CreateFile и прочие закомментированные элементы можно удалить.


 
Logo   (2005-06-23 14:07) [26]

Реально работает.
Единственное я немного подправил, чтобы ID можно было вводить русское.
Спасибо, alpet!



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

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

Наверх





Память: 0.53 MB
Время: 0.012 c
3-1120471111
Yurisimus
2005-07-04 13:58
2005.08.14
Верхний регистр в ADOQuery


3-1120653967
Ольга
2005-07-06 16:46
2005.08.14
SQL - запрос на удаление по условию


3-1120648451
WG
2005-07-06 15:14
2005.08.14
Delphi + SQL server - сориентируйте чайника


3-1120734264
Kreyl
2005-07-07 15:04
2005.08.14
Еще один чайницкий: как вызнать max и min значения


4-1118152251
Олежек
2005-06-07 17:50
2005.08.14
Как пользоваться функцией GetFileSize





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