使用鼠标配置一些键绑定时遇到了一些小问题。
我想要实现的是从背景(打开或关闭的窗口)打开程序并再次关闭它,但不要杀死任务(与x按钮等效,因此它会一直在后台运行)< / p>
我已经设置了鼠标来启动名为everything的应用程序(可以进行非常快速的文件系统搜索)
我已经想出了这个代码:
TASKKILL /F /IM Everything.exe
我可以用宏键运行我可以杀死应用程序。但是我不想仅仅在窗口中杀死应用程序本身,因为一旦我必须重新启动它就需要一段时间来索引所有重要文件。
因此,问题是有没有办法将窗口/任务调到屏幕前面或触发x按钮事件,而不必杀死整个过程?
鼠标(g600)也支持lua脚本,但这可能是更难的方法。
答案 0 :(得分:1)
无法发表评论所以我会尽力回答。 'x'按钮可能会杀死你的应用程序,除非应用程序配置,否则我猜。 我想我明白你最好把它放到图标托盘或其他什么东西。如果你的应用程序没有自然地做到这一点,这是不可能的。 你可以尝试点击alt + space + n,这是一个最小化应用程序的快捷方式。
答案 1 :(得分:1)
通常可以通过激活窗口(将其置于前台)然后使用SendKeys()
发送 Alt + Space 来完成最小化窗口,然后无论如何在您的语言环境中标有“#34;最小化&#34; (英语Windows中的 N )。 Here's one可能使用VBScript的几十个例子。
在我看来,这个序列被过度使用,不优雅和无聊 - 而且它对某些窗口(例如cmd控制台)不起作用。可以最小化窗口而不将其带到前台,并且无需模拟按键。一个人只需要从user32.dll导入一个函数。只要我们经历这个麻烦,我们也可以导入第二个函数来检测当前窗口状态,以便我们可以切换最小化/恢复。
我们可以像这样使用PowerShell导入函数。使用.bat扩展名保存此批处理/ PowerShell混合脚本并运行它。
<# : minimize.bat
:: toggles minimized state of a window by its filename
:: minimize.bat /? for usage
:: https://stackoverflow.com/a/34834953/1683264
@echo off & setlocal
if "%~1"=="" goto usage
set "prog=%~n1"
tasklist | findstr /i "\<%prog%\>" >NUL || goto usage
set /P "=Toggling the minimized state of %prog%... " <NUL
powershell -noprofile -noninteractive "iex ((gc \"%~f0\") -join \"`n\")"
goto :EOF
:usage
echo syntax: %~nx0 progname[.exe]
echo;
echo If the program is visible, minimize it. If minimized, restore it.
goto :EOF
:: end Batch / begin PowerShell hybrid chimera #>
Add-Type user32_dll @'
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
'@ -namespace System
$hwnd = @(Get-Process $env:prog)[0].MainWindowHandle
$state = [user32_dll]::GetWindowLong($hwnd, -16)
# mask of 0x20000000 = minimized; 2 = minimize; 4 = restore
if ($state -band 0x20000000) { $action = 4 } else { $action = 2 }
if ([user32_dll]::ShowWindowAsync($hwnd, $action)) {
write-host "Success" -f green
} else {
write-host "Fail" -f red
}
现在,如果您的程序最小化到系统托盘,则前一个脚本可以最小化,但在最小化时无法找到窗口句柄。尝试恢复时会失败。在这种情况下找到HWND是棘手的。如果知道窗口标题,可以使用user32.dll FindWindow()
或FindWindowEx()
函数找到HWND。
使用WMI或内置的PowerShell命令找到最小化到托盘的窗口标题,我没有多少运气。 get-process
,gwmi win32_process
和[diagnostics.process]::getProcessByName()
都没有取得成功。但是,我确实发现tasklist /v /fo list
的最后一行将显示窗口标题。这足以调用FindWindow()
并获得HWND。
这可能比它需要的更复杂,但是它可能不会。我只知道我找到了1000种失败的方法,但却找到了成功的方法。 Thanks to JPBlanc帮助我弄清楚如何将空参数传递到FindWindow()
和FindWindowEx()
。
<# : minimize.bat
:: toggles minimized state of a window by its filename
:: minimize.bat /? for usage
@echo off & setlocal
if "%~1"=="" goto usage
set "prog=%~n1"
tasklist | findstr /i "\<%prog%\>" >NUL || goto usage
set /P "=Toggling the minimized state of %prog%... " <NUL
powershell -noprofile -noninteractive "iex ((gc \"%~f0\") -join \"`n\")"
goto :EOF
:usage
echo syntax: %~nx0 progname[.exe]
echo;
echo If the program is visible, minimize it. If minimized, restore it.
goto :EOF
End batch / begin PowerShell hybrid chimera #>
Add-Type user32_dll @'
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(IntPtr lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter,
IntPtr lclassName, string windowTitle);
'@ -namespace System
$hwnd = (ps $env:prog)[0].MainWindowHandle
if ($hwnd -eq 0) {
tasklist /v /fi "imagename eq $env:prog*" /fo list | %{
$title = $_ -replace '^[^:]+:\s+'
}
$zero = [IntPtr]::Zero
$hwnd = [user32_dll]::FindWindow($zero, $title)
if ($hwnd -eq 0) {
$hwnd = [user32_dll]::FindWindowEx($zero, $zero, $zero, $title)
}
}
$state = [user32_dll]::GetWindowLong($hwnd, -16)
# mask of 0x20000000 = minimized; 2 = minimize; 4 = restore
if ($state -band 0x20000000) { $action = 4 } else { $action = 2 }
if ([user32_dll]::ShowWindowAsync($hwnd, $action)) {
write-host "Success" -f green
} else {
write-host "Fail" -f red
}