注册表自启
32位程序与64位程序
看到网上好像有人说32位与64位程序自启的注册表位置是不同的(here)
其实不然
如下是我在64位win10下分别编译了一个32位和一个64位程序,放在桌面,配置了注册表自启
重启之后,都能正常自启
如果把这两项删除,在WOW6432Node
下配置自启
同样也能自启
工作目录相关问题
才疏学浅,个人猜想注册表自启的实质应该与在cmd中执行注册表键值的exe类似。
如:我有一个crossfire.exe,启动时需要加载同目录下的factory.dll和io.dat
如果我直接配置一个自启项为此exe的路径,是无法成功自启的。
因为windows进程的CurrentDirectory是以启动进程时所在的目录为准
打开cmd看一下,通过注册表自启相当于在此处直接运行,因为进程的当前工作目录是C:\Users\23028
,是无法加载factory.dll和io.dat的,
如果将这两个文件拷贝到C:\Users\23028
,是可以成功执行的
所以如果通过注册表自启某exe有加载某目录文件的需要的话,有三种方法解决:
- exe中涉及到路径的,全部写成绝对路径,这样无论怎么启动都能找到
- exe中使用API函数,如C系的chdir,改变当前工作目录,参考
- 使用批处理脚本,配置bat为注册表自启项,bat中使用cd切换工作目录。进阶写法是用vbs隐藏运行bat时的cmd窗口,见:批处理隐藏自身窗口。
一个示例
常见的能完成自启动的注册表位置
Windows开发:注册表编程
示例代码:
首先编译一个弹窗程序作为被自动运行的程序autorun_exe.exe,源码如下
//
// Created by 23028 on 2021/3/15.
//
#include <windows.h>
int main(){
MessageBox(NULL, "autorun success!", "autorun", MB_OK);
}
然后写一个操作注册表的程序
#include <windows.h>
#include <tchar.h>
#include <iostream>
BOOL Autorun(char* exePath){
HKEY hKey = NULL;
LPCTSTR subKeyPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
LONG openStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKeyPath, 0, KEY_ALL_ACCESS, &hKey);
if (openStatus == ERROR_SUCCESS){
// 键值项名字随便起
LPCTSTR myValueName = "wuming_autorun";
// 键值项数据是exe绝对位置
LPCTSTR myValueData = exePath;
// 写入键值项
if(!RegSetValueEx(hKey, myValueName, 0, REG_SZ, (LPBYTE)myValueData, _tcslen(myValueData))){
RegCloseKey(hKey);
return TRUE;
}
}
RegCloseKey(hKey);
return FALSE;
}
int main() {
char exePath[512];
std::cin >> exePath;
if(Autorun(exePath)){
std::cout << "success" << std::endl;
}
else{
std::cout << "failed:" << GetLastError() << std::endl;
}
Sleep(10 * 1000);
return 0;
}
管理员身份运行,输入exe路径,注意头尾各加一个双引号
杀软放行
成功写入
重启一下,成功自启
服务
服务编程没接触过,只做过service control manager,先留坑。