In den bisherigen Beiträgen hieß es aber letztlich immer, es gäbe dafür keine definierte Windows-API. Deshalb möchte ich hier einmal ein kleines Demoprogrämmchen vorstellen, das zeigt, wie man mit dokumentierten Funktionsaufrufen eben diese Änderungen detektiert. Diese Änderungen dann ins eigene Environment zu übernehmen und zukünftig an Kindprozesse zu vererben, sollte dann nur noch Fleißarbeit sein, oder?
Hier der Code:
Code: Select all
// GetEnvChange.cpp : Defines the entry point for the console application.
//
#define _WIN32_WINNT 0x0400
#include <windows.h>
#include <userenv.h>
#include <stdio.h>
#include <conio.h>
#pragma comment(lib, "kernel32")
#pragma comment(lib, "user32")
#pragma comment(lib, "advapi32")
#pragma comment(lib, "userenv")
void DumpCurrentEnv()
{
HANDLE hToken = 0;
PWSTR pEnv = 0;
BOOL Ok = OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken);
if (Ok)
{
Ok = CreateEnvironmentBlock((LPVOID*)&pEnv, hToken, FALSE);
if (Ok)
{
// CreateEnvironmentBlock always returns wide strings
PWSTR pTmp = pEnv;
while (*pTmp)
{
_putws(pTmp);
pTmp += wcslen(pTmp) + 1;
}
DestroyEnvironmentBlock(pEnv);
}
else
{
puts("Can't create environment block!");
}
CloseHandle(hToken);
}
else
{
puts("Can't open process token!");
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch(iMsg)
{
case WM_DESTROY:
PostQuitMessage (0);
return 0;
case WM_SETTINGCHANGE:
if (wParam == 0 && strcmp((char*)lParam, "Environment") == 0)
{
DumpCurrentEnv();
}
return 0;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
void main(void)
{
WNDCLASS wndclass;
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = GetModuleHandle(NULL);
wndclass.hIcon = NULL;
wndclass.hCursor = NULL;
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = "GetEnvChangeWndClass";
RegisterClass(&wndclass);
HWND hClose = CreateWindow("GetEnvChangeWndClass",
"",
0,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
wndclass.hInstance,
NULL);
while (_kbhit()) getch();
puts("Waiting for environment changes. Press any key to quit.");
MSG msg;
for(;;)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if (_kbhit())
{
DestroyWindow(hClose);
}
else
{
Sleep(200);
}
}
}
}
Dann sollte jetzt doch nichts mehr dagegen sprechen, diese Funktionalität in TC einzubauen, oder?
