Files
sim_tool/wt_reg/main.cpp

370 lines
12 KiB
C++

/*
在包含任何 Windows 头文件之前定义宏 WIN32_LEAN_AND_MEAN
*/
#define WIN32_LEAN_AND_MEAN
#include <algorithm>
#include <filesystem>
#include <iostream>
#include <shlobj.h>
#include <string>
#include <vector>
#include <windows.h>
#ifndef WHAT_FUCK
#include <shellapi.h> // 需要在 windows.h 之后包含
#endif
namespace fs = std::filesystem;
class RegistryManager
{
private:
std::string wtPath;
bool checkWtExists()
{
if (fs::exists(wtPath) && fs::path(wtPath).filename() == "wt.exe") {
std::cout << "找到 wt.exe: " << wtPath << std::endl;
return true;
} else {
std::cout << "错误: wt.exe 不存在或路径无效: " << wtPath << std::endl;
return false;
}
}
bool isAdmin()
{
BOOL isAdmin = FALSE;
PSID adminGroup = NULL;
SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
if (AllocateAndInitializeSid(&ntAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
&adminGroup)) {
if (!CheckTokenMembership(NULL, adminGroup, &isAdmin)) {
isAdmin = FALSE;
}
FreeSid(adminGroup);
}
return isAdmin != FALSE;
}
// 创建注册表键并设置值
bool createRegistryKeyWithValue(const std::string& keyPath, const std::string& valueName, const std::string& valueData)
{
HKEY hKey;
std::cout << "创建注册表键: " << keyPath << std::endl;
if (!valueName.empty()) {
std::cout << "设置值: " << valueName << " = " << valueData << std::endl;
} else {
std::cout << "设置默认值: " << valueData << std::endl;
}
LONG result =
RegCreateKeyEx(HKEY_CLASSES_ROOT, keyPath.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
if (result != ERROR_SUCCESS) {
std::cout << "创建注册表键失败: " << keyPath << " 错误码: " << result << std::endl;
return false;
}
if (!valueName.empty() || valueData.length() > 0) {
result = RegSetValueEx(hKey, valueName.c_str(), 0, REG_SZ, (const BYTE*)valueData.c_str(),
static_cast<DWORD>(valueData.length() + 1));
if (result != ERROR_SUCCESS) {
std::cout << "设置注册表值失败: " << valueName << " 错误码: " << result << std::endl;
RegCloseKey(hKey);
return false;
}
}
RegCloseKey(hKey);
return true;
}
// 创建注册表键(不设置值)
bool createRegistryKey(const std::string& keyPath)
{
HKEY hKey;
std::cout << "创建注册表键: " << keyPath << std::endl;
LONG result =
RegCreateKeyEx(HKEY_CLASSES_ROOT, keyPath.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
if (result != ERROR_SUCCESS) {
std::cout << "创建注册表键失败: " << keyPath << " 错误码: " << result << std::endl;
return false;
}
RegCloseKey(hKey);
return true;
}
// 递归删除注册表键及其所有子键
bool deleteRegistryKeyRecursive(HKEY hRoot, const std::string& subKey)
{
HKEY hKey;
// 尝试打开键
LONG result = RegOpenKeyEx(hRoot, subKey.c_str(), 0, KEY_READ | KEY_WRITE, &hKey);
if (result != ERROR_SUCCESS) {
if (result == ERROR_FILE_NOT_FOUND) {
// 键不存在,视为成功删除
return true;
}
std::cout << "打开注册表键失败: " << subKey << " 错误码: " << result << std::endl;
return false;
}
// 递归删除所有子键
DWORD subKeyCount = 0;
DWORD maxSubKeyLen = 0;
result = RegQueryInfoKey(hKey, NULL, NULL, NULL, &subKeyCount, &maxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
if (result == ERROR_SUCCESS && subKeyCount > 0) {
std::vector<char> subKeyName(maxSubKeyLen + 2, 0); // +2 保证有足够空间
for (DWORD i = 0; i < subKeyCount; i++) {
DWORD nameLen = maxSubKeyLen + 1;
result = RegEnumKeyEx(hKey,
0, // 总是删除第一个子键
&subKeyName[0], &nameLen, NULL, NULL, NULL, NULL);
if (result == ERROR_SUCCESS) {
std::string childPath = subKey + "\\" + std::string(&subKeyName[0]);
if (!deleteRegistryKeyRecursive(hRoot, childPath)) {
RegCloseKey(hKey);
return false;
}
} else {
RegCloseKey(hKey);
std::cout << "枚举子键失败: " << subKey << " 错误码: " << result << std::endl;
return false;
}
}
}
RegCloseKey(hKey);
// 删除当前键
result = RegDeleteKey(hRoot, subKey.c_str());
if (result != ERROR_SUCCESS) {
std::cout << "删除注册表键失败: " << subKey << " 错误码: " << result << std::endl;
return false;
}
return true;
}
bool deleteRegistryKey(const std::string& keyPath)
{
return deleteRegistryKeyRecursive(HKEY_CLASSES_ROOT, keyPath);
}
bool installContextMenu()
{
std::cout << "安装 Windows Terminal 右键菜单..." << std::endl;
bool success = true;
// 1. 创建背景右键菜单项
std::cout << "\n=== 安装背景右键菜单 ===" << std::endl;
// 1.1 创建 wt 键
if (!createRegistryKey("Directory\\Background\\shell\\wt")) {
std::cout << "创建背景菜单键失败" << std::endl;
success = false;
}
// 1.2 设置默认值
if (!createRegistryKeyWithValue("Directory\\Background\\shell\\wt", "", "Terminal")) {
std::cout << "设置背景菜单名称失败" << std::endl;
success = false;
}
// 1.3 设置图标
if (!createRegistryKeyWithValue("Directory\\Background\\shell\\wt", "Icon", "\"" + wtPath + "\"")) {
std::cout << "设置背景菜单图标失败" << std::endl;
success = false;
}
// 1.4 创建 command 子键
if (!createRegistryKey("Directory\\Background\\shell\\wt\\command")) {
std::cout << "创建背景命令键失败" << std::endl;
success = false;
}
// 1.5 设置命令
if (!createRegistryKeyWithValue("Directory\\Background\\shell\\wt\\command", "", "\"" + wtPath + "\"")) {
std::cout << "设置背景命令失败" << std::endl;
success = false;
}
// 2. 创建目录右键菜单项
std::cout << "\n=== 安装目录右键菜单 ===" << std::endl;
// 2.1 创建 wt 键
if (!createRegistryKey("Directory\\shell\\wt")) {
std::cout << "创建目录菜单键失败" << std::endl;
success = false;
}
// 2.2 设置默认值
if (!createRegistryKeyWithValue("Directory\\shell\\wt", "", "Terminal")) {
std::cout << "设置目录菜单名称失败" << std::endl;
success = false;
}
// 2.3 设置图标
if (!createRegistryKeyWithValue("Directory\\shell\\wt", "Icon", "\"" + wtPath + "\"")) {
std::cout << "设置目录菜单图标失败" << std::endl;
success = false;
}
// 2.4 创建 command 子键
if (!createRegistryKey("Directory\\shell\\wt\\command")) {
std::cout << "创建目录命令键失败" << std::endl;
success = false;
}
// 2.5 设置命令 - 注意:这里需要转义双引号
std::string command = "\"" + wtPath + "\" -d \"%V\"";
if (!createRegistryKeyWithValue("Directory\\shell\\wt\\command", "", command)) {
std::cout << "设置目录命令失败" << std::endl;
success = false;
}
return success;
}
bool uninstallContextMenu()
{
std::cout << "卸载 Windows Terminal 右键菜单..." << std::endl;
bool success = true;
// 删除背景右键菜单项
if (!deleteRegistryKey("Directory\\Background\\shell\\wt")) {
std::cout << "警告: Directory\\Background\\shell\\wt 删除失败,可能不存在或已删除" << std::endl;
}
// 删除目录右键菜单项
if (!deleteRegistryKey("Directory\\shell\\wt")) {
std::cout << "警告: Directory\\shell\\wt 删除失败,可能不存在或已删除" << std::endl;
}
return success;
}
void refreshExplorer()
{
// 发送消息刷新资源管理器
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
(LPARAM) "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", SMTO_ABORTIFHUNG, 1000,
NULL);
// 通知资源管理器更新
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
}
public:
RegistryManager(const std::string& path) : wtPath(path)
{
// 规范化路径(统一使用反斜杠)
std::replace(wtPath.begin(), wtPath.end(), '/', '\\');
}
bool install()
{
if (!checkWtExists()) {
return false;
}
if (!isAdmin()) {
std::cout << "需要管理员权限来修改注册表" << std::endl;
std::cout << "请以管理员身份重新运行此程序" << std::endl;
return false;
}
bool success = installContextMenu();
if (success) {
refreshExplorer();
std::cout << "\n安装成功!" << std::endl;
} else {
std::cout << "\n安装失败!" << std::endl;
}
return success;
}
bool uninstall()
{
if (!isAdmin()) {
std::cout << "需要管理员权限来修改注册表" << std::endl;
std::cout << "请以管理员身份重新运行此程序" << std::endl;
return false;
}
bool success = uninstallContextMenu();
if (success) {
refreshExplorer();
std::cout << "卸载成功!" << std::endl;
} else {
std::cout << "卸载失败!" << std::endl;
}
return success;
}
};
void printUsage(const char* programName)
{
std::cout << "Windows Terminal 右键菜单管理工具" << std::endl;
std::cout << "用法:" << std::endl;
std::cout << " " << programName << " install <wt.exe路径>" << std::endl;
std::cout << " " << programName << " uninstall" << std::endl;
std::cout << std::endl;
std::cout << "示例:" << std::endl;
std::cout << " " << programName << " install \"D:\\Program\\terminal\\wt.exe\"" << std::endl;
std::cout << " " << programName << " uninstall" << std::endl;
}
int main(int argc, char* argv[])
{
// 设置控制台输出为UTF-8
SetConsoleOutputCP(CP_UTF8);
if (argc < 2) {
printUsage(argv[0]);
return 1;
}
std::string action = argv[1];
if (action == "install") {
if (argc < 3) {
std::cout << "错误: 需要指定 wt.exe 的路径" << std::endl;
printUsage(argv[0]);
return 1;
}
std::string wtPath = argv[2];
RegistryManager manager(wtPath);
return manager.install() ? 0 : 1;
} else if (action == "uninstall") {
std::string dummyPath = "C:\\Windows\\System32\\cmd.exe";
RegistryManager manager(dummyPath);
return manager.uninstall() ? 0 : 1;
} else {
std::cout << "错误: 未知的操作: " << action << std::endl;
printUsage(argv[0]);
return 1;
}
}