4

我正在尝试将我的软件添加到注册表中,我发现了一些我可以使用的代码,但不是完整的工作代码 C/C++ 对我来说是新的,不能自己创建它。但这是基本思想:如果没有创建它,请检查是否设置了 reg 键。

我能够使用以下代码获取我的程序位置:

TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL,szPath,MAX_PATH);

并且能够通过以下方式创建密钥:(不确定是否正确)

HKEY newValue;
RegOpenKey(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&newValue);
RegSetValueEx(newValue,"myprogram",0,REG_SZ,(LPBYTE)szPath,sizeof(szPath));
RegCloseKey(newValue);
return 0;

缺少什么,小检查一下钥匙是否还没有...

谢谢!

4

3 回答 3

12

这是一些可能满足您需求的代码。调用RegisterProgram您的 EXE 自行注册,以便在用户登录时自动启动。此函数调用GetModuleFileName然后调用另一个辅助函数,该函数调用该函数RegisterMyProgramForStartup将写入注册表。

调用IsMyProgramRegisteredForStartup(L"My_Program")以检测注册是否确实存在并且是否有效。

一个速记。在实际再次写出之前检查密钥是否存在的性能影响可以忽略不计。您可以盲目地调用 RegisterProgram,如果它已经存在,它将覆盖密钥。检测注册是否存在对于初始化启用或禁用自动启动的 UI 复选框很有用。(你是在给你的用户一个选择,对吧?因为我讨厌那些自动安装并自动运行而不给我选择的应用程序。)

BOOL IsMyProgramRegisteredForStartup(PCWSTR pszAppName)
{
    HKEY hKey = NULL;
    LONG lResult = 0;
    BOOL fSuccess = TRUE;
    DWORD dwRegType = REG_SZ;
    wchar_t szPathToExe[MAX_PATH]  = {};
    DWORD dwSize = sizeof(szPathToExe);

    lResult = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_READ, &hKey);

    fSuccess = (lResult == 0);

    if (fSuccess)
    {
        lResult = RegGetValueW(hKey, NULL, pszAppName, RRF_RT_REG_SZ, &dwRegType, szPathToExe, &dwSize);
        fSuccess = (lResult == 0);
    }

    if (fSuccess)
    {
        fSuccess = (wcslen(szPathToExe) > 0) ? TRUE : FALSE;
    }

    if (hKey != NULL)
    {
        RegCloseKey(hKey);
        hKey = NULL;
    }

    return fSuccess;
}

BOOL RegisterMyProgramForStartup(PCWSTR pszAppName, PCWSTR pathToExe, PCWSTR args)
{
    HKEY hKey = NULL;
    LONG lResult = 0;
    BOOL fSuccess = TRUE;
    DWORD dwSize;

    const size_t count = MAX_PATH*2;
    wchar_t szValue[count] = {};


    wcscpy_s(szValue, count, L"\"");
    wcscat_s(szValue, count, pathToExe);
    wcscat_s(szValue, count, L"\" ");

    if (args != NULL)
    {
        // caller should make sure "args" is quoted if any single argument has a space
        // e.g. (L"-name \"Mark Voidale\"");
        wcscat_s(szValue, count, args);
    }

    lResult = RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, 0, (KEY_WRITE | KEY_READ), NULL, &hKey, NULL);

    fSuccess = (lResult == 0);

    if (fSuccess)
    {
        dwSize = (wcslen(szValue)+1)*2;
        lResult = RegSetValueExW(hKey, pszAppName, 0, REG_SZ, (BYTE*)szValue, dwSize);
        fSuccess = (lResult == 0);
    }

    if (hKey != NULL)
    {
        RegCloseKey(hKey);
        hKey = NULL;
    }

    return fSuccess;
}

void RegisterProgram()
{
    wchar_t szPathToExe[MAX_PATH];

    GetModuleFileNameW(NULL, szPathToExe, MAX_PATH);
    RegisterMyProgramForStartup(L"My_Program", szPathToExe, L"-foobar");
}

int _tmain(int argc, _TCHAR* argv[])
{
    RegisterProgram();
    IsMyProgramRegisteredForStartup(L"My_Program");
    return 0;
}
于 2013-04-10T22:33:03.183 回答
4

要检查该值是否存在,请调用RegQueryValueEx.

LONG retval = RegQueryValueEx(hKey, "myprogram", NULL, NULL, NULL, NULL);

请注意,您调用newValue的实际上是键而不是值。为避免混淆,您应该这样命名。我用的名字hKey

然后检查该值是否存在,按照文档retvalERROR_SUCCESS的描述进行比较。

您的代码的另一个问题是绝对没有错误检查。我会把这个留给你解决。

于 2013-04-09T21:58:12.017 回答
0

你忘记写一个关于安全访问的论据

于 2019-02-03T15:15:58.257 回答