C语言获取win11新版终端WindowsTerminal窗口句柄

news2024/9/21 16:44:31

随着Win11的普及,越来越多的人都能发现获取控制台窗口不能再使用以下两种传统方法了:

HWND hwnd = GetConsoleWindow();
HWND hwnd = FindWindowA("ConsoleWindowClass",NULL);

那是因为win11换了新的终端窗口,叫做WindowsTerminal,高端大气,字体看得也舒服。
在这里插入图片描述
(↑如果你想换回旧版控制台主机,可以右键标题栏“Settings”进入设置,按上图操作)

不过这个窗口是真的很难抓,
第一, 不推荐使用GetForegroundWindow,风险太大,容易抓成别的窗口,准确率低;
第二, GetConsoleWindow已经无法获取该窗口;
第三, FindWindow(“ConsoleWindowClass”,NULL)也不能抓新的终端;
第四, 抓类名,用第三方工具获得新终端类名,我这里是CASCADIA_HOSTING_WINDOW_CLASS 。用FindWindow,我这里失败了。。
第五, 我去问ChatGPT(3.5),它的回答是:

在 Windows 11 中,Windows Terminal 可能使用了不同的机制来管理其窗口句柄,可能会导致传统的方法无法准确地获取到正确的窗口句柄。
尝试使用 FindWindow 可能不会成功是因为该函数是基于窗口类名或窗口标题来查找窗口的,而 Windows Terminal 可能没有传统的类名或标题。
另一个选择是尝试使用 Windows 11 的新 API,例如 Windows.UI.Xaml 应用程序的 API。你可以考虑使用 Universal Windows Platform (UWP) 或 Windows Runtime (WinRT) API,来与 Windows Terminal 进行交互。
以下是可能用于获取 Windows Terminal 窗口句柄的一种方法,但请注意,这只是一个示例,并不保证可以直接适用于你的情况,而且需要你对 UWP 或 WinRT 有一定的了解:

#include <windows.h>
#include <winrt/Windows.UI.Composition.h>
#include <winrt/Windows.UI.Xaml.Hosting.h>

using namespace winrt::Windows::UI::Composition;
using namespace winrt::Windows::UI::Xaml::Hosting;

HWND GetWindowsTerminalWindowHandle() {
    HWND terminalWindowHandle = nullptr;
    try {
        // 初始化Windows Runtime
        winrt::init_apartment();
        // 获取Windows Terminal的主机对象
        auto terminalHost = DesktopWindowXamlSource();
        // 获取Windows Terminal的根Visual对象
        auto terminalVisual = ElementCompositionPreview::GetElementVisual(terminalHost);
        // 获取Windows Terminal的窗口句柄
        terminalHost.Handle(terminalWindowHandle);
    } catch (winrt::hresult_error const& ex) {
        // 处理异常
        // 可以在这里输出错误信息,调试问题
    }
    return terminalWindowHandle;
}

int main() {
    HWND terminalWindow = GetWindowsTerminalWindowHandle();
    if (terminalWindow != nullptr) {
        // 在这里使用获取到的窗口句柄进行你需要的操作
    } else {
        // 获取窗口句柄失败,处理错误
    }
    return 0;
}

请注意,这段代码假设你已经配置好了相应的开发环境,并且能够正确地使用 WinRT 和 UWP API。在使用这些 API 时,你需要适当的访问权限和合适的配置。
记住,由于 Windows Terminal 可能采用了新的技术和 API,因此获取其窗口句柄可能需要更多针对性的方法,并且需要根据具体情况进行调整。

有没有那俩头文件、能不能用是一回事,不过这明摆的是C++(11)啊,我要求是C语言。

于是我的方案是:
第一:FindWindow只抓标题。 没试过,但应该可以,不过标题一定要一字不差。

第二:枚举窗口,如果有窗口对应的PID对应的进程名叫WindowsTerminal.exe且标题是正确的标题,则为正确的窗口句柄。 这个方案成功了!我把代码放一下,该代码的作用是自动判断是否用的是新终端,如果是则抓,如果不是则抓旧版控制台:

HWND hwnd = NULL;
bool ExistProcess(LPCSTR lpName)	//判断是否存在指定进程
{	//******警告!区分大小写!!!!******// 
	//*****警告!必须加扩展名!!!!*****// 
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);	
	if (INVALID_HANDLE_VALUE == hSnapshot) 	
	{		
		return false;	
	}	
	PROCESSENTRY32 pe = { sizeof(pe) };	
	BOOL fOk;	
	for (fOk = Process32First(hSnapshot, &pe); fOk; fOk = Process32Next(hSnapshot, &pe)) 	
	{		
		if (! stricmp(pe.szExeFile, lpName)) 		
		{			
			CloseHandle(hSnapshot);			
			return true;		
		}	
	}	
	return false;
}
bool TerminalCheck(DWORD dwPid, HWND _hwnd)
{
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);	
	if (INVALID_HANDLE_VALUE == hSnapshot) 	
	{		
		return false;	
	}	
	PROCESSENTRY32 pe = { sizeof(pe) };	
	BOOL fOk;	
	for (fOk = Process32First(hSnapshot, &pe); fOk; fOk = Process32Next(hSnapshot, &pe)) 	
	{		
		if (! stricmp(pe.szExeFile, "WindowsTerminal.exe") //进程名
			&& pe.th32ProcessID == dwPid) 		
		{			//stricmp不区分大小写的字符串比较
			CloseHandle(hSnapshot);			
			{
				char title[MAX_PATH];
				GetWindowText(_hwnd, title, MAX_PATH);
				if(strcmp(title, _pgmptr) && strcmp(title, "学生管理系统 " CURRENT_VERSION)) 
				//_pgmptr是本体路径(用于还没来得及改标题的情况) 后面那个则是具体你设的标题,自定义即可
					return false;
				return true;
			}		
		}	
	}	
	return false;
}
BOOL CALLBACK EnumWindowsProc(HWND _hwnd, LPARAM lParam)
{ //回调函数
	DWORD pid;
	GetWindowThreadProcessId(_hwnd, &pid);
	if(TerminalCheck(pid, _hwnd))
	{
		printf("Terminal Found! pid=%ld hwnd=%p\n", pid, _hwnd);
		hwnd = _hwnd;
		return FALSE; //返回false中断枚举
	}
	return TRUE;
}

int main(int argc, char* argv[])
{
	if(ExistProcess("WindowsTerminal.exe"))
	{	//win11电脑且使用新版终端
		EnumWindows(EnumWindowsProc, 0);
	}else{	//旧版控制台主机
		hwnd = GetConsoleWindow();
	}
	//再不行就只能GetForegroundWindow了
	if(!hwnd || hwnd == INVALID_HANDLE_VALUE)
	{
		hwnd = GetForegroundWindow();
		printf("Failed! using GetForegroundWindow...");
	}
	//其他的一些事情...
	return 0;
}

必要的头文件:stdio.h stdlib.h windows.h tlhelp32.h stdbool.h string.h

去试试看行不行,我刚试成功的代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1237967.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

60V降压恒流芯片 高调光比LED驱动器 SL6015B替代PT4115 电路简单

在LED照明领域&#xff0c;降压恒流芯片是一种非常重要的芯片&#xff0c;它可以将输入的电压降低并输出稳定的电流&#xff0c;从而为LED灯提供合适的驱动电源。其中&#xff0c;SL6015B是一款非常优秀的降压恒流芯片&#xff0c;它具有高调光比、简单的电路设计、低成本的优点…

三柱汉诺塔

题目描述 汉诺塔是约19世纪末&#xff0c;在欧州的商店中出售一种智力玩具。它的结构如下图所示&#xff1a; 在一个平板上立有三根铁针&#xff0c;分别记为A, B, C。开始时&#xff0c;铁针 A 上依次叠放着从大到小 n 个圆盘&#xff0c;游戏的目标就是将 A 上的 n 个圆盘…

在建立 OkHttp3 Client 时设置超时时间

这里写目录标题 一. 前言二. 导入mavengradle 三. 设置超时时间 一. 前言 OkHttp是一个处理网络请求的开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司开发。OkHttp3是Java和Android都能用&#xff0c;Android还有一个著名网络库叫Volley&#xff0c;那个只有Andro…

torch.cat是什么,以及怎么用?

文章目录 一、torch.cat 是什么&#xff1f;二、使用步骤总结 一、torch.cat 是什么&#xff1f; torch.cat 是 PyTorch 中的一个函数&#xff0c;用于沿着某个维度连接张量。 torch.cat 接受一个张量列表&#xff0c;并沿着某个维度连接它们。这个函数会返回一个新的张量&am…

一键合并多个TXT文本,将保存在TXT的快递单号进行一键合并

如果你需要处理大量的TXT文本文件&#xff0c;那么你可能会遇到需要将这些文件合并为一个文件的情况。这不仅涉及到文件的组织和管理&#xff0c;还可能涉及到文件内容的连贯性和完整性。现在&#xff0c;我们有一个强大的工具&#xff0c;可以帮助你轻松实现一键文件整理&…

C/C++结构体给函数传参

C语言中结构体给函数传参有两种方法&#xff1a; 1.值传递&#xff08;修改形参不改变原值&#xff09; void fun(STUDENT student){……} int main(){fun(student); }2.引用传递&#xff08;传的是地址&#xff0c;修改形参会改变原值&#xff09; void fun(STUDENT * stud…

深入了解Java 8 新特性:Optional类的实践应用

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概15000多字&#xff0c;预计阅读时间长需10分钟。本篇文章的兼具实战性、理论性&#xff0c;是一篇质量分数较高的技术干货文章&#x…

微服务开发中,使用AOP和自定义注解实现对权限的校验

一、背景 微服务开发中&#xff0c;暴露在外网的接口&#xff0c;为了访问的安全&#xff0c;都是需要在http请求中传入登录时颁发的token。这时候&#xff0c;我们需要有专门用来做校验token并解析用户信息的服务。如下图所示&#xff0c;http请求先经过api网关&#xff0c;网…

【word技巧】Word制作试卷,ABCD选项如何对齐?

使用word文件制作试卷&#xff0c;如何将ABCD选项全部设置对齐&#xff1f;除了一直按空格或者Tab键以外&#xff0c;还有其他方法吗&#xff1f;今天分享如何将ABCD选项对齐。 首先&#xff0c;我们打开【替换和查找】&#xff0c;在查找内容输入空格&#xff0c;然后点击全部…

渗透工具---BurpSuite 插件开发之HelloWorld

本文主要记录如何利用burp官方的新版API即MontoyaApi 写helloworld&#xff08;上一篇的demo使用旧版api写的&#xff0c;这篇及后续开发将采用新版api&#xff09; 先看效果图 更多详细内容见下方 这里有更详细更全面的代码内容 以及配置相关的内容 https://mp.weixin.qq.co…

面试题-8

1.vue路由是怎么传参的&#xff1f; params传参 this.$router.push({name:index}) this.$route.params.id 路由属性传参 this.$router.push({name:/index/${item.id}}) 配置路由{path:/index:id} query传参(可以解决页面刷新参数丢失的问题) this.$router.push({ name…

云原生入门系列(背景和驱动力)

做任何一件事&#xff0c;或者学习、应用一个领域的技术&#xff0c;莫过于先要想好阶段的目标和理解、学习它的意义是什么&#xff1f;解决了什么问题&#xff1f; 这部分&#xff0c;就尝试来探讨下这个阶段需要理解并达成的目标以及践行云原生的意义在哪里。 1.历程 任何阶…

海辰储能与FlexGen签署储能系统合作协议,加快拓展北美市场

海辰储能宣布与美国储能技术提供商和系统集成商FlexGen达成合作协议。根据协议&#xff0c;海辰储能将为FlexGen供应10GWh的先进储能产品&#xff1b;同时&#xff0c;其将支持FlexGen能源管理系统(EMS)用于总容量为15GWh的项目。 作为协议的一部分&#xff0c;FlexGen还将成为…

Windows 7 连接 Windows 10 共享打印机,Windows 无法连接打印机,操作失败,错误为0x0000011b 的终极解决办法

Windows 7 连接 Windows 10 共享打印机出现错误 0x000001b&#xff0c;建议不要通过卸载Windows10系统的KB5005565安全更新来解决该问题&#xff08;犹如削足适履&#xff09;&#xff0c;正确的处理方法是手工添加一个本地打印机&#xff0c;本方法是安全可靠的。本文详述了该…

双12电视盒子推荐:测评员解析目前电视盒子哪个最好

电视盒子不需要每月缴费&#xff0c;只需联网就可以收看海量视频资源&#xff0c;游戏、网课、投屏等功能让电视盒子的使用场景更丰富&#xff0c;我每年都会进行数十次电视盒子测评&#xff0c;本期要分享的是双十二电视盒子推荐&#xff0c;全面解析目前电视盒子哪个最好。 一…

【数据结构】链表的八种形态

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 链表的三大"性状" 一.带头链表和不带头链表 头指针与头结点的异同 头指针 头结点 二.循环链表和非循环链表 三.双向链表和单向链表 链表的八大形态 结语…

Amlogic方案遥控器配置(Android11)

配置路线 键值变化路径&#xff1a; ScanCode --> Keycode Lable --> KeyCode Layout --> KeyLable --> Keycode – > KeyEvent 文件映射路径&#xff1a; *.dtsi --> input-event-codes.h --> *.kl --> InputEventLable.h --> kecodes.h --> P…

laravel引入element-ui后,blade模板中使用elementui时,事件未生效问题(下载element-ui到本地直接引入项目)

背景 重构公司后台项目&#xff0c;使用了dcat-admin&#xff0c;但是dcat-admin有些前端功能不能满足需求。因此引入element-ui进行相关界面的优化 具体流程 1.下载element-ui到本地 2.进入如下目录 打开 node_modules\element-ui\lib 复制index.js 打开 node_modules/ele…

UE4基础篇十五:AI行为树

一、学习完教程后需要掌握知识点 1.1、基础概念: 1.1 行为树:控制并显示AI的决策制定过程 1.2 黑板:可以看做是行为树的创建一些公有变量,外部可以修改行为树黑板的变量值,达到修改行为树状态的逻辑 1.3 环境查询: 获取地图环境中的信息进行一个筛选,查找到所需要的的…

微信公众号上怎么做微信助力活动

微信公众号微信助力活动&#xff1a;一起分享&#xff0c;一起成长 在当今社交媒体时代&#xff0c;人们之间的互动和分享变得越来越重要。微信公众号作为一个广受欢迎的社交平台&#xff0c;为人们提供了一个便捷的分享和交流渠道。而微信助力活动则是通过分享和互动&#xf…