我想使用Window Script Host(WSH)查找当前处于活动状态(具有焦点)的窗口的标题,因为我希望我的WSH脚本仅用于Sendkeys如果所需窗口处于活动状态。
注意*我没有条件使用替代方案,即在调用sendkeys之前激活所需的窗口。
感谢任何帮助。
答案 0 :(得分:5)
简答:你不能。至少没有为相关的Windows API调用编写COM包装器。
您是否只能使用AppActivate
并检查结果?
Set oShell = CreateObject("WScript.Shell")
If oShell.AppActivate "Untitled - Notepad" Then
oShell.SendKeys "Hello, world!"
End If
答案很长:要获取活动窗口标题,您需要调用Windows API GetWindowText
函数并传递GetForegroundWindow()
句柄。 VBScript和Windows脚本宿主不支持Windows API调用,因此您需要围绕这些函数编写COM包装器,然后可以在脚本中使用它们。以下是例子:
Get current active Window title in C
How do I get the title of the current active window using c#?
答案 1 :(得分:4)
您可以使用GetForegroundWindow和GetWindowText制作COM对象。
将以下行放入wso.cls,store是桌面上名为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
然后在名为wso.bat的同一文件夹中创建一个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
在运行bat文件后在vbs中使用。
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网站上提出。
答案 2 :(得分:2)
这是一个可供使用的更新版本。以前的答案是最小的工作所需。
这也取代了这里的答案(appactivate between multiple internet explorer instances),因为它不适用于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
答案 3 :(得分:1)
批处理文件必须正常运行。
第一个命令从cls文件生成dll。它会说 Compilation Sucessfull 。它希望文件位于桌面上名为wso的文件夹中。
第二个命令在每台机器上注册它。您必须是管理员才能执行此操作。如果您不是管理员,则必须生成一个reg文件,并将所有HKEY_CURRENT_ROOT更改为HKEY_CURRENT_USER \ Software \ Classes。
生成regfile
"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和窗口标题(以及错误代码)。请注意,当脚本启动时,大约两秒没有活动窗口(窗口正在等待程序创建一个窗口以使其处于活动状态。它只等待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中以检查换行符。记事本完全忽略并隐藏回车,但其他程序则没有。记事本仅查找换行符。如果从基于浏览器的文档(如网页和帮助系统)进行处理,有时会将杂散的回车卡无形地插入记事本中。