C++ 写注册表添加环境变量

在站点搭建的时候需要安装.zip格式的 mysq l和 php的安装包等,需要将解压的路径写入系统环境变量中,这样方便在使用mysql或者php的时候不需要添加绝对路径而直接使用。所以需要将安装路径写入环境变量,如:D:\mywww\server\mysql\5.6\bin; 直接写入环境变量的Path。虽然以前有接触过注册表之类的,但是在用起来的时候还是很生疏,在经过网上查阅参考一些大牛的博客之后,我整理了一下适合自己使用的代码。虽然借鉴了一些大牛的代码,但是我也不记得是哪一个博客了,在此先感谢。既然是学习得到的知识,那我就整理出来供一些有需要的同学们相互学习,和探讨,希望指点不足之处。下面附上代码。

#include "stdafx.h"
#include <windows.h>
#include <shellapi.h>
#include <tchar.h>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <Strsafe.h>
#include <algorithm> 
#pragma comment(lib, "shell32.lib")
#include <iostream>
using namespace std;
//头文件有点多,因为是我是从我的demo抠出来的,可以对应的去掉试一下就行了。

int AddPath(const TCHAR* strPath);
bool nyStrstri(const wstring& src, const wstring& sub);
bool parseEnv(const wstring& data, const wstring path, std::vector<wstring>& vdata);
int IsPathExist(void *PerfData, const TCHAR *myPath);

int _tmain(int argc, _TCHAR* argv[])
{
	wstring mysqlPath = L"D:\\mywww\\server\\mysql\\5.6\\bin";
	int nRet = AddPath(mysqlPath.c_str());
	system("pause");
	return 0;
}

int AddPath(const TCHAR* strPath)
{
	if (strPath == NULL)
		return 0;

	HKEY hKey;
	const TCHAR* pEnvironmentKey = _T("System\\CurrentControlSet\\Control\\Session Manager\\Environment");

	if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, pEnvironmentKey, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &hKey))
	{
		std::cout << "RegOpenKeyEx Failded.\n" << endl;
	}

	DWORD dwBufferSize = 8192;
	DWORD dwData;
	DWORD dwRet;
	void* PerfData = malloc(dwBufferSize);
	dwData = dwBufferSize;

	LPCTSTR myVariable = _T("Path");
	dwRet = RegQueryValueEx(hKey, myVariable, NULL, NULL, (LPBYTE)PerfData, &dwData);
	while (dwRet == ERROR_MORE_DATA)
	{
		dwBufferSize += 4096;
		PerfData = realloc(PerfData, dwBufferSize);
		dwData = dwBufferSize;
		dwRet = RegQueryValueEx(hKey, myVariable, NULL, NULL, (LPBYTE)PerfData, &dwData);
	}

	if (dwRet == ERROR_SUCCESS)
	{
		if (IsPathExist(PerfData, strPath))
		{
			RegCloseKey(hKey);
			free(PerfData);
			return 1;
		}

		int len = dwData + _tcslen(strPath) + 1;
		TCHAR* temp = new TCHAR[len];
		memset(temp, 0x00, len);
		_tcscpy_s(temp, len, (TCHAR*)PerfData);

		std::wstring data;
		std::vector<wstring> vdata;
		parseEnv(temp, strPath, vdata);	//注意这里
		std::vector<wstring>::iterator it = vdata.begin();
		for (; it != vdata.end(); ++it)
		{
			data = data + it->c_str() + _T(";");
		}
		data = data + strPath + _T(";");

		vdata.clear();

		TCHAR* pathValue;
		TCHAR szbuf[4096] = { 0 };
		_tcscpy_s(szbuf, sizeof(szbuf) / sizeof(szbuf[0]), data.c_str());
		pathValue = szbuf;

		LONG  setResult = RegSetValueEx(hKey, myVariable, 0, REG_EXPAND_SZ, (LPBYTE)pathValue, (_tcslen(pathValue) + 1)*sizeof(TCHAR));
		DWORD  dwResult;
		SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, LPARAM(_T("Environment")), SMTO_ABORTIFHUNG, 5000, &dwResult);//广播立即执行 
		delete[]temp;
		temp = NULL;
	}
	RegCloseKey(hKey);//释放键句柄 
	free(PerfData);	//释放内存
	PerfData = NULL;
	return 1;
}


bool nyStrstri(const wstring& src, const wstring& sub)
{
	bool bRet = false;
	if (src.length() == 0 || sub.length() == 0)
	{
		return bRet;
	}

	string strSrc = UTF16toAnsi(src);
	string strSub = UTF16toAnsi(sub);

	transform(strSrc.begin(), strSrc.end(), strSrc.begin(), ::toupper);
	transform(strSub.begin(), strSub.end(), strSub.begin(), ::toupper);

	if (strstr(strSrc.c_str(), strSub.c_str()) != NULL)
	{
		bRet = true;
	}
	return bRet;
}

bool parseEnv(const wstring& data, const wstring path, std::vector<wstring>& vdata)
{
	std::stringstream strdata(UTF16toAnsi(data));
	std::string temp = "";
	std::vector<std::string> vtemp;
	while (getline(strdata, temp, ';'))
	{
		vtemp.push_back(temp);
	}
	bool bRet = false;
	std::string reStr;
	std::vector<string>::iterator it = vtemp.begin();
	for (; it != vtemp.end();)
	{
		bRet = nyStrstri(AnsitoUTF16(it->c_str()), path);
		if (bRet)
		{
			it = vtemp.erase(it);
			bRet = true;
			//break;
		}
		else
			++it;
	}
	//删除空字符串
	for (it = vtemp.begin(); it != vtemp.end();)
	{
		if (it->length() == 0)
		{
			it = vtemp.erase(it);
		}
		else
			++it;
	}
	//vdata = vtemp;
	std::vector<string>::iterator iit = vtemp.begin();
	for (; iit != vtemp.end(); iit++)
	{
		vdata.push_back(AnsitoUTF16(iit->c_str()));
	}
	return bRet;
}

int IsPathExist(void *PerfData, const TCHAR *myPath)
{
	TCHAR * myoldPath = (TCHAR*)PerfData;
	int i = 0;
	while (myoldPath[i] != _T('\0'))
	{
		i = i + 2;
	}
	TCHAR * path_t = new TCHAR[i / 2 + 2];

	i = 0;
	while (myoldPath[i] != _T('\0'))
	{
		path_t[i / 2] = myoldPath[i];
		i = i + 2;
	}
	path_t[i / 2] = _T('\0');
	path_t[i / 2 + 1] = _T('\0');

	wstring strMyoldPath;
	wstring strMyPath;

	strMyoldPath = path_t;
	strMyPath = myPath;

	if (strMyoldPath[strMyoldPath.length() - 1] != _T(';'))
	{
		strMyoldPath = strMyoldPath + _T(";");
	}
	if (strMyPath[strMyPath.length() - 1] != _T(';'))
	{
		strMyPath = strMyPath + _T(";");
	}


	if (-1 == strMyoldPath.find(strMyPath, 0))
	{
		delete path_t;
		return 0;
	}

	delete path_t;
	return 1;
}


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值