Winapi F#System.Runtime.InteropServices对SendInput的本机库调用在.net framework中有效,但在.net core中无效
我正在将我为keybindings编写的一个小应用程序移植到.NETCore,我遇到了一个行为不同的实例。我用这份声明打电话给F#Winapi F#System.Runtime.InteropServices对SendInput的本机库调用在.net framework中有效,但在.net core中无效,winapi,f#,user32,sendinput,Winapi,F#,User32,Sendinput,我正在将我为keybindings编写的一个小应用程序移植到.NETCore,我遇到了一个行为不同的实例。我用这份声明打电话给F# open System.Runtime.InteropServices [<StructLayout(LayoutKind.Sequential)>] type private MOUSEINPUT = struct val dx: int32 val dy:int32 val mouseData:uint32 val
open System.Runtime.InteropServices
[<StructLayout(LayoutKind.Sequential)>]
type private MOUSEINPUT = struct
val dx: int32
val dy:int32
val mouseData:uint32
val dwFlags: uint32
val time: uint32
val dwExtraInfo: int
new(_dx, _dy, _mouseData, _dwFlags, _time, _dwExtraInfo) = {dx=_dx; dy=_dy; mouseData=_mouseData; dwFlags=_dwFlags; time=_time; dwExtraInfo=_dwExtraInfo}
end
[<StructLayout(LayoutKind.Sequential)>]
type private KEYBDINPUT = struct
val wVk: uint16
val wScan: uint16
val dwFlags: uint32
val time: uint32
val dwExtraInfo:int
new(_wVk, _wScan, _dwFlags, _time, _dwExtraInfo) = {wVk =_wVk; wScan = _wScan; dwFlags = _dwFlags; time = _time; dwExtraInfo = _dwExtraInfo}
end
[<StructLayout(LayoutKind.Sequential)>]
type private HARDWAREINPUT = struct
val uMsg: uint32
val wParamL: uint16
val wParamH: uint16
new(_uMsg, _wParamL, _wParamH) = {uMsg = _uMsg; wParamL = _wParamL; wParamH = _wParamH}
end
[<StructLayout(LayoutKind.Explicit)>]
type private LPINPUT = struct
[<FieldOffset(0)>]
val mutable ``type``:int // 1 is keyboard
[<FieldOffset(4)>]
val mutable mi : MOUSEINPUT
[<FieldOffset(4)>]
val mutable ki : KEYBDINPUT
[<FieldOffset(4)>]
val mutable hi : HARDWAREINPUT
end
module private NativeMethods =
[<DllImport("user32.dll", SetLastError=true)>]
extern uint32 SendInput(uint32 nInputs, LPINPUT* pInputs, int cbSize)
let appSignature = 0xA8969
let private createPressInput (code: int) =
let mutable input = LPINPUT()
input.``type`` <- InputModes.INPUT_KEYBOARD
input.ki <- KEYBDINPUT(uint16 code, uint16 0, Dwords.KEYEVENTF_KEYDOWN, uint32 0, appSignature)
input
let pressKey (code: int) =
let input = createPressInput code
NativeMethods.SendInput(uint32 1, &&input, Marshal.SizeOf(input)) |> ignore
最后我打开了一个关于这个的bug 这在.net中不是一个问题。显然,我的.NETFramework应用程序是以32位的速度运行的。我已经将
dwExtraInfo
字段声明为int
,这对于32位来说很好。我的.net核心应用程序以64位运行,我应该使用UIntPtr
来处理该字段长度的平台差异。更新到这个代码,它的工作
[<StructLayout(LayoutKind.Sequential)>]
type private MOUSEINPUT = struct
val dx: int32
val dy:int32
val mouseData:uint32
val dwFlags: uint32
val time: uint32
val dwExtraInfo: UIntPtr
new(_dx, _dy, _mouseData, _dwFlags, _time, _dwExtraInfo) = {dx=_dx; dy=_dy; mouseData=_mouseData; dwFlags=_dwFlags; time=_time; dwExtraInfo=_dwExtraInfo}
end
[<StructLayout(LayoutKind.Sequential)>]
type private KEYBDINPUT = struct
val wVk: uint16
val wScan: uint16
val dwFlags: uint32
val time: uint32
val dwExtraInfo: UIntPtr
new(_wVk, _wScan, _dwFlags, _time, _dwExtraInfo) = {wVk =_wVk; wScan = _wScan; dwFlags = _dwFlags; time = _time; dwExtraInfo = _dwExtraInfo}
end
[<StructLayout(LayoutKind.Sequential)>]
type private HARDWAREINPUT = struct
val uMsg: uint32
val wParamL: uint16
val wParamH: uint16
new(_uMsg, _wParamL, _wParamH) = {uMsg = _uMsg; wParamL = _wParamL; wParamH = _wParamH}
end
[<StructLayout(LayoutKind.Explicit)>]
type private InputUnion = struct
[<FieldOffset(0)>]
val mutable mi : MOUSEINPUT
[<FieldOffset(0)>]
val mutable ki : KEYBDINPUT
[<FieldOffset(0)>]
val mutable hi : HARDWAREINPUT
end
[<StructLayout(LayoutKind.Sequential)>]
type private LPINPUT = struct
val mutable ``type``: int // 1 is keyboard
val mutable u: InputUnion
end
[]
键入private MOUSEINPUT=struct
val-dx:int32
瓦迪:int32
瓦尔·穆塞达塔:uint32
val dwFlags:uint32
val时间:uint32
val dwExtraInfo:UINTPTTR
新建(_dx,_dy,_mouseData,_dwFlags,_time,_dwExtraInfo)={dx=_dx;dy=_dy;mouseData=_mouseData;dwFlags=_dwFlags;time=_time;dwExtraInfo=_dwExtraInfo}
结束
[]
键入private-KEYBDINPUT=struct
val wVk:uint16
val wScan:uint16
val dwFlags:uint32
val时间:uint32
val dwExtraInfo:UINTPTTR
新建(_wVk,_wScan,_dwFlags,_time,_dwExtraInfo)={wVk=_wVk;wScan=_wScan;dwFlags=_dwFlags;time=_time;dwExtraInfo=_dwExtraInfo}
结束
[]
类型private HARDWAREINPUT=struct
val uMsg:uint32
val wParamL:uint16
val wParamH:uint16
新的({uMsg,{wParamL,{wParamH)={uMsg={uMsg;wParamL={wParamL;wParamH=}
结束
[]
类型private InputUnion=struct
[]
val可变mi:鼠标输入
[]
val可变ki:KEYBDINPUT
[]
val可变高:硬件输入
结束
[]
类型private LPINPUT=struct
val可变``type`:int//1是键盘
val可变u:InputUnion
结束
主要区别在于
dwExtraInfo
字段定义。此外,现在有一个用于联合的显式类型,而不是将其全部滚动到一个LPINPUT
。这样,我就不必为3个可选字段指定字段偏移量,这3个字段也因平台而异。我根据您的代码构建了一个最小的复制。可以找到它。很抱歉,我没有更多的帮助。我还使用Csharp构建了一个复制程序。我把你的fsharp代码翻译成了csharp。同样的事情在dotnet框架中也可以很好地工作,但是显示了dotnet核心的错误代码87。很好,谢谢。我想这意味着这不是一个F#问题,而是一个.net核心问题。我确实设法找到了一个我不满意的解决方案。我将使用此解决方案更新原始问题。错误代码5可能与。您需要满足一些特定的要求。这是一条线索。
[<StructLayout(LayoutKind.Sequential)>]
type private MOUSEINPUT = struct
val dx: int32
val dy:int32
val mouseData:uint32
val dwFlags: uint32
val time: uint32
val dwExtraInfo: UIntPtr
new(_dx, _dy, _mouseData, _dwFlags, _time, _dwExtraInfo) = {dx=_dx; dy=_dy; mouseData=_mouseData; dwFlags=_dwFlags; time=_time; dwExtraInfo=_dwExtraInfo}
end
[<StructLayout(LayoutKind.Sequential)>]
type private KEYBDINPUT = struct
val wVk: uint16
val wScan: uint16
val dwFlags: uint32
val time: uint32
val dwExtraInfo: UIntPtr
new(_wVk, _wScan, _dwFlags, _time, _dwExtraInfo) = {wVk =_wVk; wScan = _wScan; dwFlags = _dwFlags; time = _time; dwExtraInfo = _dwExtraInfo}
end
[<StructLayout(LayoutKind.Sequential)>]
type private HARDWAREINPUT = struct
val uMsg: uint32
val wParamL: uint16
val wParamH: uint16
new(_uMsg, _wParamL, _wParamH) = {uMsg = _uMsg; wParamL = _wParamL; wParamH = _wParamH}
end
[<StructLayout(LayoutKind.Explicit)>]
type private InputUnion = struct
[<FieldOffset(0)>]
val mutable mi : MOUSEINPUT
[<FieldOffset(0)>]
val mutable ki : KEYBDINPUT
[<FieldOffset(0)>]
val mutable hi : HARDWAREINPUT
end
[<StructLayout(LayoutKind.Sequential)>]
type private LPINPUT = struct
val mutable ``type``: int // 1 is keyboard
val mutable u: InputUnion
end