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

随着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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何用CHAT写励志文章?

问CHAT&#xff1a;写一篇以《过了60岁要积极面对身体疾病的坎儿》为题目&#xff0c;写一篇300字励志文章 CHAT回复&#xff1a; 标题&#xff1a;《过了60岁要积极面对身体疾病的坎儿》 人生&#xff0c;有时会像一趟不期而遇的旅程&#xff0c;各自带着乐观或悲观、阳光或…

区间第k小数 (可持久化线段树、主席树)

题意&#xff1a;多次询问&#xff0c;每次询问某区间的第k小数。 可持久化线段树&#xff1a; 掺杂了一点前缀和的思想&#xff0c;对于每一个1 ~ i 的区间都建一个树&#xff0c;每个节点存的都是一个线段树&#xff0c;值存的是当前区间中初始数组按大小排序后[l, r]之间的…

生产订单自动下达

文章目录 1 Introduction2 Detail2.1 input MM02 3 Summary 1 Introduction Production order is released order by automation . We can set the material for it . The method is the detial . 2 Detail 2.1 input MM02 please choose work Scheduling please choose S…

算法分析-三壶谜题

一.题目需求 有一个充满水的8品脱的水壶和两个空水壶&#xff08;容积分别是5品脱和3品脱&#xff09;。 通过将水壶完全倒满水和将水壶的水完全倒空这两种方式&#xff0c;在其中的一个水壶中得到4品脱的水。 二、算法思想 1.算法分析 1.1. 采用的算法思想是将某个时刻水壶…

9.3 Windows驱动开发:内核解析PE结构节表

在笔者上一篇文章《内核解析PE结构导出表》介绍了如何解析内存导出表结构&#xff0c;本章将继续延申实现解析PE结构的PE头&#xff0c;PE节表等数据&#xff0c;总体而言内核中解析PE结构与应用层没什么不同&#xff0c;在上一篇文章中LyShark封装实现了KernelMapFile()内存映…

priority_queue简单实现(优先级队列)(c++)

priority_queue priority_queue介绍逻辑实现框架调整算法adjust_up()adjust_down() 仿函数/比较函数仿函数特性 构造函数迭代器区间构造 完整优先级队列代码 priority_queue介绍 pri_que是一个容器适配器&#xff0c;它的底层是其他容器&#xff0c;并由这些容器再封装而来。类…

Win10之bandicam录音无声音问题(七十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

分布式进阶-链路追踪SpringCloudSleuth、Zipkin【实战篇】

一、前言 我们在使用微服务的时候&#xff0c;往往设计到各个微服务之间的调用&#xff0c;肯定会存在深度的调用链路&#xff0c;如果出现BUG或者异常&#xff0c;就会让问题定位和处理效率非常低。 有了Sleuth &#xff0c;就可以帮助我们记录、跟踪应用程序中的请求和操作。…

C++:哈希表的模拟实现

文章目录 哈希哈希冲突哈希函数 解决哈希冲突闭散列&#xff1a;开散列 哈希 在顺序结构和平衡树中&#xff0c;元素的Key和存储位置之间没有必然的联系&#xff0c;在进行查找的时候&#xff0c;要不断的进行比较&#xff0c;时间复杂度是O(N)或O(logN) 而有没有这样一种方案…

数据库基本操作-----数据库用户管理和授权

一、数据库用户管理 1&#xff0e;新建用户 CREATE USER 用户名来源地址 [IDENTIFIED BY [PASSWORD] 密码];‘用户名’&#xff1a;指定将创建的用户名 ‘来源地址’&#xff1a;指定新创建的用户可在哪些主机上登录&#xff0c;可使用IP地址、网段、主机名的形式&#xff0c…

linux下流媒体压力测试工具的使用

前言 因为领导要求做linux的推拉流时服务器压力测试&#xff0c;于是在网上找了找。一顿操作下来&#xff0c;发现很多软件盗用一款名为srs-bench的开源软件。 该代码仓库有详细的使用说明&#xff0c;而且可以在issues中找到可能会遇到的问题的解决办法 需要下载该仓库的源…

C# Onnx 百度PaddleSeg发布的实时人像抠图PP-MattingV2

目录 效果 模型信息 项目 代码 下载 效果 图片源自网络侵删 模型信息 Inputs ------------------------- name&#xff1a;img tensor&#xff1a;Float[1, 3, 480, 640] --------------------------------------------------------------- Outputs -----------------…

ZLMediaKit安装配置和推拉流

一、ZLMediaKit 库简介 ZLMediaKit 是一个基于 C11 的高性能运营级流媒体服务框架 官方写的项目特点&#xff1a; 基于 C11 开发&#xff0c;避免使用裸指针&#xff0c;代码稳定可靠&#xff0c;性能优越。 支持多种协议(RTSP/RTMP/HLS/HTTP-FLV/Websocket-FLV/GB28181/MP…

栈的生长方向不总是向下

据我了解&#xff0c;栈的生长方向向下&#xff0c;内存地址由高到低 测试 windows下&#xff1a; 符合上述情况 测试Linux下&#xff1a; 由此可见&#xff0c;栈在不同操作系统环境下&#xff0c;生长方向不总是向下

【Python】Vscode解决Python中制表符和空格混用导致的缩进问题

【Python】Vscode解决Python中制表符和空格混用导致的缩进问题 文章目录 【Python】Vscode解决Python中制表符和空格混用导致的缩进问题1. 问题来源2. 解决Reference 1. 问题来源 在python中使用缩进来进行代码块的分区&#xff0c;通常来说python的一个缩进包含4个空格&#…

不存在类型变量 A, T 的实例,使 Collector<T, A, List<T>> 符合 Supplier<R>

报错信息 原因: 不存在类型变量 A, T 的实例&#xff0c;使 Collector<T, A, List<\T>> 符合 Supplier<\R> 来源 测试Stream流的map方法&#xff0c;做算法习惯基本类型定义数组。 map方法:Stream API的一部分。允许以一种声明式的方式处理数据&#xff0c…

nodejs搭建本地服务

前端开发时想自己有个本地服务如下操作直接上干货 1.在桌面上直接在powerShell 输入命令行 npm install -g express-generator 然后 npm install -g express 然后新建一个例如server的文件夹 在powerShell执行 express myStudy -e 端口号默认是3000 直接在地址栏输入 http://…

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

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

枚举 蓝桥oj DNA序列修正

题目详情&#xff1a; 简单翻译&#xff1a; 主要思路&#xff1a; 1 本题采用贪心思路&#xff0c;要使调整次数最少&#xff0c;就是尽量交换两个碱基对&#xff0c;而不是单个替换&#xff0c;因为本题已经说明只能每个碱基对只能交换一次&#xff0c;所以不考虑A与B交换再…

NC65 修改元数据字段长度

NC65 修改元数据字段长度&#xff0c;执行下面sql&#xff0c;执行完后需要重启NC服务才生效。 --属性 update md_property set attrlength 200 where name fphm and classidece96dd8-bdf8-4db3-a112-9d2f636d388f ;--列 update md_column set columnlength 200 where tab…