2009-06-04 2 views
1

Об этом со ссылкой на этот вопрос:Как ввести программные приложения для Windows?

How to read output and give input to a program from c program?

Я нашел ответ на поставленный вопрос очень полезным. Точно так же я могу сделать это для приложений Windows? Как я могу программно ввести ввод в текстовое поле приложения Windows (например, .net, C#)? Могу ли я сделать действие нажатия кнопки из программы?

Если да, могу ли я сделать это из программы C (с Tiny C компилятором или любым другим на платформе Windows)? Если нет, как и на каком языке я могу это сделать? Пожалуйста, не считайте это глупым вопросом. Любые примеры кода будут очень оценены.

Редактировать: Могу ли я делать то же самое с веб-приложениями и веб-страницами?

+0

Именно то, что вы пытаетесь достичь? Это для тестирования, или вам просто нужно вызвать функциональность приложения форм Windows из другой программы? Если последний, то вы можете разместить службу WCF в приложении Windows Forms и вызвать ее из других программ. То же самое с веб-приложением. –

ответ

4

Если приложение в основном просто нужно манипулировать другими окнами, путем отправки нажатий клавиш и т.д. я хотел бы использовать AutoIt. Это в основном функция именно этой работы, и она делает это очень хорошо.

Так может быть, вы должны дать ему попробовать, вызвать не каждая проблема является гвоздь и может быть решена с помощью молотка (C#) ;-))

+1

Autoit - это язык программирования adhoc, который сначала казался мне волшебным языком. Тогда я влюбился в это и начал с ним сумасшедшие вещи. Спасибо за ответ на получение популярного значка вопроса. –

+0

@ Наслаждайтесь кодированием: Да, я хотел, чтобы половина из них ответила моим ответом. ;-)) – Oliver

2

enumerate all the windows системы.
Вы можете send windows messages в любое окно.

E.g. для установки текста текстового поля вам необходимо отправить сообщение WM_SETTEXT.

FYI: Winspector - очень интересный инструмент, который также сильно использует это (также для отладки или в противном случае сначала проверять окна, которые вы пытаетесь программно получить).

Вы также можете быть заинтересованы в this:

AutoIt v3 является бесплатным BASIC-подобный язык сценариев для автоматизации графического интерфейса Windows, и общие сценарии. Он использует комбинацию имитируемых нажатий клавиш, движения мыши и манипулирования окнами/элементами управления, чтобы автоматизировать задачи таким образом, который невозможно или надежно использовать на других языках (например, VBScript и SendKeys). AutoIt также очень маленький, автономный и будет работать на всех версиях Windows из коробки без каких-либо раздражающих «сроков выполнения»!

+0

Разве это не безумно, что приложения могут быть помешаны так? Есть ли какая-либо защита уровня процесса в Windows или каждый процесс может видеть каждый процесс? – dreamlax

+0

Не знаю, что я не знаю ... Это, например, как Revelation (http://www.snadboy.com/) работает, чтобы выявлять пароли в полях пароля ... Хотя есть другие меры, чтобы предотвратить это сейчас ... – fretje

+0

Это не безумие, чтобы окна могли контролироваться удаленно. Без API, чтобы позволить это, у вас не могло быть таких вещей, как отладчики, диспетчеры задач, инструменты автоматического тестирования и бесчисленные полезные приложения. Черт, без возможности отправлять сообщения Windows в любое окно, вы даже не можете отключить невосприимчивые приложения. –

2

Как указал fretje, вы можете это сделать.

Это намного сложнее для приложений Windows. Поскольку отдельные элементы управления также учитываются как окна, общее количество окон будет намного выше, чем вы могли ожидать; и поиск конкретного элемента управления, на который вы хотите отправить ввод, может занять много работы.

Но вы можете программно перемещать, изменять размер, проверять, заполнять, максимизировать или иным образом влиять на окна приложения, как только вы узнаете, какая из них ваша цель.

Я написал код, чтобы сделать процесс обнаружения несколько лет назад. Он обнаружил все окна целевого приложения, а затем использовал их данные размером &, получив полупрозрачное наложение каждого дочернего окна вместе с номером дескриптора. Поэтому я мог визуально определить, какой элемент управления прошел с помощью этого дескриптора.

EDIT: Добавлен код. Это базовый код взаимодействия C#, который позволит вам легко звонить в user32.dll, который содержит fns, на который ссылался fretje. Это просто дает вам основные призывы к обнаружению и манипулированию; вам все равно придется тяжело перечислить и изучить то, что вы найдете. Если вы можете найти сторонний пакет, который выполняет эту работу для вас, избавьте себя от неприятностей; Я только делал это как учебный опыт, и это было довольно сложно.

using System; 
using System.Collections; 
using System.Runtime.InteropServices; 
using System.Text; 

namespace WinAPI 
{ 
    [Flags] public enum WindowStyleFlags : uint 
    { 
     WS_OVERLAPPED  = 0x00000000, 
     WS_POPUP   = 0x80000000, 
     // more... 
    } 

    [Flags] public enum ExtendedWindowStyleFlags: int 
    { 
     WS_EX_DLGMODALFRAME = 0x00000001, 
     WS_EX_NOPARENTNOTIFY = 0x00000004, 
     // more... 
    } 

    [StructLayout(LayoutKind.Sequential, Pack = 4)] 
    public struct RECT 
    { 
     public int Left; 
     public int Top; 
     public int Right; 
     public int Bottom; 
    } 

    [StructLayout(LayoutKind.Sequential, Pack = 4)] 
    public struct POINT 
    { 
     public int Left; 
     public int Top; 
    } 

    [StructLayout(LayoutKind.Sequential, Pack = 4)] 
    public struct FLASHWINFO 
    { 
     public int cbSize; 
     public IntPtr hwnd; 
     public int dwFlags; 
     public int uCount; 
     public int dwTimeout; 
    } 

    public delegate int EnumWindowsCallback(IntPtr hwnd, int lParam); 

    public class User32Dll 
    { 
     // Constants & fields 
     public const int FLASHW_STOP = 0; 
     public const int FLASHW_CAPTION = 0x00000001; 
     // lots, lots more, web search for them... 

     // Self-added, don't know if correct 
     [DllImport("user32")] 
     public extern static bool CloseWindow(IntPtr hWnd); 
     [DllImport("user32")] 
     public extern static IntPtr GetDesktopWindow(); 
     [DllImport("user32")] 
     public extern static IntPtr GetForegroundWindow(); 
     [DllImport("user32")] 
     public extern static int GetDlgItem(IntPtr hWnd, int wMsg); 
     [DllImport("user32")] 
     public extern static int GetListBoxInfo(IntPtr hWnd); 
     [DllImport("user32")] 
     public extern static bool MoveWindow(IntPtr hWnd, int X, int Y, int Width, int Height, bool Repaint); 
     [DllImport("user32")] 
     public static extern int SendMessage(IntPtr hWnd, int uMsg, IntPtr wParam, StringBuilder lpString); 
     [DllImport("user32")] 
     public static extern bool SetWindowPos(IntPtr hWnd, IntPtr afterWnd, int X, int Y, int cX, int cY, uint uFlags); 

     [DllImport("user32")] 
     public extern static int BringWindowToTop (IntPtr hWnd); 
     [DllImport("user32")] 
     public extern static int EnumWindows(EnumWindowsCallback lpEnumFunc, int lParam); 
     [DllImport("user32")] 
     public extern static int EnumChildWindows(IntPtr hWndParent, EnumWindowsCallback lpEnumFunc, int lParam); 
     [DllImport("user32.dll")] 
     public static extern int EnumThreadWindows(IntPtr hWndParent, EnumWindowsCallback callback, int lParam); 
     [DllImport("user32.dll")] 
     public static extern int FindWindow(string lpClassName, string WindowName); 
     [DllImport("user32.dll")] 
     public static extern int FindWindowEx(IntPtr hWnd, IntPtr hWnd2, string lpsz, string lpsz2); 
     [DllImport("user32")] 
     public extern static int FlashWindow (IntPtr hWnd, ref FLASHWINFO pwfi); 
     [DllImport("user32")] 
     public extern static IntPtr GetAncestor(IntPtr hWnd, uint gaFlags); 
     [DllImport("user32", CharSet = CharSet.Auto)] 
     public extern static int GetClassName (IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); 
     [DllImport("user32", CharSet = CharSet.Auto)] 
     public extern static uint GetWindowLong(IntPtr hwnd, int nIndex); 
     [DllImport("user32")] 
     public extern static int GetClientRect(IntPtr hWnd, ref RECT lpRect); 
     [DllImport("user32")] 
     public extern static int GetWindowRect(IntPtr hWnd, ref RECT lpRect); 
     [DllImport("user32", CharSet = CharSet.Auto)] 
     public extern static int GetWindowText(IntPtr hWnd, StringBuilder lpString, int cch); 
     [DllImport("user32", CharSet = CharSet.Auto)] 
     public extern static int GetWindowTextLength(IntPtr hWnd); 
     [DllImport("user32")] 
     public extern static int IsIconic(IntPtr hWnd); 
     [DllImport("user32")] 
     public extern static int IsWindowVisible(IntPtr hWnd); 
     [DllImport("user32")] 
     public extern static int IsZoomed(IntPtr hwnd); 
     [DllImport("user32", CharSet = CharSet.Auto)] 
     public extern static int PostMessage(IntPtr hWnd, int wMsg, int wParam, int lParam); 
     [DllImport("user32.dll")] 
     public static extern int RealGetWindowClass(IntPtr hWnd, StringBuilder pszType, uint bufferSize); 
     [DllImport("user32")] 
     public extern static int ScreenToClient(IntPtr hWnd, ref POINT lpPoint); 
     [DllImport("user32", CharSet = CharSet.Auto)] 
     public extern static int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam); 
     [DllImport("user32.dll")] 
     public extern static int SetForegroundWindow (IntPtr hWnd); 
     [DllImport("user32.dll")] 
     public static extern int SetWindowText(IntPtr hWnd, string lpsz); 
    } 
} 
+0

Большое спасибо за ваш сердечный ответ. Любые примеры кода, пожалуйста .. –

0

Проверьте следующую SO вопрос. Для этого есть множество инструментов для разработчиков и open-source, поэтому вам не нужно вводить код в Win32 API.

automated-testing-of-windows-forms

Смежные вопросы