タイトル : Re^9: Keybd_Eventでのモニターリセット 投稿日 : 2021/03/18(Thu) 17:31 投稿者 : 魔界の仮面弁士
※2021/03/19: コードを若干修正しました。(ParamArray 化) グラフィックドライバーの違いが原因なのか、 OS バージョンに依存する話であるのか…。 当方でも実験してみましたが、リセットされない要因については 現時点でははっきりしません。 ★ .NET Framework 4.8.4300.0【Windows 10 Pro (20H2)】物理マシン 上記環境においては、自作プログラムから GPU をリセットできました。 また、[スタート] - [Windows 簡単操作] - [スクリーン キーボード] からでもリセット可能なことを確認しました。 [Ctrl]+[Shift]を押しながらスクリーン キーボードを起動するパターンも 確認してみましたが、どうやら管理者モードの有無も無関係のようです。 ★ .NET Framework 4.8.4300.0【Windows 10 Pro (2004)】Hyper-V ゲスト ★ .NET Framework 4.7.3416.0【Windows 10 Enterprise 2016 LTSB (1607)】Hyper-V ゲスト ★ .NET Framework 4.7.3620.0【Windows Server 2016 Standard (1607)】Hyper-V ゲスト 上記環境においては、自作プログラムからの GPU リセットが動作しませんでした。 また、スクリーン キーボードからの操作も反応なしです。 Imports System Imports System.Windows.Forms Imports System.Runtime.InteropServices Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Text = $"64bitOS={Environment.Is64BitOperatingSystem}, 64bitProc={Environment.Is64BitProcess}, {RuntimeInformation.FrameworkDescription}" 'Text = $"{RuntimeInformation.OSDescription}, {RuntimeInformation.OSArchitecture} ({RuntimeInformation.ProcessArchitecture}) - {RuntimeInformation.FrameworkDescription}" End Sub Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click SendStrokes( Input.NewKeyboard(Keys.ControlKey, True), Input.NewKeyboard(Keys.ShiftKey, True), Input.NewKeyboard(Keys.LWin, True), Input.NewKeyboard(Keys.B, True) ) Await Task.Delay(TimeSpan.FromSeconds(0.2)) SendStrokes( Input.NewKeyboard(Keys.B, False), Input.NewKeyboard(Keys.ControlKey, False), Input.NewKeyboard(Keys.LWin, False), Input.NewKeyboard(Keys.ShiftKey, False) ) End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click SendStrokes( Input.NewKeyboard(Keys.ControlKey, True), Input.NewKeyboard(Keys.ShiftKey, True), Input.NewKeyboard(Keys.LWin, True), Input.NewKeyboard(Keys.B, True), Input.NewKeyboard(Keys.B, False), Input.NewKeyboard(Keys.ControlKey, False), Input.NewKeyboard(Keys.LWin, False), Input.NewKeyboard(Keys.ShiftKey, False) ) End Sub End Class Imports System Imports System.ComponentModel Imports System.Drawing Imports System.Runtime.InteropServices Imports System.Windows.Forms Public Module InputModule 'Public Sub SendStrokes(stroke() As Input) 'ParamArray に変更 Public Sub SendStrokes(ParamArray stroke() As Input) If If(stroke?.Length, 0) = 0 Then Return End If Dim count As Integer = SendInput(stroke.Length, stroke, Marshal.SizeOf(Of Input)()) If count = 0 Then Throw New Win32Exception() End If End Sub Private Declare Unicode Function GetMessageExtraInfo Lib "user32" () As IntPtr Private Declare Unicode Function SendInput Lib "user32" ( nInputs As Integer, <MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=0)> pInputs As Input(), cbsize As Integer) As Integer Public Enum InputType As Integer Mouse = 0 Keyboard = 1 Hardware = 2 End Enum <Flags> Public Enum KeyFlags As UShort None = 0 ExtendedKey = 1 KeyUp = 2 Unicode = 4 ScanCode = 8 End Enum <Flags> Public Enum MouseFlags As UShort None = &H0 Move = &H1 LeftDown = &H2 LeftUp = &H4 RightDown = &H8 RightUp = &H10 MiddleDown = &H20 MiddleUp = &H40 XDown = &H80 XUp = &H100 Wheel = &H800 HWheel = &H1000 Move_NoCoalesce = &H2000 VirtualDesk = &H4000 Absolute = &H8000 End Enum <StructLayout(LayoutKind.Sequential)> Public Structure Input Public Type As InputType Public Union As InputUnion Public Shared Function NewKeyboard(wVk As UShort, wScan As UShort, dwFlags As UInteger) As Input Dim t As New Input() With {.Type = InputType.Keyboard} With t.Union.Keyboard .VirtualKey = wVk .ScanCode = wScan .Flags = dwFlags .Time = 0 .ExtraInfo = GetMessageExtraInfo() End With Return t End Function Public Shared Function NewKeyboard(virtualKey As Keys, pushed As Boolean) As Input Return NewKeyboard(CUShort(virtualKey), 0US, CUShort(If(pushed, KeyFlags.None, KeyFlags.KeyUp))) End Function Public Shared Function NewMouse(dx As Integer, dy As Integer, dwFlags As MouseFlags, mouseData As UInteger) As Input Dim t As New Input() With {.Type = InputType.Mouse} With t.Union.Mouse .X = 0 .Y = 0 .Data = mouseData .Flags = dwFlags .Time = 0 .ExtraInfo = GetMessageExtraInfo() End With Return t End Function Public Shared Function NewHardware(uMsg As UInteger, wParamH As UShort, wParamL As UShort) As Input Dim t As New Input() With {.Type = InputType.Hardware} With t.Union.Hardware .Msg = uMsg .WParamH = wParamH .WParamL = wParamL End With Return t End Function Public Shared Function NewHardware(uMsg As UInteger, wParam As UInteger) As Input Dim t As New Input() With {.Type = InputType.Hardware} With t.Union.Hardware .Msg = uMsg .WParamH = CUShort(wParam And &HFFFFUS) .WParamL = CUShort(wParam >> 16) End With Return t End Function End Structure <StructLayout(LayoutKind.Explicit)> Public Structure InputUnion <FieldOffset(0)> Public Mouse As MouseInput <FieldOffset(0)> Public Keyboard As KeyboardInput <FieldOffset(0)> Public Hardware As HardwareInput End Structure <StructLayout(LayoutKind.Sequential)> Public Structure MouseInput Public X As Integer Public Y As Integer Public Data As UInteger Public Flags As UInteger Public Time As UInteger Public ExtraInfo As IntPtr End Structure <StructLayout(LayoutKind.Sequential)> Public Structure KeyboardInput Public VirtualKey As UShort Public ScanCode As UShort Public Flags As UInteger Public Time As UInteger Public ExtraInfo As IntPtr End Structure <StructLayout(LayoutKind.Sequential)> Public Structure HardwareInput Public Msg As UInteger Public WParamL As UShort Public WParamH As UShort End Structure End Module |