Вниз
Скачать: CL | DM;

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 вся ветка

Скачать: CL | DM;



Память: 0.52 MB
Время: 0.022 c
14-1122037873
tormoz
2005-07-22 17:11
2005.08.14
Скучно тут у вас!!!


1-1122047608
jeon1
2005-07-22 19:53
2005.08.14
Как сделать цикл зависимым от времени?


3-1120627489
Тучудище
2005-07-06 09:24
2005.08.14
FibPlus 5.3.0 Release не работает LookupCache:=true??


1-1122313034
Aldaris
2005-07-25 21:37
2005.08.14
Чтение Boolean переменных из *.ini файлов.


4-1118729844
vinni_0FFh
2005-06-14 10:17
2005.08.14
Как нажать кнопку в тулбаре чужой программы




   Наверх