【问题标题】:InputSimulator works while debugging but not when program is builtInputSimulator 在调试时工作,但在构建程序时不工作
【发布时间】:2017-07-09 15:36:01
【问题描述】:

在我的项目中,我使用了 inputsimulator,当 Visual Studio 以管理员身份运行时效果很好,但是当我将其构建为 .exe 时,即使我以管理员身份运行它也无法正常工作。这是我的代码

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    AutoSaveTimer.Enabled = True

    Try
        System.Threading.Thread.Sleep(50)
        GameConnection.SendKeyTo(Keys.OemSemicolon)
        System.Threading.Thread.Sleep(2000)
        GameConnection.SendKeyTo(Keys.K)
        System.Threading.Thread.Sleep(50)
        GameConnection.SendKeyTo(Keys.Enter)

    Catch AutoSaveExeption As GameException
        If AutoSaveExeption.GameErrorCode = GameError.GAME_ERR_SENDMSG Then
            ' Send message error - connection to Game lost.
            ' 
            MessageBox.Show("cant make a connection.... can't autosave sadly", AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            SimConnectionBar.BackColor = Color.Red
        End If
    End Try
End Sub

它确实将焦点发送到我指定的窗口,但它不发送击键

【问题讨论】:

  • 通过将每一行缩进四个空格来格式化您的代码。使用反引号 ` 仅适用于 inline code,例如在提及有关 Button1 或 ListBox 等的内容时。有关更多信息,请参阅 Markdown and formatting help。
  • 这应该可行,但另一种选择是挂接到游戏的消息循环或简单地将消息发布到游戏的消息循环。使用此代码,我看不出它可以在调试中工作但不能在发布中工作的任何原因。你在调用winAPI'SetForegroundWindow'吗?你怎么知道游戏有焦点?您应该在发送输入之前调用 API。
  • 好的,这是一个按钮点击事件,这意味着在运行此代码时您的应用程序具有焦点。您需要在此方法中调用 SetForegoundWindow。你能掌握游戏的手柄吗?
  • 或者在开始时创建一个延迟,让您有时间将窗口切换回游戏。
  • 不要使用按钮单击,当单击它会为您的应用程序提供焦点,而是尝试使用热键。当您的应用程序收到按下特定热键的消息时,您可以执行此代码。这意味着您可以在游戏中按下一个热键来告诉您的应用程序做某事。你的应用永远不需要关注这个。如果您想尝试热键,请告诉我,我可以给您发送示例。

标签: vb.net keyboard keystrokes


【解决方案1】:

在发送任何输入之前尝试使用 SetForegroundWindow 以确保您的游戏确实具有焦点。应在发送输入之前在您的方法中调用 SetForegroundWindow。

    <DllImport("user32.dll")> _
Public Shared Function SetForegroundWindow(hWnd As IntPtr) As Boolean
End Function


Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click `
AutoSaveTimer.Enabled = True
Try
    'Find the handle to the game. This can do it by searching for the process.
        Dim p As System.Diagnostics.Process() = System.Diagnostics.Process.GetProcessesByName("notepad")
        'search for process notepad
        If p.Length > 0 Then
            'check if window was found
            'bring notepad to foreground
            SetForegroundWindow(p(0).MainWindowHandle)
        End If

        System.Threading.Thread.Sleep(50)
        GameConnection.SendKeyTo(Keys.OemSemicolon)
        System.Threading.Thread.Sleep(2000)
        GameConnection.SendKeyTo(Keys.K)
        System.Threading.Thread.Sleep(50)
        GameConnection.SendKeyTo(Keys.Enter)

    Catch AutoSaveExeption As GameException
        If AutoSaveExeption.GameErrorCode = GameError.GAME_ERR_SENDMSG Then
            ' Send message error - connection to Game lost.
            ' 
            MessageBox.Show("cant make a connection.... can't autosave sadly", AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            SimConnectionBar.BackColor = Color.Red
        End If
    End Try
end sub

【讨论】:

  • 我得到 3 个错误:语句不能出现在方法主体之外...声明预期(在 SetForegroundWindow 上)...结束 if 必须前面有一个匹配的 if...
  • PInvoke 声明必须在函数之外。这只是示例代码。让我更新一下它在您的代码中的外观。
  • 查看更新的代码。您还需要确保您的游戏在 timer elapsed 方法中也具有焦点,否则无法保证您的游戏具有焦点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-15
  • 2015-03-27
  • 1970-01-01
  • 1970-01-01
  • 2020-04-05
相关资源
最近更新 更多