User32 API custom PostMessage for automatisation

2020-05-29 06:34发布

问题:

I want to automate a program called Spotify from C#, the best way (I think) to do this is by triggering fake keypresses. I want to program to pause playback, and I don't know enough about this stuff to find another way than keypresses. So I use Visual Studio's Spy++ to see what message Spotify gets when pressing the play button on my keyboard, I copy the data from that message into my Console Application and run it, when I run I can see the PostMessage in Spy++'s Message Logging, so this is working but it doesn't pause/play my music. I guess this is because I also have to send another PostMessage with another destination, but how do I know what else to send?

Post Message call:

MessageHelper.PostMessage((int)hwndSpotify, 0x100, 0x000000B3, 0x01000001);

I hope someone is familiar with this and can help me out.

回答1:

To automate Spotify, first you have to get the handle of the window with the following class name: SpotifyMainWindow (using FindWindow()).

Then, you can use the SendMessage() method to send a WM_APPCOMMAND message to the Spotify's window.

Following a simple code to do that:

internal class Win32
{
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    internal static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

    internal class Constants
    {
        internal const uint WM_APPCOMMAND = 0x0319;
    }
}

public enum SpotifyAction : long
{ 
    PlayPause = 917504,
    Mute = 524288,
    VolumeDown = 589824,
    VolumeUp = 655360,
    Stop = 851968,
    PreviousTrack = 786432,
    NextTrack = 720896
}

For instance, to play or pause the current track:

Win32.SendMessage(hwndSpotify, Win32.Constants.WM_APPCOMMAND, IntPtr.Zero, new IntPtr((long)SpotifyAction.PlayPause));


回答2:

Pressing the "play buttion" results in a virtual key code - for an official list see http://msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx .

There you find for example VK_VOLUME_UP VK_MEDIA_PLAY_PAUSE VK_ZOOM .

Even some Remotes translate to these codes to be as compatible as possible with existing software.

These were introduced back in the day when Windows ME (!) came out and are still in use - at least when I checked the registry of my Windows 2008 R2 !

Basically Windows translates certain VK* into WM_APPCOMMAND messages with certain codes which the applications listen to...
If the key has something to do with launching an app to do (i.e. Mail, Browser etc.) then the magic happens via Windows Explorer which reads the mapping (either by association or direct exec) from the registry at Software\ Microsoft\ Windows\ CurrentVersion\ Explorer\ AppKey - either HKLM or HKCU.

Some links with old but as it seems still valid information:

  • http://msdn.microsoft.com/en-us/windows/hardware/gg463446.aspx
  • http://msdn.microsoft.com/en-us/windows/hardware/gg462991
  • http://msdn.microsoft.com/en-us/windows/hardware/gg463372