1. 程式人生 > >C++ 寫登錄檔新增環境變數

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;
}