使用User32.dll将输入发送到不同的窗口

时间:2015-12-04 21:54:08

标签: c# .net

我正在尝试将关键命令从我的程序发送到另一个程序,但它目前无法正常工作。 这与在不同程序中完全正常工作的完全相同的实现无关。

其他窗口的激活工作正常,但没有扫描码发送给它。

非常感谢帮助。

这是我的代码

[DllImport( "User32.dll" )]
private static extern int SetForegroundWindow( IntPtr point );

[DllImport( "User32.dll" )]
private static extern bool ShowWindow( IntPtr hWnd, int nCmdShow );

public void SendKeyBind( ) {
        if ( Main.Device == DeviceType.Keyboard ) {
            SetForegroundWindow( EliteDangerousPointer );
            ShowWindow( EliteDangerousPointer, 5 );

            List<uint> modifiersSC = Modifiers.ConvertAll( x => ConvertKeyToSC( x.Key ) );
            uint mainSC = ConvertKeyToSC( Main.Key );

            foreach ( uint msc in modifiersSC )
                SendKey( msc, KeyFlag.KeyDown | KeyFlag.Scancode );
            SendKey( mainSC, KeyFlag.KeyDown | KeyFlag.Scancode );
            System.Threading.Thread.Sleep( 100 );
            SendKey( mainSC, KeyFlag.KeyUp | KeyFlag.Scancode );
            foreach ( uint msc in modifiersSC )
                SendKey( msc, KeyFlag.KeyUp | KeyFlag.Scancode );
        }
    }

[DllImport( "User32.dll" )]
private static extern uint MapVirtualKey( uint uCode, uint uMapType );

private uint ConvertKeyToSC( Keys key ) {
    uint keyCode = (uint)key;
    uint scanCode = MapVirtualKey(keyCode, 0);
    return scanCode;
}

使用此类与using static实际发送扫描码

public static class VirtualKeyboard {

    [StructLayout( LayoutKind.Sequential )]
    internal struct KEYBOARDINPUT {
        public uint type;
        public ushort vk;
        public ushort scanCode;
        public uint flags;
        public uint time;
        public uint extrainfo;
        public uint padding1;
        public uint padding2;
    }

    [StructLayout( LayoutKind.Sequential )]
    internal struct MOUSEINPUT {
        public uint dx;
        public uint dy;
        public uint mouseData;
        public uint dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }

    [StructLayout( LayoutKind.Sequential )]
    internal struct HARDWAREINPUT {
        public int uMsg;
        public short wParamL;
        public short wParamH;
    }

    [StructLayout( LayoutKind.Explicit )]
    internal struct INPUT {

        [FieldOffset(0)]
        public int type;

        [FieldOffset(4)]
        public MOUSEINPUT mi;

        [FieldOffset(4)]
        public KEYBOARDINPUT ki;

        [FieldOffset(4)]
        public HARDWAREINPUT hi;
    }

    [DllImport( "User32.dll" )]
    private static extern uint SendInput( uint numberOfInputs, ref INPUT input,
    int structSize );

    [Flags]
    public enum KeyFlag {
        KeyDown = 0x0000,
        KeyUp = 0x0002,
        Scancode = 0x0008
    }

    public static void SendKey( uint keyCode, KeyFlag keyFlag ) {
        INPUT InputData = new INPUT();

        InputData.type = 1;
        InputData.ki.scanCode = ( ushort ) keyCode;
        InputData.ki.flags = ( uint ) keyFlag;
        Console.WriteLine( InputData.ki.scanCode );
        Console.WriteLine( keyCode );

        SendInput( ( uint ) 1, ref InputData, ( int ) Marshal.SizeOf( typeof( INPUT ) ) );
    }
}

1 个答案:

答案 0 :(得分:0)

当Windows Messenger是一个东西,我做了一个实用程序来自动打开并输入我的电子邮件和密码,也许这种方法适合你:

using System.Runtime.InteropServices;
using System.Security.Cryptography;

[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);



System.Diagnostics.Process.Start("C:\\Program Files (x86)\\Windows Live\\Messenger\\msnmsgr.exe");
IntPtr msnHandle = FindWindow("SharedSigninDialogClass", "Windows Live Messenger");

while (msnHandle == IntPtr.Zero)
{
    System.Threading.Thread.Sleep(100);
    msnHandle = FindWindow("SharedSigninDialogClass", "Windows Live Messenger");
}
SetForegroundWindow(msnHandle);
SendKeys.SendWait("my_awesomeEmail@hotmail.com");
SendKeys.SendWait("{TAB}");
SendKeys.SendWait("myawesomepassword");
SendKeys.SendWait("{ENTER}");