2013-04-09 5 views
4

Я пытаюсь добавить свое программное обеспечение в реестр, я нашел несколько частей кодов, которые я могу использовать, но не полный рабочий код. C/C++ - это новое для меня и не может его создать. самостоятельно. Но вот основная идея: проверьте, установлен ли ключ реестра, если он не создан.Добавить приложение для запуска (реестр)

Я был в состоянии получить мое местоположение программы с помощью этого кода:

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

Чтобы проверить, существует ли значение, позвоните по номеру RegQueryValueEx.

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

Обратите внимание, что то, что вы назвали newValue, фактически является ключом, а не значением. Чтобы избежать путаницы, вы должны называть это такой. Я использовал имя hKey.

Затем, чтобы проверить, существует ли значение, сравните retval с ERROR_SUCCESS, как описано в documentation.

Другая проблема с вашим кодом в том, что проверка ошибок абсолютно отсутствует. Я оставлю это вам.

+0

Как это выглядит? http://pastebin.com/U85ZSrnY –

+0

Это не так. Вы должны вызвать 'RegQueryValueEx' после того, как вы вызвали' RegOpenKey'. Потому что вам нужно иметь ручку ключа. –

+0

О, моя глупая ошибка, как насчет теперь лучше? http://pastebin.com/0guvBRfj –

12

Вот код, который, вероятно, сделает то, что вы хотите. Позвоните RegisterProgram, чтобы ваш EXE самостоятельно зарегистрировался для автоматического запуска, когда пользователь входит в систему. Эта функция вызывает GetModuleFileName, а затем вызывает другую вспомогательную функцию с именем RegisterMyProgramForStartup, которая записывает в реестр.

Позвоните по номеру IsMyProgramRegisteredForStartup(L"My_Program"), чтобы узнать, существует ли регистрация и действительно ли она действительна.

Однократное примечание. Влияние производительности проверки на то, чтобы увидеть, существует ли ключ до его фактического написания, незначительно. Вы можете просто вызвать RegisterProgram вслепую и перезаписать ключ, если он уже существует. Обнаружение, если регистрация существует, полезна для инициализации вашего пользовательского интерфейса, который включает или отключает автозапуск. (Вы даете своим пользователям выбор, верно? Потому что я ненавижу приложения, которые автоматически устанавливают себя для автоматического запуска, не давая мне выбора.)

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; 
} 
+0

Спасибо, selbie действительно выглядит именно так Мне нужно, чтобы я протестировал его сейчас. Однократное замечание: как добавить аргументы в exe. У программы есть файл конфигурации, но он не всегда находит его, поэтому я хочу добавить после ключа reg .exe -f/includes/config.conf –

+0

Я добавил int main RegisterProgram(), чтобы проверить, работает ли он, и у меня была ошибка при компиляции: 1. В функции 'RegisterMyProgramForStartup ': 7718: 5: warning: передать аргумент 2 из' RegCreateKeyExA 'из incompat ible указательный тип [включен по умолчанию] 2. c: \ mingw \ bin \ ../ lib/gcc/mingw32/4.7.2 /. ./../../../include/winreg.h:66:23: note: ожидаемый 'LPCSTR', но аргумент имеет тип 'short unsigned int *' 7725: 9: warning: передающий аргумент 2 из 'RegSetValueExA' от incompati Тип указателя на ввод [включен по умолчанию] 3. Ожидаемый 'LPCSTR', но аргумент имеет тип 'PCWSTR' –

+1

@MarkVoidale - Вы исправите проблему компиляции #defining UNICODE и _UNICODE в вашей среде сборки. Я исправил свой ответ выше, так что вам не нужно это делать. Кроме того, я изменил код, чтобы добавить «кавычки» вокруг пути EXE. Я также обновил его, чтобы разрешить ему передавать аргументы. – selbie

Смежные вопросы