2011-01-17 43 views
6

Tôi đang cố gửi lệnh đến đầu vào của ứng dụng cmd.exe bằng các chức năng điều khiển đọc/ghi mức thấp. Tôi không gặp khó khăn khi đọc văn bản (cào) bằng cách sử dụng các hàm ReadConsole...()WriteConsole() sau khi đã đính kèm vào bảng điều khiển quy trình, nhưng tôi đã không tìm ra cách viết ví dụ "dir" và yêu cầu giao diện điều khiển dịch thành lệnh được gửi.Bàn điều khiển cấp thấp Nhập và chuyển hướng

Dưới đây là một chút mã của tôi:

CreateProcess(NULL, "cmd.exe", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); 
AttachConsole(pi.dwProcessId); 

strcpy(buffer, "dir"); 
WriteConsole(GetStdHandle(STD_INPUT_HANDLE), buffer, strlen(buffer), &charRead, NULL); 

STARTUPINFO thuộc tính của quá trình này đều được thiết lập để không, trừ, tất nhiên, thuộc tính .cb.

Không có thay đổi nào trên màn hình, tuy nhiên tôi nhận được Error 6: Invalid Handle được trả lại từ WriteConsole đến STD_INPUT_HANDLE. Nếu tôi viết thư cho (STD_OUTPUT_HANDLE) Tôi nhận được dir được viết trên màn hình, nhưng không có gì xảy ra. Tôi đoán SetConsoleMode() có thể giúp đỡ, nhưng tôi đã thử nhiều kết hợp chế độ, không có gì hữu ích. Tôi cũng đã tạo ra một ứng dụng giao diện điều khiển nhanh chóng mà chờ đầu vào (scanf()) và phản hồi lại bất cứ điều gì đi vào, không hoạt động.

Tôi cũng đã thử nhập vào mã khuyến mại scanf() rồi xem trong bộ đệm đầu vào bằng cách sử dụng PeekConsoleInput(), trả về 0, nhưng mảng INPUT_RECORD trống.

Tôi biết rằng có một cách khác xung quanh việc này sử dụng WriteConsoleInput() để chèn trực tiếp các sự kiện có cấu trúc INPUT_RECORD vào bảng điều khiển, nhưng điều này sẽ quá dài, tôi sẽ phải gửi mỗi lần nhấn phím vào đó.

Tôi hy vọng câu hỏi là rõ ràng. Vui lòng cho tôi biết nếu bạn cần thêm bất kỳ thông tin nào. Cảm ơn bạn đã giúp đỡ.

Cập nhật 1:

tôi có thể gửi bấm phím để một quá trình sử dụng cmdWriteConsoleInput() với INPUT_RECORD cấu trúc, tuy nhiên, đôi khi AttachConsole ném ERROR_GEN_FAILURE #31: A device attached to the system is not functioning., và do đó INPUT_RECORD không được gửi (Error 6: Invalid Handle). Sleep(1000) sau CreateProcess() trước khi AttachConsole() giải quyết vấn đề này. Các nhân vật dir được gõ vào tự động, nhưng tôi không thể tìm ra cách để gửi RETURN chính:

ir[0].EventType = KEY_EVENT; 
ir[0].Event.KeyEvent.bKeyDown = TRUE; 
ir[0].Event.KeyEvent.dwControlKeyState = 0; 
ir[0].Event.KeyEvent.uChar.UnicodeChar = '\n'; 
ir[0].Event.KeyEvent.wRepeatCount = 1; 
ir[0].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; 
ir[0].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC); 
ir[1].EventType = KEY_EVENT; 
ir[1].Event.KeyEvent.bKeyDown = FALSE; 
ir[1].Event.KeyEvent.dwControlKeyState = 0; 
ir[1].Event.KeyEvent.uChar.UnicodeChar = '\n'; 
ir[1].Event.KeyEvent.wRepeatCount = 1; 
ir[1].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; 
ir[1].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC); 

WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), ir, 2, &charRead); 

WriteConsoleInput lợi nhuận 0, nhưng không có gì xảy ra trong giao diện điều khiển, tôi đã cố gắng thiết lập SetConsoleMode()-ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT và một sự kết hợp của chúng, không có kết quả. Tuy nhiên, nếu tôi nhấn enter từ bàn phím, lệnh dir được nhập tự động sẽ thực hiện (không giống như thời điểm tôi chỉ WriteConsole()), vì vậy tôi đoán tôi đang đi đúng hướng.

SSH không gửi qua các phím bấm thực tế và nhận được bộ đệm màn hình thực tế (như TAB và CTRL + C CTRL + D hoạt động)? Tôi là sau một cái gì đó giống như.

Cập nhật 2:

tôi thấy vấn đề với tiêm lệnh trở lại. Phải là ir[1].Event.KeyEvent.uChar.AsciiChar = '\r'; tức là một \r thay vì \n, siêu đơn giản.Có vẻ như không có cách nào để sử dụng WriteConsole() để nhập lệnh, người ta nên nhận bằng cách gửi WriteConsoleInput() INPUT_RECORD hoặc bằng cách tạo đường ống (không phải lúc nào cũng hoàn hảo, nhưng tuyệt vời cho hầu hết các ứng dụng thẳng về phía trước). Một lợi thế lớn khi sử dụng WriteConsoleInput() là bạn có thể gửi VK_UPVK_DOWN, để truy cập lịch sử bảng điều khiển, (nếu chúng tôi đang ở CMD) và VK_TAB để tự động hoàn thành, tất cả các phím CTRL + _ sequences, ESC và FUNCTION và thậm chí NHƯ CHUỘT .

biết thêm thông tin ở đây: http://msdn.microsoft.com/en-us/library/ms687403%28v=vs.85%29.aspx cộng tấn ví dụ ở đây: http://controllingtheinter.net/forums/viewtopic.php?f=116&t=366

Nếu ai có ý tưởng tuyệt vời khác cảm thấy tự do để chip trong Cảm ơn tất cả những người đã quan tâm đến việc này.. Mong rằng điều này sẽ giúp ai đó trong tương lai.

Trả lời

2

Ngay bây giờ bạn đang cố gắng ghi vào tay cầm stdin của riêng bạn, không phải là trình xử lý cmd.exe. Bạn sẽ phải làm nhiều công việc hơn để chuyển hướng xử lý đầu vào cho điều đó. Nó đòi hỏi một đường ống. Dưới đây là một số KB article hiển thị mã bản mẫu.

Btw: luôn luôn kiểm tra giá trị trả lại của hàm API.

+0

Tôi nghĩ rằng tôi đã gắn với bảng điều khiển của quy trình mới. 'AttachConsole()' cho phép điều này; khi tôi 'printf()' sau khi gắn tôi đang thực sự in vào 'cmd.exe'. Tôi đã cập nhật Mã lỗi mà tôi nhận được từ 'WriteConsole()' thành 'STD_INPUT_HANDLE' – soulseekah

+0

Bạn chỉ chia sẻ cửa sổ bảng điều khiển, đúng vậy. Có, mã lỗi cho bạn thấy những gì đang xảy ra, bạn không thể ghi vào một tay cầm đầu vào. –

+0

Tôi đã đọc mã đó và thử nó ngày hôm qua, hoạt động như một sự quyến rũ, các chương trình sinh sản như 'FTP.exe' và' EDIT.exe' có bộ đệm riêng, không được chuyển hướng, điều này kêu gọi đọc và viết ở mức độ thấp vào bảng điều khiển. Về cơ bản tôi muốn sao chép một cửa sổ giao diện điều khiển, bằng cách chuyển hướng tất cả mọi thứ từ một đến khác. – soulseekah

Các vấn đề liên quan