WinAPI的SendInput的奇怪行为?另类?

时间:2015-09-24 13:26:55

标签: c# c user-interface winapi automation

有什么方法可以在键盘上发布笔画序列吗?

使用下面的SendInput代码在我的计算机上运行得非常好并且自信,但是当我在其他人(使用相同或其他操作系统(W7 / W10))上进行测试时,它没有。 当我尝试检查返回代码和上次错误时,我在各处都获得了成功(发布了X键击,返回代码:0),但没有完成笔画。

我的程序差不多完成了,早些时候有人建议我使用UIAutomation,但我现在对这项技术并不熟悉,我认为完全重新完成整个代码是无稽之谈。

任何人都可以告诉我有关winapi或C#类的信息,它可以替代SendInput并可靠地完成工作,或者我的代码中的内容很糟糕,而在我的机器上运行良好而在其他机器上运行不好。

非常感谢

PIXEL_COLOR pix = PIXEL_COLOR.PIX_UNKNOWN;
        bool isException = false;
        string mess ="";
        uint a = 0, b = 0;
        int ea = -1, eb = -1;

        try
        {
            const int TRUE = 1;
            const int FALSE = 0;
            MainWindow.ShowWindow(GetParent(clickSettings.GetHandler), SW_SHOWMAXIMIZED);
            SetWindowPos(GetParent(clickSettings.GetHandler), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);


            switch (lev.expiry)
            {
                case 5:
                case 10:
                case 15:
                    PutSingleClick(clickSettings.GetHandler, clickSettings.GetM15.GetX, clickSettings.GetM15.GetY);
                    break;
                case 60:
                    PutSingleClick(clickSettings.GetHandler, clickSettings.GetM60.GetX, clickSettings.GetM60.GetY);
                    break;
            }
            //show list
            PutSingleClick(clickSettings.GetHandler, clickSettings.GetInstruments.GetX, clickSettings.GetInstruments.GetY);
            Thread.Sleep(1000);
            //downarrows
            a = PutKeystroke(hWndMain, (int)lev.symbol, TRUE, out ea);
            Thread.Sleep(1000);

有两个鼠标点击,第二个是浏览器的组合框,我需要“手动”(通过键盘)选择一个项目。它使用以下代码从库中执行本机winapi函数:

extern "C" __declspec(dllexport) UINT __stdcall PutKeystroke(HWND hnd, int index, BOOL isDown, int& err)
{
    INPUT ip = {0};
    ip.type = INPUT_KEYBOARD;
    ip.ki.wVk =isDown? VK_DOWN : VK_UP;
    int times;
    if(index < 2)
        times = index+1;
    else
        times = index+2; //only correction, I forgot an option on third position which is not needed (and I'm very lazy :)
    INPUT ips[100] = {0};

    for(int i = 0; i < times*2; i+=2)
    {
        ip.ki.dwFlags = 0;
        ips[i] = ip;
        ip.ki.dwFlags = KEYEVENTF_KEYUP;
        ips[i+1] = ip;
    }
    ip.ki.dwFlags = 0;
    ip.ki.wVk = VK_RETURN;
    ips[times*2] = ip;
    ip.ki.dwFlags = KEYEVENTF_KEYUP;
    ips[(times*2)+1] = ip;

    UINT s = SendInput((times*2)+2, &ips[0], sizeof(INPUT));
    err = GetLastError();
    return s;
}

完成这项工作后,我还有更多工作要做,点击,将一些数字写入文本框等,之后我必须将combox选项恢复为默认值:

//combobox show
PutSingleClick(clickSettings.GetHandler, clickSettings.GetInstruments.GetX, clickSettings.GetInstruments.GetY);
Thread.Sleep(1000);
//uparrows
b = PutKeystroke(hWndMain, (int)lev.symbol + 15, FALSE, out eb);
Thread.Sleep(1000);

如果一切正常(没有异常发生,请解锁最顶层的浏览器并查看结果:

        finally
        {
            SetWindowPos(GetParent(clickSettings.GetHandler), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
            ShowWindow(GetParent(clickSettings.GetHandler), SW_HIDE);
            MessageBox.Show(string.Format("Keystrokes: choosing {0} error {1}, return to all {2} error {3}", a, ea, b, eb));
            if (isException)
            {
                MessageBox.Show(String.Format("Exception: {0} ", mess));
            }
            else
            {

                if (pix == PIXEL_COLOR.PIX_GREEN)
                { .........

我有总体上肯定结果(击键:选择X,错误0,返回Y,错误0),但是组合是画图,但没有笔画完成。< / p>

怎么了?

非常感谢

以下最简单,完整且可验证的示例 主要是为www.highlow.net上的HighLow经纪人自动使用Web应用程序而设计的程序。你需要点击“打开一个演示”(它是免费的,无需注册),右边会有一些组合框,这是问题的对象。

**** C#控制台应用代码****

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Globalization;

namespace clickTest1
{
    class Program
    {
        enum SYMBOLS
        {
            AUDJPY, AUDNZD, CADJPY, CHFJPY, EURAUD, EURGBP,
            EURJPY, EURUSD, GBPAUD, GBPJPY, GBPUSD, NZDJPY,
            NZDUSD, USDCAD, USDCHF, USDJPY, GOLD, UNKNOWN
        };

        const int SW_SHOWMAXIMIZED = 3;
        const int SW_HIDE = 0;
        const uint SWP_NOSIZE = 0x0001;
        const uint SWP_NOMOVE = 0x0002;
        const uint SWP_SHOWWINDOW = 0x0040;


        [DllImport(@"tradeInterop.dll")]
        public static extern void PutSingleClick(IntPtr hwnd, int x, int y);
        [DllImport(@"tradeInterop.dll")]
        public static extern uint PutKeystroke(IntPtr shouldBeNULL, int times, int isDown, out int err);
        [DllImport(@"user32.dll")]
        public static extern int SetWindowPos(IntPtr hwnd, IntPtr precendingHwnd, int x, int y, int cx, int cy, uint flags);
        [DllImport(@"user32.dll")]
        public static extern int ShowWindow(IntPtr hwnd, int cmdShow);
        [DllImport(@"user32.dll")]
        public static extern IntPtr GetParent(IntPtr hwnd);
        static void Main(string[] args)
        {
            UInt32 handler = 0;
            int x, y = 0;
            int keystrokesCount = 0;
            IntPtr HWND_BOTTOM = new IntPtr(1);
            IntPtr HWND_TOPMOST = new IntPtr(-1);
            UInt32 originalHandler = 0;
            while (true)
            {
                Console.WriteLine("H WND (hexadecimal) 0 = exit: ");
                handler = UInt32.Parse(Console.ReadLine(), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
                if (handler == 0)
                {
                    ShowBrowser((IntPtr)originalHandler, IntPtr.Zero);
                    break;
                }
                originalHandler = handler;
                HideBrowser((IntPtr)handler, HWND_BOTTOM);
                Console.WriteLine("X: ");
                x = int.Parse(Console.ReadLine());
                Console.WriteLine("Y: ");
                y = int.Parse(Console.ReadLine());
                Console.WriteLine("Choose instrument index (e.g. EURUSD=7)");
                keystrokesCount = int.Parse(Console.ReadLine());
                Console.WriteLine("Getting browser maximized and topomost");

                ShowBrowser((IntPtr)handler, HWND_TOPMOST);

                Console.WriteLine("Clicking on combobox");
                PutSingleClick((IntPtr)handler, x, y);
                Thread.Sleep(1000); // for content of combo full load
                Console.WriteLine("Putting keystrokes");
                int lastErr = -1;
                uint strokesPut = PutKeystroke(IntPtr.Zero, keystrokesCount, 1, out lastErr); // 1 = TRUE, is key down

                System.Threading.Thread.Sleep(5000);
                HideBrowser((IntPtr)handler, HWND_BOTTOM);

                Console.WriteLine("Keys down pressed, {0} would be choosen", (SYMBOLS)keystrokesCount);
                Console.WriteLine("From library: Sent {0} strokes, error: {1}", strokesPut, lastErr);
                Console.WriteLine("Press enter to continue");
                Console.ReadLine();

                ShowBrowser((IntPtr)handler, HWND_TOPMOST);
                PutSingleClick((IntPtr)handler, x, y);
                Thread.Sleep(1000);
                strokesPut = PutKeystroke(IntPtr.Zero, keystrokesCount + 5, 0, out lastErr);

                System.Threading.Thread.Sleep(5000);
                HideBrowser((IntPtr)handler, HWND_BOTTOM);

                Console.WriteLine("Keys up pressed, ALL would be choosen");
                Console.WriteLine("From library: Sent {0} strokes, error: {1}", strokesPut, lastErr);
                Console.WriteLine("Press enter to continue");
                Console.ReadLine();
            }
        }

        private static void ShowBrowser(IntPtr hwnd, IntPtr precHwnd)
        {
            Console.WriteLine("Showing browser...");
            ShowWindow(GetParent(hwnd), SW_SHOWMAXIMIZED);
            SetWindowPos(GetParent(hwnd), precHwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
        }

        private static void HideBrowser(IntPtr hwnd, IntPtr precHwnd)
        {
            Console.WriteLine("Hiding browser...");
            SetWindowPos(GetParent(hwnd), precHwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
            ShowWindow(GetParent(hwnd), SW_HIDE);
        }
    }

**** TradeInterop dll及其相关功能****

int _stdcall DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved)
{
    return true;
}

extern "C" __declspec(dllexport) void __stdcall PutSingleClick(HWND hwnd, int x, int y, BOOL needFocus = TRUE)
{
    if(needFocus == TRUE)
    {
        SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(0,0));
        SendMessage(hwnd, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(0,0));
    }
    SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x, y));
    SendMessage(hwnd, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(x, y));

}
extern "C" __declspec(dllexport) UINT __stdcall PutKeystroke(HWND hnd, int index, BOOL isDown, int& err)
{
    INPUT ip = {0};
    ip.type = INPUT_KEYBOARD;
    ip.ki.wVk =isDown? VK_DOWN : VK_UP;
    int times;
    if(index < 2)
        times = index+1;
    else
        times = index+2;

    INPUT ips[100] = {0};

    for(int i = 0; i < times*2; i+=2)
    {
        ip.ki.dwFlags = 0;
        ips[i] = ip;

        ip.ki.dwFlags = KEYEVENTF_KEYUP;
        ips[i+1] = ip;
    }

    ip.ki.dwFlags = 0;
    ip.ki.wVk = VK_RETURN;
    ips[times*2] = ip;

    ip.ki.dwFlags = KEYEVENTF_KEYUP;
    ips[(times*2)+1] = ip;
    err = -1;
    UINT s = SendInput((times*2)+2, &ips[0], sizeof(INPUT));
    err = GetLastError();
    return s;
}

重申C#部分与戴维斯的想法和建议,遗憾的是问题仍然存在

    using System;
using System.Threading;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Windows.Forms;

namespace clickTest1
{
    class Program
    {
        enum SYMBOLS
        {
            AUDJPY, AUDNZD, CADJPY, CHFJPY, EURAUD, EURGBP,
            EURJPY, EURUSD, GBPAUD, GBPJPY, GBPUSD, NZDJPY,
            NZDUSD, USDCAD, USDCHF, USDJPY, GOLD, UNKNOWN
        };

        const int SW_SHOWMAXIMIZED = 3;
        const int SW_HIDE = 0;
        const uint SWP_NOSIZE = 0x0001;
        const uint SWP_NOMOVE = 0x0002;
        const uint SWP_SHOWWINDOW = 0x0040;


        [DllImport(@"tradeInterop.dll")]
        public static extern void PutSingleClick(IntPtr hwnd, int x, int y);
        /*[DllImport(@"tradeInterop.dll")]
        public static extern uint PutKeystroke(IntPtr shouldBeNULL, int times, int isDown, out int err);*/
        [DllImport(@"user32.dll")]
        public static extern int SetWindowPos(IntPtr hwnd, IntPtr precendingHwnd, int x, int y, int cx, int cy, uint flags);
        [DllImport(@"user32.dll")]
        public static extern int ShowWindow(IntPtr hwnd, int cmdShow);
        [DllImport(@"user32.dll")]
        public static extern IntPtr GetParent(IntPtr hwnd);
        static void Main(string[] args)
        {
            UInt32 handler = 0;
            int x, y = 0;
            int keystrokesCount = 0;
            IntPtr HWND_BOTTOM = new IntPtr(1);
            IntPtr HWND_TOPMOST = new IntPtr(-1);
            UInt32 originalHandler = 0;
            while (true)
            {
                Console.WriteLine("H WND (hexadecimal) 0 = exit: ");
                handler = UInt32.Parse(Console.ReadLine(), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
                if (handler == 0)
                {
                    ShowBrowser((IntPtr)originalHandler, IntPtr.Zero);
                    break;
                }
                originalHandler = handler;
                HideBrowser((IntPtr)handler, HWND_BOTTOM);
                Console.WriteLine("X: ");
                x = int.Parse(Console.ReadLine());
                Console.WriteLine("Y: ");
                y = int.Parse(Console.ReadLine());
                Console.WriteLine("Choose instrument index (e.g. EURUSD=7)");
                keystrokesCount = int.Parse(Console.ReadLine());
                Console.WriteLine("Getting browser maximized and topomost");

                ShowBrowser((IntPtr)handler, HWND_TOPMOST);

                Console.WriteLine("Clicking on combobox");
                PutSingleClick((IntPtr)handler, x, y);
                Thread.Sleep(1000); // for content of combo full load
                Console.WriteLine("Putting keystrokes");
                for (int i = 0; i < (keystrokesCount < 2 ? keystrokesCount+1 : keystrokesCount+2); i++)
                {
                    SendKeys.SendWait("{DOWN}");
                }
                SendKeys.SendWait("{ENTER}");

                System.Threading.Thread.Sleep(5000);
                HideBrowser((IntPtr)handler, HWND_BOTTOM);

                Console.WriteLine("Keys down pressed, {0} would be choosen", (SYMBOLS)keystrokesCount);
                //Console.WriteLine("From library: Sent {0} strokes, error: {1}", strokesPut, lastErr);
                Console.WriteLine("Press enter to continue");
                Console.ReadLine();

                ShowBrowser((IntPtr)handler, HWND_TOPMOST);
                PutSingleClick((IntPtr)handler, x, y);
                Thread.Sleep(1000);
                for (int i = 0; i < keystrokesCount+5; i++)
                {
                    SendKeys.SendWait("{UP}");
                }
                SendKeys.SendWait("{ENTER}");
                System.Threading.Thread.Sleep(5000);
                HideBrowser((IntPtr)handler, HWND_BOTTOM);

                Console.WriteLine("Keys up pressed, ALL would be choosen");
                //Console.WriteLine("From library: Sent {0} strokes, error: {1}", strokesPut, lastErr);
                Console.WriteLine("Press enter to continue");
                Console.ReadLine();
            }
        }

        private static void ShowBrowser(IntPtr hwnd, IntPtr precHwnd)
        {
            Console.WriteLine("Showing browser...");
            ShowWindow(GetParent(hwnd), SW_SHOWMAXIMIZED);
            SetWindowPos(GetParent(hwnd), precHwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
        }

        private static void HideBrowser(IntPtr hwnd, IntPtr precHwnd)
        {
            Console.WriteLine("Hiding browser...");
            SetWindowPos(GetParent(hwnd), precHwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
            ShowWindow(GetParent(hwnd), SW_HIDE);
        }
    }
}

0 个答案:

没有答案