Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simulating keystrokes with Haskell on Windows

I am trying to write a Haskell program that simulates keystrokes on Windows. I tried to call keybd_event and SendInput, but neither one compiled. I can run the program with the interpreter, though. When I try to build the program when it contains a binding to SendInput in winable.h, I get the error:

cabal install
...
[1 of 2] Compiling WindowsKeys      ( dist\build\WindowsKeys\WindowsKeys-tmp\WindowsKeys.hs, dist\build\WindowsKeys\WindowsKeys-tmp\WindowsKeys.o )
[2 of 2] Compiling Main             ( src\Main.hs, dist\build\WindowsKeys\WindowsKeys-tmp\Main.o )
Linking dist\build\WindowsKeys\WindowsKeys.exe ...
dist\build\WindowsKeys\WindowsKeys-tmp\WindowsKeys.o:fake:(.text+0x35d): undefined reference to `SendInput'
collect2: ld returned 1 exit status
cabal: Error: some packages failed to install:
WindowsKeys-0.1.0.0 failed during the building phase. The exception was:
ExitFailure 1

The verbose error is at http://pastebin.com/trg21N0x , but it doesn't seem to contain any more clues. I get a similar error when I try to use keybd_event. The hsc file I wrote includes these headers:

#include "windows.h"
#include "winuser.h"
#include "winable.h"

Here is the C binding:

foreign import ccall unsafe "winable.h SendInput"
        c_SendInput :: UINT
                    -> Ptr Input
                    -> CInt
                    -> IO UINT

I assumed that I could not call SendInput on winuser.h because of the #if :

#if (_WIN32_WINNT >= 0x0403)
WINUSERAPI UINT WINAPI SendInput(UINT,LPINPUT,int);

When I add a binding for _WIN32_WINNT , the value is 0x400.

I have version 2012.4.0.0 of the Haskell Platform. It came with a folder of headers containing the ones that I included. I could not find any other headers with the same names on my computer. I am using Windows 7 Professional, version 6.1 .

Thank you!

Here is WindowsKeys.cabal :

-- Initial WindowsKeys.cabal generated by cabal init.  For further 
-- documentation, see http://haskell.org/cabal/users-guide/

name:                WindowsKeys
version:             0.1.0.0
build-type:          Simple
cabal-version:       >=1.8
extra-source-files:  windows.h, winuser.h, winable.h

executable WindowsKeys
  main-is:             Main.hs
  other-modules:       WindowsKeys
  build-depends:       base ==4.5.*, Win32 ==2.2.*
  hs-source-dirs:      src
  build-tools:         hsc2hs
  extra-libraries:     user32
  include-dirs:        src

The build succeeds when I comment out the bindings to the keyboard functions.

like image 727
user2917747 Avatar asked Nov 12 '22 19:11

user2917747


1 Answers

I finally found that I had used the wrong calling convention. keybd_event and SendInput both need to be called with stdcall instead of ccall.

like image 154
user2917747 Avatar answered Nov 15 '22 06:11

user2917747