Also im Grunde habe ich einen Dienst, der als mein Programm Update Manager fungieren soll. Das ist alles in meine Bemühungen um eine automatische Aktualisierung Programm zu machen, die den Benutzer nicht sein müssen angemeldetWie lese/ändere ich die Registrierungswerte, die ein anderer Windows-Dienst erstellt hat?
Also, wenn meine Update-Manager erstellt einige anfängliche Registrierungswerte/Strukturen mit dem folgenden Code installiert.
LPCWSTR strInITKeyName = L"SOFTWARE\\InIT\\";
DWORD rtime = 0;
HKEY InITKey;
LONG nInITError;
nInITError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strInITKeyName, 0, 0, &InITKey);
if (ERROR_NO_MATCH == nInITError || ERROR_FILE_NOT_FOUND == nInITError)
{
std::cout << "Registry key not found. Setting up..." << std::endl;
long nError = RegCreateKeyEx(HKEY_LOCAL_MACHINE, strInITKeyName, 0L, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &InITKey, NULL);
if (ERROR_SUCCESS != nError)
std::cout << "Error: Could not create registry key HKEY_LOCAL_MACHINE\\" << strInITKeyName << std::endl << "\tERROR: " << nError << std::endl;
else
{
std::cout << "Successfully created registry key HKEY_LOCAL_MACHINE\\" << strInITKeyName << std::endl;
// See https://www.experts-exchange.com/questions/10171094/Using-RegSetKeySecurity.html for example
//SECURITY_DESCRIPTOR sd;
//PACL pDacl = NULL;
//RegSetKeySecurity(InITKey);
}
}
else if (nInITError == ERROR_ACCESS_DENIED)
{
long nError = RegCreateKeyEx(HKEY_LOCAL_MACHINE, strInITKeyName, 0L, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &InITKey, NULL);
if (ERROR_SUCCESS != nError)
std::cout << "Error: Could not create registry key HKEY_LOCAL_MACHINE\\" << strInITKeyName << std::endl << "\tERROR: " << nError << std::endl;
else
std::cout << "Successfully created registry key HKEY_LOCAL_MACHINE\\" << strInITKeyName << std::endl;
}
else if (ERROR_SUCCESS != nInITError)
{
std::cout << "Cannot open registry key HKEY_LOCAL_MACHINE\\" << strInITKeyName << std::endl << "\tERROR: " << nInITError << std::endl;
rtime = 0;
}
// Generate guid
//
GUID guid;
HRESULT hr = CoCreateGuid(&guid);
// Convert the GUID to a string
OLECHAR* guidString;
StringFromCLSID(guid, &guidString);
// Setup registry values
// Sets clientguid value and ties to strInITKeyName
std::wstring clientguid = guidString; // InITKey
clientguid = clientguid.substr(1, 36);
LONG nClientGUIDError = RegSetValueEx(InITKey, L"clientguid", NULL, REG_SZ, (const BYTE*)clientguid.c_str(), (clientguid.size() + 1) * sizeof(wchar_t));
if (nClientGUIDError)
std::cout << "Error: " << nClientGUIDError << " Could not set registry value: " << "clientguid" << std::endl;
else
std::wcout << "Successfully set InIT clientguid to " << clientguid << std::endl;
// ensure memory is freed
::CoTaskMemFree(guidString);
RegCloseKey(InITKey);
Wenn es deinstalliert wird, löscht es dann die Registrierungswerte. Mein aktuelles Programm ist ein Windows-Dienst, der auf dem installierten Computer ausgeführt wird, der auf einige dieser Registrierungswerte zugreifen muss.
Zuvor hatte ich diesen Update-Manager nicht und legte stattdessen die Werte in der Registrierung im eigentlichen Programmdienst fest. Lesen und Schreiben funktionierte dann gut. Aber seit ich meinen Update-Manager dazu gebracht habe, diese Anfangswerte festzulegen, beabsichtige ich, dass mein Haupt-Windows-Dienst auf sie zugreift.
Wenn ich dies versuche, habe ich jedes Mal einen ERROR_ACCESS_DENIED-Fehler erhalten, obwohl ich verschiedene Arten von Sicherheitstoken wie KEY_READ || versucht habe KEY_WOW64_64KEY und andere in vielen Kombinationen beim Versuch, den Schlüssel zu öffnen. Wie Sie oben gesehen haben, ordere ich KEY_ALL_ACCESS, wenn ich das Token setze. Ich würde denken, dass ich in der Lage sein sollte, in Ordnung zu gehen, aber es lässt mich nicht. Die einzige Schlussfolgerung, zu der ich kommen kann, ist, dass mein Update-Manager irgendwie Eigentümer der Schlüssel/Werte in der Registrierung ist.
Was wäre der richtige Code für den Zugriff auf diese Registrierungsdateien von meinem Hauptfenster Service?
Meine aktuellen Code für diese Registrierungswerte zugreift (die clientguid, die ich auf der Update Manager installieren erzeugen siehe oben Code):
// Log a service start message to the Application log.
WriteEventLogEntry(L"InITService Starting in OnStart", EVENTLOG_INFORMATION_TYPE);
this->m_ServiceLogger->info("Initialized logger bruh");
// Query clientguid from registry
HKEY InITKey;
std::wstring valuename;
ULONG nError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\InIT\\", 0, KEY_READ || KEY_WOW64_64KEY, &InITKey);
DWORD dwBufferSize = TOTALBYTES;
DWORD cbData;
WCHAR *wcBuffer = (WCHAR*)malloc(dwBufferSize);
cbData = dwBufferSize;
if (nError == ERROR_SUCCESS)
this->m_ServiceLogger->info("Getting reg");
if (nError == ERROR_SUCCESS)
{
std::wstring clientguid;
clientguid = L"";
valuename = L"clientguid";
nError = RegQueryValueExW(HKEY_LOCAL_MACHINE, valuename.c_str(), 0, NULL, (LPBYTE) wcBuffer, &cbData);
while (nError == ERROR_MORE_DATA) // Get a buffer that is big enough if not already
{
this->m_ServiceLogger->info("Increasing clientguid buffer size");
dwBufferSize += BYTEINCREMENT;
wcBuffer = (WCHAR*) realloc(wcBuffer, dwBufferSize);
cbData = dwBufferSize;
nError = RegQueryValueExW(HKEY_LOCAL_MACHINE, valuename.c_str(), 0, NULL, (LPBYTE)wcBuffer, &cbData);
}
if (ERROR_SUCCESS == nError)
{
clientguid = wcBuffer;
std::string cg(clientguid.begin(), clientguid.end());
this->m_ClientGuid = cg;
this->m_ServiceLogger->info("Clientguid yo: " + cg);
}
else if (nError = ERROR_ACCESS_DENIED)
this->m_ServiceLogger->info("ClientGUID: Access Denied");
if (!this->checkRegistryValues())
{
this->generateRegistry();
}
}
else
{
std::stringstream errstr;
errstr << nError;
this->m_ServiceLogger->info("Error: " + errstr.str() + " RegOpenKeyEx failed");
}
this->setSchedulingUtility(); // Hardcoded to set scheduled update at 1:00 AM
WriteEventLogEntry(L"InITService Initialized Schedule in OnStart", EVENTLOG_INFORMATION_TYPE);
this->m_ServiceLogger->info("Initialized ClientGUID: " + this->m_ClientGuid);
this->m_ServiceLogger->info("Initialized CurrentVersion: " + this->m_CurrentVersion);
this->m_ServiceLogger->info("Initialized WebServerURL: " + this->m_POSTAddress);
this->m_ServiceLogger->flush();
RegCloseKey(InITKey);
// Queue the main service function for execution in a worker thread.
CThreadPool::QueueUserWorkItem(&CSampleService::ServiceWorkerThread, this);