C++程序环境变量添加以及右键菜单

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-22 18:45   62   0

踩到的坑

注意:由于是对环境变量的操作,防止出问题,提前保存path的路径。

执行不成功可能原因:1. 字符串转换的问题(unicode和多字节), 2. 用管理员权限运行

#include <Windows.h>
#include <iostream>
#include <string>

using namespace std;

bool setRightMenu(string strRegKeyName, string strApplication, string& error){
 HKEY hresult;
 string strRegKey = "*\\shell\\" + strRegKeyName;// "*\\shell\\"表示任意类型,"txtfile\\shell\\"文本类型
 string strRegSubkey = strRegKey + "\\command";
 error = "";
 strApplication = strApplication + " %1"; // %1参数
 DWORD dwPos;
 //创建“加密”子键,并设置右键菜单项的名称
 if (RegCreateKeyEx(HKEY_CLASSES_ROOT, (LPSTR)(LPCSTR)strRegKey.c_str(), 0,
  NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY | KEY_ALL_ACCESS, NULL, &hresult, &dwPos) != ERROR_SUCCESS) {
  error += "RegCreateKeyEx Failure " + strRegKey;
  RegCloseKey(hresult);
  return false;
 }

 if (RegSetValueEx(hresult, NULL, 0, REG_SZ, (BYTE*)(LPCTSTR)strRegKeyName.c_str(), strRegKeyName.size()) != ERROR_SUCCESS) {
  error += "RegSetValueEx Failure " + strRegKeyName;
  RegCloseKey(hresult);
  return false;
 }
 //创建“command”子键,并设置关联的应用程序
 if (RegCreateKeyEx(HKEY_CLASSES_ROOT, (LPSTR)(LPCSTR)strRegSubkey.c_str(), 0,
   NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY | KEY_ALL_ACCESS, NULL, &hresult, &dwPos) != ERROR_SUCCESS) {
  error += "RegCreateKeyEx Failure " + strRegSubkey;
  RegCloseKey(hresult);
  return false;
 }

 if (RegSetValueEx(hresult, NULL, 0, REG_SZ, (const BYTE*)(LPCTSTR)strApplication.c_str(), strApplication.size()) != ERROR_SUCCESS) {
  error += "RegSetValueEx Failure " + strApplication;
  RegCloseKey(hresult);
  return false;
 }
 //关闭注册表
 RegCloseKey(hresult);
 return true;
}

bool delRightMenu(string strRegKeyName, string& error){
 HKEY hKey;
 string strRegKey = "*\\shell\\" + strRegKeyName;
 string strRegSubkey = "*\\shell";

 //注册表必须从里面到外面依次删除
 //打开父键
 if (RegOpenKeyEx(HKEY_CLASSES_ROOT, (LPSTR)(LPCSTR)strRegKey.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
  error += "RegOpenKeyEx Failure " + strRegKey;
  RegCloseKey(hKey);
  return false;
 }
 //删除“command”子键  
 if (RegDeleteKey(hKey, LPCTSTR("command")) != ERROR_SUCCESS) {
  error += "RegDeleteKey Failure command";
  RegCloseKey(hKey);
  return false;
 }

 if (RegOpenKeyEx(HKEY_CLASSES_ROOT, (LPSTR)(LPCSTR)strRegSubkey.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
  error += "RegOpenKeyEx Failure " + strRegSubkey;
  RegCloseKey(hKey);
  return false;
 }
 //删除“加密”子键  
 if (RegDeleteKey(hKey, LPCTSTR(strRegKeyName.c_str())) != ERROR_SUCCESS) {
  error += "RegDeleteKey Failure " + strRegKeyName;
  RegCloseKey(hKey);
  return false;
 }
 RegCloseKey(hKey);
 return true;
}

bool setPath(string path, string& error, bool del = false) {
 HKEY hKey;
 error = "";
 path = ";" + path;
 const char *key = "System\\CurrentControlSet\\Control\\Session Manager\\Environment";

 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ | KEY_WRITE, &hKey) != ERROR_SUCCESS) {
  error += "RegOpenKeyEx Failure!";
  RegCloseKey(hKey);
  return false;
 }
 DWORD dwType = REG_SZ;
 char data[1024] = {};
 DWORD dwSize = sizeof(data);

 //获取当前环境变量Path的值
 if (RegQueryValueEx(hKey, "Path", NULL, &dwType, (LPBYTE)data, &dwSize) != ERROR_SUCCESS) {
  error += "RegQueryValueEx Failure!";
  RegCloseKey(hKey);
  return false;
 }
 string environment(data);
 while ( int idx = environment.find(path)) {
  if (idx == environment.npos) break;
  environment.erase(idx, path.size());
 }

 if (!del) {
  environment += path;
 }

 //设置环境变量Path的值
 if (RegSetValueEx(hKey, "Path", NULL, REG_SZ, (const unsigned char *)environment.c_str(), environment.size()) != ERROR_SUCCESS) {
  error += "RegSetValueEx Failure!";
  RegCloseKey(hKey);
  return false;
 }
 string strRegSubkey = "Environment";

 if (SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)(LPCTSTR)strRegSubkey.c_str(), SMTO_ABORTIFHUNG, 5000, 0) == 0) {
  error += "SendMessageTimeout Failure!";
  RegCloseKey(hKey);
  return false;
 }

 RegCloseKey(hKey);
 return true;
}

int main(){
 string name = "ffplay";     // 注册名称
 string exe = "ffplay.exe";    // 应用名称
 string path = "D:\\ffmpeg\\bin";  // 应用路径
 
 string error = "";
 if (setPath(path, error)) {
  cout << "写入环境成功" << endl;
 }
 else {
  cout << "写入环境失败" << error << endl;
 }

 if (setRightMenu(name, path + "\\" + exe, error)){
  cout << "添加完成!右键点击任意文件看看" << endl;
 }
 else{
  cout << "添加失败!请以管理员身份运行" << error << endl;
 }

 if (delRightMenu(name, error)){
  cout << "删除右键菜单成功!" << endl;
 }
 else{
  cout << "删除右键菜单失败!" << error << endl;
 }

 if (setPath(path, error, true)) {
  cout << "删除环境成功" << endl;
 }
 else {
  cout << "删除写入环境失败" << error << endl;
 }
 return 0;
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP