Search code examples
c++regedit

Problem with add value to registry with cpp


I am trying to add value to the registry in order to run my program on system startup and after execution in Regedit. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run

is only the first letter of the path "C"

int start_with_os() {
    long result;
    HKEY hkey;

    result = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Run"),
        0, KEY_READ | KEY_WRITE | KEY_QUERY_VALUE, &hkey);
    if (result != ERROR_SUCCESS) return 1;

    char* fpath = new char;
    GetModuleFileNameA(NULL, fpath, MAX_PATH);

    const size_t cSize = strlen(fpath) + 1;
    wchar_t* wc = new wchar_t[cSize];

    size_t outSize;
    mbstowcs_s(&outSize, wc, cSize, fpath, cSize-1);

    OutputDebugStringW(wc);

    result = RegSetValueEx(hkey,  _T("sysservice"), 0, REG_SZ, (BYTE*)wc, strlen((const char*)wc));
    if (result != ERROR_SUCCESS) return 1;

    RegCloseKey(hkey);
    return 0;
}

The output from variable wc is the correct path. C:\Users\Piotrek\source\repos\myprogram\Release\myprogram.exe


Solution

  • From the code you provided, I guess your project is using the Unicode character set.

    Microsoft documentation says that the last parameter of RegSetValueEx is in bytes.

    cbData

    The size of the information pointed to by the lpData parameter, in bytes. If the data is of type REG_SZ, REG_EXPAND_SZ, or REG_MULTI_SZ, cbData must include the size of the terminating null character or characters.

    So, change

    result = RegSetValueEx(hkey,  _T("sysservice"), 0, REG_SZ, (BYTE*)wc, strlen((const char*)wc));
    

    to

    result = RegSetValueEx(hkey,  _T("sysservice"), 0, REG_SZ, (BYTE*)wc, (_tcslen(wc) + 1) * sizeof(TCHAR));
    

    should work.


    Edit: Thanks @john for the comment, char* fpath = new char; is also an error.

    Consider to use TCHAR fpath[MAX_PATH]; directly. And the following code also needs to be changed to T string functions.