C++ 有没有办法获得一个应用程序';将其自动添加到注册表并在C+中与Windows启动一起运行的路径+;?
我正在开发一个应用程序,想知道是否有办法自动获取它的可执行路径,并通过将其添加到注册表来与Windows startup一起运行 这是我目前的职能:C++ 有没有办法获得一个应用程序';将其自动添加到注册表并在C+中与Windows启动一起运行的路径+;?,c++,winapi,C++,Winapi,我正在开发一个应用程序,想知道是否有办法自动获取它的可执行路径,并通过将其添加到注册表来与Windows startup一起运行 这是我目前的职能: void Open(){ HKEY hKey; WCHAR path[MAX_PATH]; //to store the directory DWORD size = GetModuleFileNameW(NULL, path, MAX_PATH); const char* StartName = "MyApplicatio
void Open(){
HKEY hKey;
WCHAR path[MAX_PATH]; //to store the directory
DWORD size = GetModuleFileNameW(NULL, path, MAX_PATH);
const char* StartName = "MyApplication";
LONG lnRes = RegOpenKeyEx( HKEY_CURRENT_USER,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
0 , KEY_WRITE,
&hKey);
if( ERROR_SUCCESS == lnRes )
{
lnRes = RegSetValueEx( hKey,
StartName,
0,
REG_SZ,
(LPBYTE)path,
size );
}
RegCloseKey(hKey);
}
我使用GetModuleFileName获取路径,但它返回的路径带有一个反斜杠,并且在注册表中它只识别“D”驱动器。例如:D:\Usuario\Desktop\log\mariobros.exe
(这是我登记处的打印件)
我怀疑问题在于,要将代码识别为单个反斜杠,它需要有一个双反斜杠。我认为应该是这样的:D:\\Usuario\\Desktop\\log\\mariobros.exe
有人知道我在这里能做什么吗
提前感谢。这看起来像是您传递了一个宽字符串,同时承诺它是一个窄字符串(从您的C型演员阵容中可以明显看出) 宽字符串中的第二个字节是0,这将终止窄字符串
建议:仅在处理Win API时使用宽字符串。您显然是在使用项目中未定义的
UNICODE
进行编译,这意味着RegOpenKeyEx()
和RegSetValueEx()
实际上分别调用了ANSI函数RegOpenKeyExA()
和RegSetValueExA()
(您可以将char*
字符串传递给它们而不会出现编译器错误,这一点很明显)
但是,您正在以Unicode UTF-16字符串的形式检索文件路径,并将其按原样传递给RegSetValueExA()
,因此在RegSetValueExA()时,您最终会将嵌入的nul
字符写入注册表
将UTF-16字符串误解为ANSI字符串,并将其每个字节分别重新编码为Unicode字符。ASCII范围内的Unicode字符中包含nul
字节
由于您使用的是Unicode函数来检索文件路径,并且由于注册表内部仅以Unicode形式存储字符串,因此应该使用注册表的Unicode函数来匹配相同的编码
另外,请注意,GetModuleFileName(A | W)
的返回值在输出字符串的长度中不包括空终止符,但是RegSetValueEx(A | W)
希望cbSize
参数包含足够的字节,以便为REG|(EXPAND | MULTI| uz)SZ
值类型提供空终止符
试试这个:
void Open()
{
WCHAR path[MAX_path];//用于存储目录
DWORD size=GetModuleFileNameW(空、路径、最大路径);
如果((大小>0)和&(大小<最大路径))
{
HKEY HKEY;
LONG lnRes=RegOpenKeyExW(HKEY_当前用户,
L“软件\\Microsoft\\Windows\\CurrentVersion\\Run”,
0,键设置值,
&香港教育学院);
如果(错误\u成功==lnRes)
{
lnRes=regsetValueXw(hKey,
L“我的申请”,
0,
瑞格施,
(LPBYTE)路径,
(尺寸+1)*尺寸(WCHAR);
雷克洛斯基(香港中学),;
}
}
}
双反斜杠仅适用于文字或应用第二层解释的情况(例如正则表达式)。以编程方式获取的路径不需要它。不需要额外的反斜杠。哦,我明白了。但为什么注册表中只能识别我的D驱动器?您的程序是否在\u UNICODE
/UNICODE
模式下编译?您在某些地方使用显式W
后缀方法,但如果您不是在A
后缀版本,您将wchar
s传递给需要char
的函数,反之亦然(例如,RegSetValueEx
正在接收一个宽字符path
,因此RegSetValueExA
会有问题;RegOpenKeyEx
正在接收一个窄字符注册表路径,因此RegOpenKeyExW
会有问题)。我建议保持一致;始终使用W
API,始终使用L
-前缀字符串文字。我认为它是UNICODE格式的,但我明白你的意思。将路径更改为CHAR和GetModuleFileName,改为GetModuleFileName,效果很好。非常感谢!这意味着你的编译设置是非UNICODE格式的。你是默认的ng到A
后缀API。无论API是RegSetValueExA
还是RegSetValueExW
(它们都以const BYTE*
作为参数),都需要强制转换;OP需要显示它们的编译设置,以便我们知道RegSetValueEx
是前者还是后者。@ShadowRanger由于RegOpenKeyEx()
和RegSetValueEx()的事实,我们已经隐式地知道编译设置是什么
接受char*
字符串时没有错误,这意味着编译必须明确设置为禁用UNICODE
。此外,由于此键中的字符串用作-如果您使用的是包含空格的长文件名,请使用带引号的字符串指示文件名结束和参数开始的位置-因此始终需要在getModuleFileName