C++ 有没有办法获得一个应用程序';将其自动添加到注册表并在C+中与Windows启动一起运行的路径+;?

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

我正在开发一个应用程序,想知道是否有办法自动获取它的可执行路径,并通过将其添加到注册表来与Windows startup一起运行

这是我目前的职能:

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
后缀方法,但如果您不是在模式下编译ode>UNICODE模式,非固定方法将隐式地为
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