Как найти заголовок окна активного (переднего плана) окна с помощью 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 специфичны для этого проекта. Не используйте их для других целей.
Больше информации о том, что мы делаем
Если вам необходимо выполнить установку для каждого пользователя, используйте 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, чтобы проверить разрывы строк. Блокнот полностью игнорирует и скрывает возврат каретки, но другие программы этого не делают. Блокнот ищет только перевод строки. Если копирование из документации на основе браузера, такой как веб-страницы и справочные системы, иногда случайные возвраты каретки незаметно вставляются в блокнот.