如何通过编程获取Windows Terminal(wt.exe)的版本信息?
如何编程获取Windows Terminal版本字符串
背景
执行命令wt -v会弹出消息框显示Windows Terminal的版本信息,但需要通过编程方式直接获取该版本字符串,优先使用.NET(C#)实现,C/C++方案也可接受。已知wt.exe内部通过winrt::hstring DefaultTerminal::Version() const方法获取版本,但该方法未对外导出,无法直接调用。
可行方案
方案1:读取wt.exe的文件版本信息(推荐)
Windows Terminal的版本信息会嵌入在wt.exe的文件版本资源中,这是最稳定可靠的方式,无需依赖UI或内部未导出接口。
C# 实现
using System; using System.IO; using System.Diagnostics; using System.Linq; public static string GetWindowsTerminalVersion() { // 先尝试系统目录下的wt.exe var wtPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "system32", "wt.exe"); if (!File.Exists(wtPath)) { // 系统目录不存在则查找商店版本的安装目录 var programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); var windowsAppsPath = Path.Combine(programFiles, "WindowsApps"); if (Directory.Exists(windowsAppsPath)) { var wtDirs = Directory.GetDirectories(windowsAppsPath, "Microsoft.WindowsTerminal_*"); if (wtDirs.Length > 0) { // 取版本号最高的目录 var latestDir = wtDirs.OrderByDescending(d => new DirectoryInfo(d).Name).First(); wtPath = Path.Combine(latestDir, "wt.exe"); } else { throw new FileNotFoundException("未找到Windows Terminal的安装文件"); } } else { throw new FileNotFoundException("未找到Windows Terminal的安装文件"); } } var fileVersionInfo = FileVersionInfo.GetVersionInfo(wtPath); // 返回与wt -v显示一致的产品版本字符串 return fileVersionInfo.ProductVersion; }
C/C++ 实现
#include <windows.h> #include <string> #include <vector> #include <stdexcept> std::wstring GetWindowsTerminalVersion() { std::wstring wtPath = L"C:\\Windows\\System32\\wt.exe"; // 检查系统目录下的文件是否存在 if (GetFileAttributesW(wtPath.c_str()) == INVALID_FILE_ATTRIBUTES) { // 此处可扩展为遍历WindowsApps目录查找商店版本,简化示例中直接抛出异常 throw std::runtime_error("未找到wt.exe文件"); } DWORD dummy; // 获取版本信息所需的缓冲区大小 DWORD bufferSize = GetFileVersionInfoSizeW(wtPath.c_str(), &dummy); if (bufferSize == 0) { throw std::runtime_error("无法获取文件版本信息大小"); } std::vector<BYTE> buffer(bufferSize); if (!GetFileVersionInfoW(wtPath.c_str(), 0, bufferSize, buffer.data())) { throw std::runtime_error("读取文件版本信息失败"); } VS_FIXEDFILEINFO* fileInfo = nullptr; UINT infoSize; if (!VerQueryValueW(buffer.data(), L"\\", reinterpret_cast<LPVOID*>(&fileInfo), &infoSize)) { throw std::runtime_error("解析版本信息失败"); } // 拼接成标准版本格式:主版本.次版本.构建版本.修订版本 WCHAR versionStr[256]; swprintf_s(versionStr, L"%u.%u.%u.%u", HIWORD(fileInfo->dwProductVersionMS), LOWORD(fileInfo->dwProductVersionMS), HIWORD(fileInfo->dwProductVersionLS), LOWORD(fileInfo->dwProductVersionLS)); return versionStr; }
方案2:捕获wt -v弹出的消息框文本(不推荐)
这种方法依赖Windows UI自动化,稳定性较差(系统语言变更、消息框样式修改都会导致失效),仅作为特殊场景下的备选方案。
C# 实现(基于Windows UI自动化)
using System; using System.Diagnostics; using System.Windows.Automation; using System.Threading; public static string GetWtVersionFromMessageBox() { var processStartInfo = new ProcessStartInfo("wt.exe", "-v") { UseShellExecute = true, CreateNoWindow = false }; using var process = Process.Start(processStartInfo); // 等待消息框加载,需根据实际情况调整等待时长 Thread.Sleep(1000); // 查找Windows Terminal版本消息框 var desktop = AutomationElement.RootElement; var messageBoxCondition = new PropertyCondition(AutomationElement.NameProperty, "Windows Terminal"); var messageBox = desktop.FindFirst(TreeScope.Children, messageBoxCondition); if (messageBox == null) { throw new InvalidOperationException("未找到版本信息消息框"); } // 获取消息框内的文本内容 var textCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Text); var textElement = messageBox.FindFirst(TreeScope.Descendants, textCondition); var versionText = textElement.Current.Name; // 自动关闭消息框 var okButtonCondition = new PropertyCondition(AutomationElement.NameProperty, "确定"); var okButton = messageBox.FindFirst(TreeScope.Descendants, okButtonCondition); if (okButton != null) { ((InvokePattern)okButton.GetCurrentPattern(InvokePattern.Pattern)).Invoke(); } return versionText; }
说明
优先选择方案1,因为文件版本信息是Windows应用的标准资源,不受UI变化影响,稳定性和兼容性更强。方案2仅在无法读取文件版本的特殊场景下使用,需额外处理各种异常情况。
内容的提问来源于stack exchange,提问作者unknown6656
相关产品推荐
相关产品推荐

