MediaState软件项目地址:https://gitee.com/txwh-media-state
对这个类进行一些说明:
类中的每一个方法都可以单独拿来使用,不受类中定义的变量影响
构造函数除外
类中的部分方法我已经标明了参考的网址,如果想要进行学习的话可以去详细学习
类中部分方法有这比较详细的注释,供大家参考
构造函数中"MediaStateT"是我的项目名称。项目地址如上
核心代码讲解:
GetMouleFileName
来获取当前程序运行的地址std::string get_programme_path() { TCHAR buffer[512] = {0}; GetModuleFileName(nullptr, buffer, sizeof(buffer)); //TCHAR转string //参考:https://www.cnblogs.com/staring-hxs/archive/2013/01/24/2874690.html UINT len = wcslen(buffer)*2; char *buf = (char *)malloc(len); UINT i = wcstombs(buf,buffer,len); std::string full_path = buf; return full_path; }
获取到当前程序运行的地址之后,加上程序的名称就可添加到自启动注册表了,对于不需要管理员权限的程序来讲,我们需要注册到HKEY_CURRENT_USER
下的
SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run
这个路径当中,不然会提示需要管理员权限
对于以上的函数实现:
这里用到的stringToPCWSTR函数下面的全部代码有些,这里为了讲述明白不再赘述
bool tart_with_system(const std::string &name, const std::string &full_path) { if (name_w == NULL){ //string转LPCWSTR stringToLPCWSTR(name, name_w); std::cout << "hello"; stringToLPCWSTR(full_path, path_w); } //打开启动项 if (RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS){ //判断注册表项目是否存在 TCHAR strDir[MAX_PATH] = {}; DWORD nLength = MAX_PATH; // If the function succeeds, the return value is ERROR_SUCCESS. // 函数解释:https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-reggetvaluea long result = RegGetValue(hkey, nullptr, name_w, RRF_RT_REG_SZ, 0, strDir, &nLength); //注册表已经存在 if (result != ERROR_SUCCESS) { //添加一个Key RegSetValueEx(hkey, name_w, 0, REG_SZ, (LPBYTE)path_w, (strlen(full_path.c_str()) + 1) * sizeof(TCHAR)); //关闭注册表 RegCloseKey(hkey); return true; }else{ std::cout << "StartWithSystem: Have been created!" << std::endl; return false; } } else{ std::cout << "StartWithSystem: Can`t open the Reg!" << std::endl; return false; } }
然后就是对于状态的检测,其实上面的代码已经状态检测的代码了,这里不在赘述,下面的源代码部分会有具体方法实现
最后就是删除注册表代码的实现:
这里只需要知道程序的名称就可以了
bool remove_sws(const std::string &name) { if (name_w == NULL){ //string转LPCWSTR stringToLPCWSTR(name, name_w); } if (RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS){ RegDeleteValue(hkey, name_w); RegCloseKey(hkey); return true; }else{ return false; } }
全部代码实现(可直接复制使用):
代码虽然看起来比较长,但不难。好多都是注释和为了代码阅读的缩进
这个【实用类库】系列到时候应该会整一个Gitee仓库存放。慢慢完善。
可以关注我的Gitee:踏雪无痕 (TaXue_TianXing) - Gitee.com
StartWithSystem.h
// // Created by Txwh on 2022/1/12. // #include <windows.h> #include <iostream> #include <stringapiset.h> class StartWithSystem { private: HKEY hkey; public: std::string programme_full_path; //PCWCHAR 是 WCHAR的指针,这里是为了防止内存泄露而不用new //所以选择新建非指针变量 WCHAR name_w[512]; WCHAR path_w[512]; public: StartWithSystem(); /** * @brief: string 转 LPCWSTR * @param: 被转换string * @param: 存储WCHAR的变量 * @note: PCWCHAR是WCHAR的指针 * **/ void stringToLPCWSTR(const std::string &converse_str, PCWCHAR out); /** * @brief: 获取当前程序运行的绝对路径 * @return: 返回绝对路径 * **/ std::string get_programme_path(); /** * @brief: 添加开机自启项目 * @param: 开机项目的名称 * @param: 开机项目的绝对路径 **/ bool start_with_system(const std::string &name, const std::string &full_path); /** * @brief: 检测给定程序名称是否在注册表中 * @param: 开机项目名称 * @param: 开机项目的绝对路径 **/ bool sws_statue(const std::string &name, const std::string &full_path); /** * @brief: 移除开机自启项 * @param: 开机项目的名称 * **/ bool remove_sws(const std::string &name); /** * @brief: 用来设置当前工作目录,解决自动启动导致的工作目录不对的问题 * @param: 开机项目的绝对路径 **/ void SetWorkDirectory(std::string & full_path); };
StartWithSystem.cpp
// // Created by Txwh on 2022/1/12. // #include "StartWithSystem.h" StartWithSystem::StartWithSystem() { hkey = NULL; programme_full_path = get_programme_path(); //string转LPCWSTR stringToLPCWSTR("MediaStateT", name_w); stringToLPCWSTR(programme_full_path, path_w); SetWorkDirectory(programme_full_path); } std::string StartWithSystem::get_programme_path() { TCHAR buffer[512] = {0}; GetModuleFileName(nullptr, buffer, sizeof(buffer)); //TCHAR转string //参考:https://www.cnblogs.com/staring-hxs/archive/2013/01/24/2874690.html UINT len = wcslen(buffer)*2; char *buf = (char *)malloc(len); UINT i = wcstombs(buf,buffer,len); std::string full_path = buf; return full_path; } void StartWithSystem::stringToLPCWSTR(const std::string &converse_str, PCWCHAR out) { // 参考:https://blog.csdn.net/wangshubo1989/article/details/50274103 wchar_t * buffer = new wchar_t[converse_str.size()+1]; MultiByteToWideChar(CP_ACP, 0, converse_str.c_str(), converse_str.size(), buffer, converse_str.size() * sizeof(wchar_t)); buffer[converse_str.size()] = 0; //宽字符一个字体两个字节 memcpy((void *)out, (void *)buffer, (converse_str.size()+1)*sizeof(wchar_t)); delete [] buffer; } bool StartWithSystem::start_with_system(const std::string &name, const std::string &full_path) { if (name_w == NULL){ //string转LPCWSTR stringToLPCWSTR(name, name_w); std::cout << "hello"; stringToLPCWSTR(full_path, path_w); } //打开启动项 if (RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS){ //判断注册表项目是否存在 TCHAR strDir[MAX_PATH] = {}; DWORD nLength = MAX_PATH; // If the function succeeds, the return value is ERROR_SUCCESS. // 函数解释:https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-reggetvaluea long result = RegGetValue(hkey, nullptr, name_w, RRF_RT_REG_SZ, 0, strDir, &nLength); //注册表已经存在 if (result != ERROR_SUCCESS) { //添加一个Key RegSetValueEx(hkey, name_w, 0, REG_SZ, (LPBYTE)path_w, (strlen(full_path.c_str()) + 1) * sizeof(TCHAR)); //关闭注册表 RegCloseKey(hkey); return true; }else{ std::cout << "StartWithSystem: Have been created!" << std::endl; return false; } } else{ std::cout << "StartWithSystem: Can`t open the Reg!" << std::endl; return false; } } bool StartWithSystem::sws_statue(const std::string &name, const std::string &full_path) { if (name_w == NULL){ //string转LPCWSTR stringToLPCWSTR(name, name_w); stringToLPCWSTR(full_path, path_w); } if (RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS){ //判断注册表项目是否存在 TCHAR strDir[MAX_PATH] = {}; DWORD nLength = MAX_PATH; // If the function succeeds, the return value is ERROR_SUCCESS. long result = RegGetValue(hkey, nullptr, name_w, RRF_RT_REG_SZ, 0, strDir, &nLength); //注册表已经存在 if (result != ERROR_SUCCESS) { return false; }else{ return true; } } else{ std::cout << "StartWithSystem: Can`t open the Reg!" << std::endl; return false; } } bool StartWithSystem::remove_sws(const std::string &name) { if (name_w == NULL){ //string转LPCWSTR stringToLPCWSTR(name, name_w); } if (RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS){ RegDeleteValue(hkey, name_w); RegCloseKey(hkey); return true; }else{ return false; } } void StartWithSystem::SetWorkDirectory(std::string & full_path) { //参考:https://www.cxyzjd.com/article/qq_42987442/108831931 std::string workpath_c = full_path; //删除最后的xxx.exe std::string work_path = workpath_c.substr(0, workpath_c.find_last_of('\\')); //设置工作目录 SetCurrentDirectoryA(work_path.c_str()); }