将应用程序添加到启动(注册表)

Posted

技术标签:

【中文标题】将应用程序添加到启动(注册表)【英文标题】:Add Application to Startup (Registry) 【发布时间】:2013-04-09 21:47:31 【问题描述】:

我正在尝试将我的软件添加到注册表中,我发现了一些我可以使用的代码,但不是完整的工作代码 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;

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

谢谢!

【问题讨论】:

【参考方案1】:

这里有一些代码可能符合您的要求。为您的 EXE 调用 RegisterProgram 以自行注册,以便在用户登录时自动启动。此函数调用 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;

【讨论】:

谢谢 selbie,它看起来确实正是我所需要的,我现在将对其进行测试。一个快速说明:如何向 exe 添加参数。该程序有配置文件,但它并不总是找到它,所以我想在 reg key .exe -f /includes/config.conf 之后添加 我添加了 int main RegisterProgram();测试它是否有效并且我在编译时出错: 1. 在函数“RegisterMyProgramForStartup”中:7718:5:警告:从不兼容的指针类型传递“RegCreateKeyExA”的参数 2 [默认启用] 2. c:\mingw\ bin\../lib/gcc/mingw32/4.7.2/../../../../include/winreg.h:66:23:注意:预期为“LPCSTR”,但参数类型为“短” unsigned int *' 7725:9:警告:从不兼容的指针类型传递“RegSetValueExA”的参数 2 [默认启用] 3. 预期为“LPCSTR”,但参数的类型为“PCWSTR” @MarkVoidale - 您将通过在构建环境中#defining UNICODE 和 _UNICODE 来修复编译问题。我已经在上面修复了我的答案,这样你就不必这样做了。另外,我更改了代码以在 exe 路径周围添加“引号”。我还更新了它以允许将参数传递给它。 我的错。我正在用 C++ 编译。固定。 @MarkVoidale - 将所有 wchar_t 类型更改为 WCHAR。【参考方案2】:

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

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

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

然后检查该值是否存在,将retvalERROR_SUCCESS 进行比较,如documentation 中所述。

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

【讨论】:

这不对。在您拨打RegOpenKey 之后,您必须拨打RegQueryValueEx。因为您需要掌握钥匙的句柄。 还是不对。 RegQueryValueEx 必须传递您已打开的密钥。这就是RegOpenKey 产生的关键。你只需要一把钥匙。就像我说的,不要把它命名为newValue,因为它是一个键而不是一个值。 应该是这样的:pastebin.com/RaKUNUMZ我没有仔细检查,根本没有错误检查。 subValue 尚未声明。因此,在尝试分配之前声明它。 您可以将调试器与 GCC 一起使用。例如 GDB。但是你也可以只使用 printf 调试。【参考方案3】:

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

【讨论】:

以上是关于将应用程序添加到启动(注册表)的主要内容,如果未能解决你的问题,请参考以下文章

如何将程序添加到系统服务实现开机自启动

管理员模式下将当前路径下程序添加到注册表开机启动批处理命令

CentOS 7 添加开机启动项

Ubuntu中怎样添加开机启动项

C# 将当前应用程序写入到注册表开机启动项中

C# Winform打包部署时添加注册表信息实现开机启动.