【问题标题】:Send ENTER key to console in form application in VB.NET在 VB.NET 的表单应用程序中将 ENTER 键发送到控制台
【发布时间】:2020-05-26 16:40:22
【问题描述】:

编辑:我的问题从未完全解决,但下面的答案提供了一个有趣的结果。

该应用程序最终将由 powershell 脚本调用,在这种情况下,我没有下面解释的问题。在 PS 控制台中不需要额外的 {ENTER},所以没有更多问题!通过 cmd.exe 手动启动我的应用程序时是否需要额外的 ENTER ,我不在乎


问题:在 VB.NET 中 表单应用程序,在代码完成运行后,我无法将控制台恢复为“默认”状态。我需要手动回车。

我的应用程序也可以从命令行执行(在这种情况下,没有打开任何表单。代码正在自动执行并将输出发送到控制台以供用户查看发生了什么)

我打电话给AttachConsole(-1),运行一些代码,当一切都完成后,我在控制台中看到了我的最新消息,但好像这个过程还没有完全完成。

我试过SendKeys.SendWait("{ENTER}")。它运作良好,但仅当控制台是当前焦点时。如果我在代码运行时单击控制台外部,则 ENTER 键将发送到我激活的任何窗口。

所以我尝试让控制台成为当前窗口:

Dim bProcess As Process = Process.GetProcessesByName("cmd").FirstOrDefault()
SetForegroundWindow(bProcess.MainWindowHandle)
// I also tried AppActivate(bProcess.Id)

SendKeys.SendWait("{ENTER}")

FreeConsole()

不,ENTER 键仍将发送到其他地方,而不是控制台。但它确实使控制台呈橙色闪烁,所以SetForegroundWindow 似乎在做某事......

任何帮助将不胜感激:)


编辑

回应@TnTinMn 的回答:

FreeConsole()
// SendKeys.SendWait("test")
PieceOfCodeFromTnTinMn()

与我到目前为止的行为相同:如果在代码运行时失去焦点,这会将SendKeys.SendWait("~")command 发送到控制台“外部”。

但是上面的第 2 行没有注释,“测试”被发送到控制台之外,SendKeys.SendWait("~") 被发送控制台,正如预期的那样。

我仍在试图弄清楚这里发生了什么......

【问题讨论】:

  • 尝试在您的应用程序退出之前调用FreeConsole
  • 感谢您的评论!我应该提到它,但我确实在发送 ENTER 命令后立即调用了 FreeConsole。
  • 当然,最好的解决方案是首先找到一种方法来避免需要一个奇怪的额外控制台窗口。
  • @JoelCoehoorn 实际上有一个控制台一直打开。我启动一个简单的 cmd.exe 进程,然后从这个控制台执行 myapp.exe 文件。

标签: windows vb.net winforms process console


【解决方案1】:

您可以在调用SendKeys.SendWait 之前使用VB Interaction.AppActivate Method 激活父控制台。这要求您获取作为应用程序父进程的控制台窗口的 ProcessID。

一种方法是使用 Windows Management Instrumentation (WMI)。以下内容并不漂亮,但似乎有效。你会在调用FreeConsole之后执行这个

Using currentProcess As Process = Process.GetCurrentProcess
  Dim query As New SelectQuery()
  Dim props As New StringCollection
  props.Add("ProcessId")
  props.Add("ParentProcessId")
  With query
    .ClassName = "Win32_Process"
    .Condition = $"ProcessId={currentProcess.Id}"
    .SelectedProperties = props
  End With

  Dim parentProcessId As Int32
  Using searcher As New ManagementObjectSearcher(query)
    Using mos As ManagementObjectCollection = searcher.Get
      Using en As ManagementObjectCollection.ManagementObjectEnumerator = mos.GetEnumerator
        If en.MoveNext() Then
          parentProcessId = CInt(en.Current.Item("ParentProcessId"))
        End If
      End Using 'en
    End Using ' mos
  End Using 'searcher

  If parentProcessId <> 0 Then
    AppActivate(parentProcessId)
    SendKeys.SendWait("~")
  End If
End Using 'currentProcess

【讨论】:

  • 感谢您的回答。它不太好用,但它可以做一些事情,哈哈。我编辑了我的问题
猜你喜欢
  • 2012-02-19
  • 1970-01-01
  • 2016-07-02
  • 2015-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-19
  • 2011-04-28
相关资源
最近更新 更多