17

Is there an command i can use on cmd to switch to/focus on selected app window?

Lets say i have three apps working: A, B, C and currently i m focused on B. Is there a command (not shortcut) to switch to/focus on app A?

Maybe can i do it with batch?

Im working on windows.

regularny
  • 385
  • 1
  • 2
  • 11

5 Answers5

17

try with sendKeys.bat :

call sendkeys.bat "Title A" ""

The first argument is the beginning of the title you want to switch to (if it is Some Title you can use only Some if it is unique enough). Second argument are empty double quotes. In general the script is used to send keys to a particular window. But if you left the second parameter empty (like "") it will not send any keys.

Community
  • 1
  • 1
npocmaka
  • 55,367
  • 18
  • 148
  • 187
  • Thank, this script help me a lot! – regularny Mar 15 '16 at 12:00
  • 1
    @Garric - there's a code that activates the window - `if (sh.AppActivate(title)){` , also the OP accepted the answer . The answer itself explain the rest. – npocmaka May 28 '20 at 10:50
  • 1
    Thanks. I was looking for a similar function – Garric May 29 '20 at 14:28
  • This .bat file seems not working if the window is minimized... is there a way to solve this? – shelper May 19 '21 at 20:32
  • @shelper there is , but requires a call to another script - check this: https://github.com/npocmaka/batch.scripts/blob/master/hybrids/.net/c/windowMode.bat - check the usage with `-h` – npocmaka May 20 '21 at 07:23
  • @npocmaka interestingly, `sendkeys` finds window with title "title1 title2" by either "title1" or "title2" but `windowMode` can only find window using the beginning word "title1". `sendkeys` always bring window to front but cannot find minimized window, and `windowMode` can find minimized window but does not bring window to front. Would be nice if they can merge some features. – shelper May 20 '21 at 15:01
  • @shelper - Isn't an option to use both tools in your script? – npocmaka May 21 '21 at 04:09
  • 1
    @npocmaka it seems impossible even by both tools if I want to find a minimized window "title1 title2" by "title2" and bring it to front ... – shelper May 21 '21 at 14:41
  • @shelper do you know the PID of the window? Another option is to use [TASKLIST](https://ss64.com/nt/tasklist.html) and filter the process with FIND and then to use windowMode.bat with the PID. – npocmaka May 21 '21 at 14:56
  • @npocmaka humm, PID changes if i restart the program... TASKLIST may work, thanks for the suggestion... – shelper May 21 '21 at 15:03
  • @shelper you can do it with a tiny C++ program. Check out my answer and look up how to find window by title. After finding the title, you can easily parse it and get the `title2`. – ScienceDiscoverer Aug 23 '23 at 13:54
9

This should work:

echo (new ActiveXObject("WScript.Shell")).AppActivate("app A"); > focus.js
cscript //nologo focus.js
del focus.js
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • this used to work for me fine then one day I starte getting errors: `Access is denied. Input Error: Can not find script file "C:\focus.js". Could Not Find C:\focus.js` – Kalamalka Kid Jun 03 '20 at 06:04
  • This works and has the benefit of being clear on how it works. npocmaka's script actually does the same within. – 8ctopus Jan 10 '23 at 06:09
  • It's pretty clear yes, but it also does nothing. "app A" doesn't even blik in the taskbar, nothing happens at all. Any tips ? – Charles Feb 17 '23 at 12:55
  • @Charles Be sure that the "app A" title exactly matches the title of the desired window, or at least its beginning... This code had proven to work many times before. – Aacini Feb 17 '23 at 16:28
  • Oh WINDOW !! And not app ! My app names its windows ... the window name will ultimately contain the app name, but not right away at all. Any way to find it, nonetheless ? I also happen to have a way to access the specific window names, because they are the name of files that I ask the app to open, and so I have those file names ... but that's just luck really. – Charles Feb 20 '23 at 10:42
  • @Charles: perhaps if you post three or four window _titles_ and the file names they comes from we could figure out the method used to create the titles – Aacini Feb 20 '23 at 18:54
  • Just to be clear. I CAN get this to work by using the file names (since I luckily happen to have them). It works. I'm just wondering. The way my app (Qt Creator) creates window names is : ` ( @ ) [] - - Qt Creator` e.g. `geometry.c (source\utils @ serverSide) [develop] - myApp - Qt Creator` – Charles Feb 21 '23 at 08:59
0

My solution in this gist is very much based on @npocmaka's answer, but it gives a more complete and exact answer to the OPs specific question (I had to incorporate a couple more references to get to this): it activates and restores the named app if it is already running, or starts it if not.

I'll repeat the code here for completeness - replace the image name of the app and the path required to start it as you need:

@if (@X)==(@Y) @end /* JScript comment 

@echo off 
setlocal
for /f "tokens=2" %%i in ('tasklist /FI "IMAGENAME eq Fork.exe" ^| find /I "Fork.exe"') do set pid=%%i
if "%pid%" == "" (
    %localappdata%\Fork\Fork.exe
) else (
    cscript //E:JScript //nologo "%~f0" "%~nx0" "%pid%"
)
exit /b %errorlevel% 
endlocal

@if (@X)==(@Y) @end JScript comment */ 

var sh=new ActiveXObject("WScript.Shell"); 
if (sh.AppActivate(WScript.Arguments.Item(1)) == 0) {
    sh.SendKeys("% r"); 
}
MikeBeaton
  • 3,314
  • 4
  • 36
  • 45
0

Powershell -command "$wshell = New-Object -ComObject wscript.shell ; $wshell.AppActivate('App title')"

P.Hkp
  • 9
  • 2
0

Here is my solution in pure Windows API:

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#pragma comment( lib, "user32" )

#include "types.h"

i32 wmain(ui64 argc, wchar_t **argv)
{
    if(argc != 2)
    {
        return 1;
    }
    
    // Find window by Class Name
    HWND wnd = NULL;
    ui64 tries = 100;
    while(--tries != UI64_MAX)
    {
        wnd = FindWindow(argv[1], NULL);
        if(wnd != NULL)
        {
            break;
        }
        Sleep(50);
    }
    
    if(wnd == NULL)
    {
        return 2;
    }
    
    AllowSetForegroundWindow(ASFW_ANY);
    
    DWORD cur_thread = GetCurrentThreadId();
    DWORD fg_pid = 0;
    DWORD fg_thread = GetWindowThreadProcessId(wnd, &fg_pid);
    
    AttachThreadInput(cur_thread, fg_thread, TRUE);
    SetFocus(wnd);
    SetForegroundWindow(wnd);
    ShowWindow(wnd, SW_NORMAL);
    AttachThreadInput(cur_thread, fg_thread, FALSE);
    
    SetWindowPos(wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
    
    return 0;
}

Compile it and just call the compiled program with the argument of the window's class name. You can get window's class name with programs like WinSpy++ or similar. If you want it to search by title, I think you can easily modify it yourself. There is tons of info on how to find window handle by title.

Oh yes, it also restores window if it is currently minimised.

If it fails to find the window, it keeps trying up to 100 times with 50 ms intervals (so total 5 seconds), after that it gives up. It is useful if you are starting some program from CMD, and it takes a few seconds to start up, but you want it brought to focus immediately after its ready.

ScienceDiscoverer
  • 205
  • 1
  • 3
  • 13