Open a directory in File Explorer from the console and return focus back to the console

让人想犯罪 __ 提交于 2020-01-23 17:28:30

问题


Using the following code I can open a folder in Explorer in Windows 10:

require('child_process').exec('start "" "c:\\test"');

This works well. However, focus is given to the newly opened window. I'm using this from a node script and am prompting for input from the user after the window has been opened. This is annoying to the user as they have to manually click inside the console window to respond to the input request.

Is there any way that the above command can be modified to either not give focus to the opened window in the first place. Or, force focus to return to the console window?


回答1:


Note:

  • This answer should work even from Git Bash.

  • Since the code involves creating a PowerShell process and code that involves on-demand compilation of C# code, the solution is slow.

  • The File Explorer window briefly receives focus, but the previously active window is reactivated right away.

  • While the Shell.Application COM object's .ShellExcecute() method would make for a simpler and faster solution, its ability to launch a process without window activation unfortunately doesn't work with explorer.exe.

require('child_process').execFile(
  'powershell.exe', 
  [ 
    '-NoProfile',
    '-Command', 
    `
    $type = Add-Type -PassThru -Namespace Util -Name WinApi -MemberDefinition '[DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();'
    # Get the current foreground window.
    $hwndBefore = $type::GetForegroundWindow()
    # Open the target folder in File Explorer
    Start-Process 'c:\\temp'
    # Wait for a different window - assumed to be the File Explorer window - to become active.
    while ($hwndBefore -eq $type::GetForegroundWindow()) { Start-Sleep -Milliseconds 200 }
    Start-Sleep -Milliseconds 200
    # Put focus back on the previous foreground window.
    $null = $type::SetForegroundWindow($hwndBefore)
    `
  ]
 );

Note: I've used an ES6 template literal (`...`) above, for the convenience of being able to define multi-line strings with it; conceptually, the above is a verbatim string. Beware of PowerShell constructs such as ${var} inside a template literal, because they would be interpreted as JavaScript expressions to expand, up front.



来源:https://stackoverflow.com/questions/59755890/open-a-directory-in-file-explorer-from-the-console-and-return-focus-back-to-the

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