Send ENTER key to console in form application in VB.NET

左心房为你撑大大i 提交于 2020-08-09 09:44:42

问题


edit: My issue was never quite resolved, but the answer below provided an interesting result.

The app will eventually be called by a powershell script and in this situation, I don't have the issue explained below. No additional {ENTER} is required in the PS console, so no more issue! I couldn't care less if an extra ENTER is required when my app is launched manually via cmd.exe


Problem: In a VB.NET form app, I'm unable to get the console back to it's "default" state after the code is finished running. I need to press enter manually.

My app can also be executed from command line (in this case, no form is opened. Code is being executed automatically and output sent to console for user to see what happens)

I call AttachConsole(-1), run some code, and when everything's finished I see my latest message in console, but it's as if the process wasn't quite finished.

I have tried SendKeys.SendWait("{ENTER}"). It works well, but only when the console is the current focus. If I click outside the console while the code is running, the ENTER key is sent to whichever window I made active.

So I tried to make the console the current window:

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

SendKeys.SendWait("{ENTER}")

FreeConsole()

Nope, the ENTER key will still be sent somewhere else and not to the console. But it does make the console blink orange, so SetForegroundWindow seems to do something...

Any help will be greatly appreciated :)


EDIT

In response to @TnTinMn's answer:

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

Same behavior as I've had so far: This will send the SendKeys.SendWait("~")command "outside" the console if it loses focus while the code is running.

BUT with the 2nd line above un-commented, "test" is sent outside the console and SendKeys.SendWait("~") is sent to the console, as expected.

I'm still trying to figure out what is happening here...


回答1:


You can use the VB Interaction.AppActivate Method to activate the parent console prior to calling SendKeys.SendWait. This requires that you obtain the ProcessID of the console window that is the parent process of your application.

One way to do this is using Windows Management Instrumentation (WMI). The following is not pretty, but it appears to work. You would execute this after calling 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


来源:https://stackoverflow.com/questions/62027134/send-enter-key-to-console-in-form-application-in-vb-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!