Как найти заголовок окна активного (переднего плана) окна с помощью Window Script Host

Я хочу найти заголовок окна, которое в данный момент активно (имеет фокус), с помощью Window Script Host(WSH), потому что я хочу, чтобы мой сценарий WSH работал только с Sendkeys, если желаемое окно активно.

Примечание * Я не в состоянии использовать альтернативу, т.е. активировать желаемое окно перед вызовом sendkeys.

Любая помощь приветствуется.

4 ответа

Краткий ответ: вы не можете. По крайней мере, без написания оболочки COM для соответствующих вызовов Windows API.

Вы не можете просто использовать AppActivate и проверить результат?

Set oShell = CreateObject("WScript.Shell")
If oShell.AppActivate "Untitled - Notepad" Then
  oShell.SendKeys "Hello, world!"
End If


Длинный ответ: чтобы получить активный заголовок окна, вам нужно вызвать Windows API GetWindowText функционировать и передать GetForegroundWindow()справиться. VBScript и Windows Script Host не поддерживают вызовы Windows API, поэтому вам нужно написать обертку COM вокруг этих функций, которую вы затем сможете использовать в своем скрипте. Вот примеры:

Получить текущий активный заголовок окна в C

Как я могу получить заголовок текущего активного окна, используя C#?

Вы можете создать COM-объект с помощью GetForegroundWindow и GetWindowText.

Поместите следующие строки в wso.cls и сохраните папку wso на рабочем столе.

Imports System
Imports System.Runtime.InteropServices
Imports Microsoft.Win32

Namespace WindowScriptingObject

    <Guid("7448E08D-ED0F-4E23-B528-91937BB41756"), _
    InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
   Public Interface _WindowScriptingObject
        <DispId(1)> Function ActiveWindow() As Integer
        <DispId(2)> Function WindowText(ByVal hWnd As Integer) As String
    End Interface

    <Guid("B146BF9E-78FC-4DB0-ABFE-9FF026B43E4D"), _
     ClassInterface(ClassInterfaceType.None), _
     ProgId("WindowScriptingObject")> Public Class WindowScriptingObject
        Implements _WindowScriptingObject

        Public WindowScriptingObject()

        Public Declare Auto Function GetForegroundWindow Lib "user32" Alias "GetForegroundWindow"() As Integer
        Public Declare Auto Function GetWindowText Lib "user32.dll" (ByVal hwnd As Int32, <Out()> ByVal lpString As System.Text.StringBuilder, ByVal cch As Int32) As Int32
        Public Function ActiveWindow() As Integer Implements _WindowScriptingObject.ActiveWindow
    ActiveWindow=GetForegroundWindow()

        End Function

        Public Function WindowText(hwnd as Integer) As String Implements _WindowScriptingObject.WindowText
    on error resume next
    Dim b As New System.Text.StringBuilder(ChrW(0), 512)
                Dim ret = GetWindowText(hWnd, b, b.Capacity)
    WindowText = b.tostring
        End Function


    End Class

End Namespace

Затем создайте файл bat в той же папке с именем wso.bat.

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\vbc.exe" /target:library /out:"%userprofile%\desktop\wso\wso.dll" "%userprofile%\desktop\wso\wso.cls" /verbose

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm" /codebase "%userprofile%\desktop\wso\wso.dll" /tlb:"%userprofile%\desktop\wso\wso.tlb" /v

If /i "%cmdcmdline:~0,6%"=="cmd /c" pause

Использовать в vbs после запуска bat-файла.

Set wso=CreateObject("WindowScriptingObject")
x = wso.ActiveWindow
msgbox x, , "vbs"
msgbox wso.windowtext(x), , "vbs"

Используемые здесь GUID специфичны для этого проекта. Не используйте их для других целей.

Больше информации о том, что мы делаем

http://social.msdn.microsoft.com/Forums/en-US/adcae113-4758-481a-a367-60d5d14d97d6/this-is-how-to-turn-vbs-and-js-files-into-exe-files-from-the-command-line-without-third-party-tools?forum=scripting

Если вам необходимо выполнить установку для каждого пользователя, используйте regasm, чтобы создать regfile, а не регистрировать его. Затем измените все ссылки на HKCR в HKCU\Software\Classes, Затем слить с regedit /s regfile.reg,

Чтобы переместить файл, вам нужно запустить Regasm на новом месте. Смотрите команду в файле bat.

Будут выставлены на сайте MS, конечно, для точных исторических целей.

Это обновленная версия для использования. Предыдущий ответ - минимум, необходимый для его работы.

Это также заменяет ответ здесь ( appactivate между несколькими экземплярами Internet Explorer), так как он не работал для Windows 7 и более поздних версий из-за того, что sendmail был зарезервированным именем в этих ОС.

Imports System
Imports System.Runtime.InteropServices
Imports Microsoft.Win32

Namespace WindowScriptingObject

    <Guid("7448E08D-ED0F-4E23-B528-91937BB41756"), _
    InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
   Public Interface _WindowScriptingObject
        <DispId(1)> Function ActiveWindow() As UInteger
        <DispId(2)> Function WindowText(ByVal hWnd As UInteger) As String
        <DispId(3)> Function WindowPID(ByVal hWnd As UInteger) As UInteger
    End Interface

    <Guid("B146BF9E-78FC-4DB0-ABFE-9FF026B43E4D"), _
     ClassInterface(ClassInterfaceType.None), _
     ProgId("WindowScriptingObject")> Public Class WindowScriptingObject
        Implements _WindowScriptingObject

        Public WindowScriptingObject()

        Public Declare Auto Function GetForegroundWindow Lib "user32" Alias "GetForegroundWindow"() As UInteger
        Public Declare Auto Function GetWindowText Lib "user32.dll" (ByVal hwnd As Int32, <Out()> ByVal lpString As System.Text.StringBuilder, ByVal cch As Int32) As Int32
        Public Declare Auto Function GetWindowThreadProcessId Lib "user32" Alias "GetWindowThreadProcessId" (ByVal hwnd As UInteger, ByRef lpdwProcessId As UInteger) As UInteger

        Public Function ActiveWindow() As UInteger Implements _WindowScriptingObject.ActiveWindow
    ActiveWindow = GetForegroundWindow()
    If err.lastdllerror <> 0 then
        Dim tmp as uinteger = err.lastdllerror and &h80070000
        err.raise(tmp,  "WindowSystemObject.GetForegroundWindow", "Type net helpmsg " & err.lastdllerror & " in a command prompt for help")
        Exit Function
    End If
        End Function

        Public Function WindowText(hwnd as UInteger) As String Implements _WindowScriptingObject.WindowText
    Dim b As New System.Text.StringBuilder(ChrW(0), 512)
                Dim ret as uinteger = GetWindowText(hWnd, b, b.Capacity)
    If err.lastdllerror <> 0 then
        Dim tmp as uinteger = err.lastdllerror and &h80070000
        WindowText = ""
        err.raise(tmp,  "WindowSystemObject.GetWindowText", "Type net helpmsg " & err.lastdllerror & " in a command prompt for help")
        Exit Function
    End If
    WindowText = b.tostring
        End Function

        Public Function WindowPID(HWnd as UInteger) As UInteger Implements _WindowScriptingObject.WindowPID 
    Dim X as UInteger
    Dim M as UInteger = 1
    X=GetWindowThreadProcessID(HWnd,M)
    If err.lastdllerror <> 0 then
        Dim tmp as uinteger = err.lastdllerror and &h80070000
        WindowPID = 0
        err.raise(tmp,  "WindowSystemObject.GetWindowThreadProcessID", "Type net helpmsg " & err.lastdllerror & " in a command prompt for help")
        Exit Function
    End If  
    WindowPID = M
        End Function


    End Class

End Namespace

Пакетный файл должен работать без ошибок.

Первая команда делает DLL из файла cls. Это будет сказать сборник успешно. Он ожидает, что файлы будут находиться в папке wso на вашем рабочем столе.

Вторая команда регистрирует его для каждой машины. Вы должны быть администратором, чтобы сделать это. Если вы не являетесь администратором, вы должны сгенерировать reg-файл и изменить все HKEY_CURRENT_ROOT на HKEY_CURRENT_USER\Software\Classes.

Создать регфайл

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm" /regfile:"%userprofile%\desktop\wso\wso.reg" "%userprofile%\desktop\wso\wso.dll"  /v

После редактирования wso.reg объедините его с

regedit /m "%userprofile%\desktop\wso\wso.reg"

И вам нужно прочитать результаты команд.

Вот скрипт, показывающий hwnd, PID и заголовок окна (и код ошибки). Обратите внимание, что при запуске скрипта нет активного окна в течение двух секунд (Windows ждет, пока ваша программа создаст его, чтобы он стал активным. Он ждет только 2 секунды). Обычно при запуске программы, но также и в другое время, в течение коротких периодов не будет активного окна. Вы должны поймать это в ловушку. Вот сценарий, который делает.

On error resume next
Set wso=CreateObject("WindowScriptingObject")
Do
x = wso.ActiveWindow
    wscript.echo x

    wscript.echo wso.windowtext(x)

    wscript.echo (err.number)
    err.clear
    wscript.echo wso.windowpid(x)

    wscript.echo (err.number)
    err.clear
    wscript.sleep 1000
Loop

И вот как это выглядит при запуске с CScript в командной строке.

C:\Users\User>cscript "C:\Users\User\Desktop\ActiveWindow.vbs"
Microsoft (R) Windows Script Host Version 5.7
Copyright (C) Microsoft Corporation. All rights reserved.


-2147024809
-2147024809
3344366
Administrator: Command Prompt - cscript  "C:\Users\User\Desktop\ActiveWin
dow.vbs"
0
972
0
3344366
Administrator: Command Prompt - cscript  "C:\Users\User\Desktop\ActiveWin
dow.vbs"
0
972
0
3344366
1312854
vbscript - How to find the window Title of Active(foreground) window using Windo
w Script Host - - Windows Internet Explorer
0
4724
0
1312854
vbscript - How to find the window Title of Active(foreground) window using Windo
w Script Host - - Windows Internet Explorer
0
4724
0
3344366
Administrator: Command Prompt - cscript  "C:\Users\User\Desktop\ActiveWin
dow.vbs"
0
972
0
^C
C:\Users\User>

----РЕДАКТИРОВАТЬ----

Похоже, что вы пострадали от ошибки блокнота при вставке с веб-страниц из забавного пробела имени объекта в сообщении об ошибке.

При использовании блокнота, чтобы написать его, скопируйте и вставьте в WordPad, чтобы проверить разрывы строк. Блокнот полностью игнорирует и скрывает возврат каретки, но другие программы этого не делают. Блокнот ищет только перевод строки. Если копирование из документации на основе браузера, такой как веб-страницы и справочные системы, иногда случайные возвраты каретки незаметно вставляются в блокнот.

Другие вопросы по тегам