# 在Windows系统上，如何强制让任意GUI软件在后台/最小化启动而不显示窗口？

**URL:** <https://meta.appinn.net/t/topic/63409>\
**Category:** 问题求助\
**Tags:** windows\
**Created:** [2024 年11 月 23 日 06:58 UTC](https://meta.appinn.net/t/topic/63409 "2024-11-23T06:58:07Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

作者： ![shadows](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/shadows/32/17001_2.png) [@shadows](https://meta.appinn.net/u/shadows)\
发布日期： [2024 年11 月 23 日 06:58 UTC](https://meta.appinn.net/t/topic/63409/1 "2024-11-23T06:58:07Z")

</div>

如标题所述，在Windows系统上（win 10+），有什么办法让本身没有静默启动功能的GUI软件，能够在后台/最小化启动而不显示窗口？  
另外，只在软件启动时不显示，之后能够恢复窗口

例如：雷电模拟器

最简单的方法是用cmd命令`start /min`或者`Start-Process -WindowStyle Minimized`或者快捷方式属性-运行方式-最小化，但个别软件却会忽略这些参数，仍然在前台显示窗口。

当然还可以用像AHK之类的自动化工具或者用powershell调用winapi，启动软件然后自动点击窗口的最小化来实现。但这样会使得屏幕上短暂闪现窗口，仍然不够完美。

因此问问大家有没有办法完美解决这个问题？

update：我又想到，也许可以通过虚拟桌面或者多桌面的功能，让软件在当前不显示的桌面上打开

总结：  
根据解决方案中的源码，移植到powershell，并大大简化了  
作用于雷电模拟器：

```powershell
# Windows API
Add-Type @"
	using System;
	using System.Runtime.InteropServices;
	public static class WinAPI {
		[DllImport("user32.dll", CharSet = CharSet.Unicode)]
		public static extern IntPtr FindWindow(String sClassName, IntPtr sAppName);

		[DllImport("user32.dll")]
		public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
	}
"@

$SWP_NOSIZE = 0x0001
$SWP_NOMOVE = 0x0002
$SWP_NOZORDER = 0x0004
$SWP_NOACTIVATE = 0x0010
$SWP_HIDEWINDOW = 0x0080
$windowFlags = $SWP_HIDEWINDOW -bor $SWP_NOSIZE -bor $SWP_NOMOVE -bor $SWP_NOZORDER -bor $SWP_NOACTIVATE

Start-Process dnplayer.exe

while ($true)
{
	[System.IntPtr] $hwnd = [WinAPI]::FindWindow("LDPlayerMainFrame", [System.IntPtr]::Zero);
	if ($hwnd -ne [System.IntPtr]::Zero) {
		[WinAPI]::SetWindowPos($hwnd, 0, 0, 0, 0, 0, $windowFlags) | Out-Null
		break
	}
	Start-Sleep -Milliseconds 1
}

```

---

<div class="post-metadata">

作者： ![wffty](https://meta-edge.appinn.com/letter_avatar_proxy/v4/letter/w/e9c0ed/32.png) [@wffty](https://meta.appinn.net/u/wffty)\
发布日期： [2024 年11 月 23 日 09:08 UTC](https://meta.appinn.net/t/topic/63409/2 "2024-11-23T09:08:41Z")

</div>

请问一下用ahk 怎么写？

---

<div class="post-metadata">

作者： ![shadows](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/shadows/32/17001_2.png) [@shadows](https://meta.appinn.net/u/shadows)\
发布日期： [2024 年11 月 23 日 10:08 UTC](https://meta.appinn.net/t/topic/63409/3 "2024-11-23T10:08:08Z")

</div>

我不会AHK，但搜索论坛时有人说到了这个方法

我可以提供一个powershell把窗口完全隐藏的例子

```powershell
# 窗口状态与对应值
$WindowStates = @{
	'FORCEMINIMIZE' = 11
	'HIDE' = 0
	'MAXIMIZE' = 3
	'MINIMIZE' = 6
	'RESTORE' = 9
	'SHOW' = 5
	'SHOWDEFAULT' = 10
	'SHOWMAXIMIZED' = 3
	'SHOWMINIMIZED' = 2
	'SHOWMINNOACTIVE' = 7
	'SHOWNA' = 8
	'SHOWNOACTIVATE' = 4
	'SHOWNORMAL' = 1
}

# 调用 Windows API
Add-Type @"
	using System;
	using System.Runtime.InteropServices;
	public class WinAPI {
		[DllImport("user32.dll")]
		public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
	}
"@
#启动程序
Start-Process dnplayer.exe
#循环40次，避免多次弹出窗口
for ($i = 0; $i -lt 40; $i++)
{
	# 进程名是dnplayer
	$process = Get-Process -Name "dnplayer" -ErrorAction SilentlyContinue
	# 如果主窗口存在
	if ($process.MainWindowHandle -ne 0) {
		[System.IntPtr] $MainWindowHandle = $process.MainWindowHandle
		# 最小化窗口
		[WinAPI]::ShowWindowAsync($MainWindowHandle, $WindowStates['MINIMIZE']) | Out-Null
		Write-Host "Hide dnplayer!"
	}
	# 睡眠50ms
	Start-Sleep -Milliseconds 50
}

```

---

<div class="post-metadata">

作者： ![3\_5105](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/3_5105/32/57748_2.png) [@3\_5105](https://meta.appinn.net/u/3_5105)\
发布日期： [2024 年11 月 23 日 12:28 UTC](https://meta.appinn.net/t/topic/63409/4 "2024-11-23T12:28:10Z")

</div>

我想出有几个办法  
**1.简单粗暴** ，使用程序语言（如c）以轮询的方式查找并隐藏窗口，不需要特殊权限，因为编译的代码执行很快，所以大概率来不及闪一下  
**优点：**  
五行代码就能完成  
**缺点：** \*  
大概率来不及闪一下，所以小概率来得及闪一下…  
CPU占用会很高

**2.一般思路** ，调用hook相关api进行全局hook，每一个窗口显示前先检查它是否属于待拦截进程，若是则拦截，否则放行  
**优点：**  
不会闪一下  
**缺点：**  
全局钩子必须创建一个用于注入进程的dll和一个设置hook的程序，所以必须使用可以创建dll的语言  
必须取得管理员权限  
大量设置hook会拖慢系统性能

**3.利用轮子** ，基于上一个思路，我们发现这很像弹窗拦截程序。于是直接在弹窗拦截程序（如火绒）中拦截主窗口即可  
**优点：**  
不会闪一下  
不需要编程  
**缺点：**  
得安装一个弹窗拦截程序，失去可移植性  
同理，失去自定义能力

**4.dll注入** ，使用dll劫持，直接hook程序中显示窗口的api，不让他显示  
**优点：**  
不会闪一下  
只需要增加一个dll了，不需要管理员权限  
**缺点：**  
可能被报毒  
需要写一个dll

**5.非法修改** ，直接把要隐藏的程序进行反汇编，去掉显示窗口的那一条指令。不显示=隐藏  
**优点：**  
不会闪一下  
并且不会损失性能，不需要新增组件  
**缺点：**  
需要修改者需要一定（不多）的反汇编能力  
剩余缺点的数量取决于待隐藏软件具体情况

---

<div class="post-metadata">

作者： ![shadows](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/shadows/32/17001_2.png) [@shadows](https://meta.appinn.net/u/shadows)\
发布日期： [2024 年11 月 23 日 12:43 UTC](https://meta.appinn.net/t/topic/63409/5 "2024-11-23T12:43:51Z")

</div>

1. 其实还是先有窗口显示出来后，再把窗口最小化/隐藏。这肯定还是会有窗口闪现的，个人理解是这样的

2. 过于困难，这估计都到系统底层了。是否有现成的工具？等人寻找

3. 弹窗拦截程序：这就不是启动时最小化/隐藏了，弹窗拦截是关闭窗口……要的只是启动时不显示而已，之后想看的时候还是需要显示窗口的

4和5 有没有例子？

---

<div class="post-metadata">

作者： ![3\_5105](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/3_5105/32/57748_2.png) [@3\_5105](https://meta.appinn.net/u/3_5105)\
发布日期： [2024 年11 月 23 日 12:56 UTC](https://meta.appinn.net/t/topic/63409/6 "2024-11-23T12:56:22Z")

</div>

您已经选定了2、4、5方案  
接着：  
若您可以直接提供软件，我可以为您选择一个最合适的方案，编写一个程序完成  
若您不能直接提供软件，则我们可能需要您确认一些信息，然后再确定是否有可用的解决方案

---

<div class="post-metadata">

作者： ![shadows](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/shadows/32/17001_2.png) [@shadows](https://meta.appinn.net/u/shadows)\
发布日期： [2024 年11 月 23 日 13:05 UTC](https://meta.appinn.net/t/topic/63409/7 "2024-11-23T13:05:38Z")

</div>

目前我遇到的软件是 雷电模拟器9.1.30 其中的 dnplayer.exe  
[直链下载](http://123.60.172.133:5244/d/ct/%E9%9B%B7%E7%94%B5%E6%A8%A1%E6%8B%9F%E5%99%A89(64)-9.1.30.0%E5%8E%BB%E5%B9%BF%E5%91%8A%E7%BB%BF%E8%89%B2%E7%89%88.exe) [飞书云](https://dqg5ydiknl.feishu.cn/file/HwYSbLCOBobdsrxcHENcmvRKnBg) [123云盘](https://www.123684.com/s/1QeA-lPH8v)  
（无需安装，修改为7Z后缀解压即可）

如果需要提供信息的话，就直接问吧

---

<div class="post-metadata">

作者： ![lilyhcn1](https://meta-edge.appinn.com/letter_avatar_proxy/v4/letter/l/439d5e/32.png) [@lilyhcn1](https://meta.appinn.net/u/lilyhcn1)\
发布日期： [2024 年11 月 24 日 05:09 UTC](https://meta.appinn.net/t/topic/63409/8 "2024-11-24T05:09:03Z")

</div>

你搜一下nircmd，这个程序可以让程序在前台运行，但不显示窗口。

---

<div class="post-metadata">

作者： ![shadows](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/shadows/32/17001_2.png) [@shadows](https://meta.appinn.net/u/shadows)\
发布日期： [2024 年11 月 24 日 05:32 UTC](https://meta.appinn.net/t/topic/63409/9 "2024-11-24T05:32:48Z")

</div>

试过了  
`nircmd exec hide`是吗？不起作用的  
根据参数的可选类型show/hide/min/max，我推测它实际就是`Start-Process -WindowStyle `的包装罢了

---

<div class="post-metadata">

作者： ![3\_5105](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/3_5105/32/57748_2.png) [@3\_5105](https://meta.appinn.net/u/3_5105)\
发布日期： [2024 年11 月 24 日 06:26 UTC](https://meta.appinn.net/t/topic/63409/10 "2024-11-24T06:26:48Z")

</div>

我回来啦！因为不可抗力耽搁了…昨天晚上就应该发出来了  
**[LDHIDER](https://wwgz.lanzouw.com/b00mowveoj)  
密码:2jak**  
下载ldhook.7z，解压缩文件到雷电模拟器主目录，启动pecmd.exe即可  
ldhook\_src.7z则是源码

* * *

**以下写给开发人员**

这个程序为了性能应该是使用了某种直接写入显存来显示画面的库（按导入表看应该是OpenGL）；而隐藏启动参数则是针对使用GDI绘制标准窗口的程序。它们的底层实现不一样，所以没办法通用

实际上主窗口是一层GDI标准窗口，底下再加一层OpenGL窗口，所以我的解决方案实现原理大致如下

1 挂钩到每一个窗口，只要任意窗口有窗口消息就触发以下逻辑：  
（因为”只要任意窗口有窗口消息“就触发，所以雷电模拟器创建窗口时也会触发）

2 检查雷电模拟器那层GDI标准窗口是否存在  
（那层GDI标准窗口先被创建，而且调用winapi就可以检查，故以此为执行条件）

3 若存在，隐藏之，并将其移动到显示屏外  
（OpenGL窗口跟随GDI窗口移动，而OpenGL又不会绘制显示屏外的部分，这样直接避免了OpenGL窗口被绘制）  
（如果只隐藏GDI窗口，不移动它的话，启动时会在原地留下一个大黑框——其实是找不到gdi窗口的OpenGL窗口）

4 在开始挂钩的五秒钟后卸载挂钩  
（挂钩很浪费系统资源，故需要尽可能快卸载）

---

<div class="post-metadata">

作者： ![shadows](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/shadows/32/17001_2.png) [@shadows](https://meta.appinn.net/u/shadows)\
发布日期： [2024 年11 月 24 日 06:54 UTC](https://meta.appinn.net/t/topic/63409/11 "2024-11-24T06:54:23Z")

</div>

所以是用全局钩子做的吗？

---

<div class="post-metadata">

作者： ![3\_5105](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/3_5105/32/57748_2.png) [@3\_5105](https://meta.appinn.net/u/3_5105)\
发布日期： [2024 年11 月 24 日 06:55 UTC](https://meta.appinn.net/t/topic/63409/12 "2024-11-24T06:55:45Z")

</div>

是的，基于思路2，但是因为情况复杂所以多了好几步额外处理

---

<div class="post-metadata">

作者： ![shadows](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/shadows/32/17001_2.png) [@shadows](https://meta.appinn.net/u/shadows)\
发布日期： [2024 年11 月 24 日 07:03 UTC](https://meta.appinn.net/t/topic/63409/13 "2024-11-24T07:03:17Z")

</div>

我试了下，模拟器还是正常显示了窗口  
环境：windows 11 关闭了安全软件（火绒）

---

<div class="post-metadata">

作者： ![3\_5105](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/3_5105/32/57748_2.png) [@3\_5105](https://meta.appinn.net/u/3_5105)\
发布日期： [2024 年11 月 24 日 07:10 UTC](https://meta.appinn.net/t/topic/63409/14 "2024-11-24T07:10:20Z")

</div>

可恶…我暂时没有设备可供调试  
如果您已经确保pecmd.exe、ldhook.dll与dnplayer.exe处于同一目录下，则您可以尝试以管理员身份启动pecmd.exe  
您也可以先下载ldhook\_src.7z进行调试，我要在获取可用设备后才能进行调试…

---

<div class="post-metadata">

作者： ![shadows](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/shadows/32/17001_2.png) [@shadows](https://meta.appinn.net/u/shadows)\
发布日期： [2024 年11 月 24 日 07:15 UTC](https://meta.appinn.net/t/topic/63409/15 "2024-11-24T07:15:01Z")

</div>

是的，都在同一目录下，不然也启动不了dnplayer.exe。并且运行时是要求必须管理员权限的，不给是不行的

---

<div class="post-metadata">

作者： ![3\_5105](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/3_5105/32/57748_2.png) [@3\_5105](https://meta.appinn.net/u/3_5105)\
发布日期： [2024 年11 月 24 日 12:02 UTC](https://meta.appinn.net/t/topic/63409/16 "2024-11-24T12:02:04Z")

</div>

请重试，已更新

---

<div class="post-metadata">

作者： ![shadows](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/shadows/32/17001_2.png) [@shadows](https://meta.appinn.net/u/shadows)\
发布日期： [2024 年11 月 24 日 12:21 UTC](https://meta.appinn.net/t/topic/63409/17 "2024-11-24T12:21:06Z")

</div>

很遗憾，同样的结果，窗口正常显示  
我把程序都放在D:\Program\LDPlayer9里面

ps：照着别的hook示例和你的源码，想改写成powershell，发现有的函数还是必须用dll……算了

---

<div class="post-metadata">

作者： ![3\_5105](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/3_5105/32/57748_2.png) [@3\_5105](https://meta.appinn.net/u/3_5105)\
发布日期： [2024 年11 月 24 日 12:50 UTC](https://meta.appinn.net/t/topic/63409/18 "2024-11-24T12:50:57Z")

</div>

要不我们试试看思路1？我测了十几遍，没有出现闪一下的情况  
在原链接里面的那个未命名1.exe

---

<div class="post-metadata">

作者： ![shadows](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/shadows/32/17001_2.png) [@shadows](https://meta.appinn.net/u/shadows)\
发布日期： [2024 年11 月 24 日 12:59 UTC](https://meta.appinn.net/t/topic/63409/19 "2024-11-24T12:59:26Z")

</div>

的确完全不闪  
不过这个程序自身就会显示一个终端窗口……能改成不显示终端窗口吗？

~~还有个问题，这会导致被隐藏的窗口，在这次运行中，无法显示了。只能关掉模拟器，重开~~  
需要双击托盘在状态栏显示出图标，然后右键图标，再打开，会在左上角显示一个小窗口……

---

<div class="post-metadata">

作者： ![3\_5105](https://meta-edge.appinn.com/user_avatar/meta.appinn.net/3_5105/32/57748_2.png) [@3\_5105](https://meta.appinn.net/u/3_5105)\
发布日期： [2024 年11 月 24 日 13:21 UTC](https://meta.appinn.net/t/topic/63409/20 "2024-11-24T13:21:50Z")

</div>

如果只是不需要显示控制台，原链接中的t\_ldhider.7z可以

[下一页](https://meta.appinn.net/t/topic/63409.md?page=2)
