Народ, проблема в следующем! Пишу прогу на VC++ 6.0 (MFC). В NT для получеия списка процессов используется psapi.dll, а в Win9x — ToolHelp. На этапе старта она определяет WinNT или Win9x и должна использовать тот или иной механизм для получения списка процессов. На практике получается, что прога даёт сбой при старте, пытаясь проверить функции ToolHelp в NT и PSAPI в 9x из соответствующих заголовочных файлов и, естественно, не находя их. Как обойти это?
23.07.05 02:38: Перенесено модератором из 'MFC' — SchweinDeBurg
Исправлено форматирование текста.
Здравствуйте, KoMikadze, Вы писали:
KM>Народ, проблема в следующем! Пишу прогу на VC++ 6.0 (MFC). В NT для получеия списка процессов используется psapi.dll, а в Win9x — ToolHelp. На этапе старта она определяет WinNT или Win9x и должна использовать тот или иной механизм для получения списка процессов. На практике получается, что прога даёт сбой при старте, пытаясь проверить функции ToolHelp в NT и PSAPI в 9x из соответствующих заголовочных файлов и, естественно, не находя их. Как обойти это?
Чтобы узнать какая ось у тебя на компе попробуй следующий код (правда большой, но определяет прямо до Build'a):
char Buffer[1024];
memset(Buffer,0,sizeof(Buffer));
char *p=Buffer;
////////// Узнать ось
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*)&osvi)))
{
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
}
switch (osvi.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT: /////////// Проверяем семейство Windows NT
if (osvi.dwMajorVersion <= 4)
strcat(p,"Microsoft Windows NT ");
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
strcat(p,"Microsoft Windows 2000 ");
if (bOsVersionInfoEx) // Используем информацию из GetVersionEx.
{
if(osvi.wProductType == VER_NT_WORKSTATION)
{
if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
strcat(p,"Microsoft Windows XP ");
if(osvi.wSuiteMask & VER_SUITE_PERSONAL)
strcat(p,"Home Edition ");
else
strcat(p,"Professional ");
}
else
{
if ( osvi.wProductType == VER_NT_SERVER )
{
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
strcat(p,"Microsoft Windows .NET ");
if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
strcat(p,"DataCenter Server ");
}
else
{
if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
{
if( osvi.dwMajorVersion == 4 )
strcat(p,"Advanced Server ");
else
strcat(p,"Enterprise Server ");
}
else
{
if(osvi.wSuiteMask == VER_SUITE_BLADE)
strcat(p,"Web Server ");
else
strcat(p,"Server ");
}
}
}
}
else
{
HKEY hKey;
char szProductType[80];
DWORD dwBufLen=80;
LONG lRet;
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
0, KEY_QUERY_VALUE,&hKey);
lRet = RegQueryValueEx( hKey, "ProductType", NULL, NULL,(LPBYTE) szProductType, &dwBufLen);
RegCloseKey(hKey);
if(lstrcmpi("WINNT", szProductType) == 0 )
strcat(p,"Professional ");
if ( lstrcmpi( "LANMANNT", szProductType) == 0 )
strcat(p,"Server ");
if ( lstrcmpi( "SERVERNT", szProductType) == 0 )
strcat(p,"Advanced Server ");
}
// Отображаем версию, service pack (если есть), и номер билда.
if (osvi.dwMajorVersion <= 4)
{
strcat(p,"version ");
strcat(p,ltoa(osvi.dwMajorVersion,Hour,10));
strcat(p,".");
strcat(p,ltoa(osvi.dwMinorVersion,Hour,10));
strcat(p," ");
strcat(p,osvi.szCSDVersion);
strcat(p," Build ");
strcat(p,ltoa(osvi.dwBuildNumber & 0xFFFF,Hour,10));
}
else
{
strcat(p,osvi.szCSDVersion);
strcat(p," Build ");
strcat(p,ltoa(osvi.dwBuildNumber & 0xFFFF,Hour,10));
}
break;
case VER_PLATFORM_WIN32_WINDOWS: ////// Проверяем семейство Windows 95
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
{
strcat(p,"Microsoft Windows 95 ");
if (osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B')
strcat(p,"OSR2");
}
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
{
strcat(p,"Microsoft Windows 98 ");
if (osvi.szCSDVersion[1] == 'A')
strcat(p,"SE");
}
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
{
strcat(p,"Microsoft Windows Millennium Edition");
}
break;
}
MessageBox(p);
хм.......а здесь где-нить у вас на форуме можно редактировать сообщение? Я вот тег ccode забыл поставить.....
Здравствуйте, KoMikadze, Вы писали:
KM>Народ, проблема в следующем! Пишу прогу на VC++ 6.0 (MFC). В NT для получеия списка процессов используется psapi.dll, а в Win9x — ToolHelp. На этапе старта она определяет WinNT или Win9x и должна использовать тот или иной механизм для получения списка процессов. На практике получается, что прога даёт сбой при старте, пытаясь проверить функции ToolHelp в NT и PSAPI в 9x из соответствующих заголовочных файлов и, естественно, не находя их. Как обойти это?
http://www.rsdn.ru/?article/qna/baseserv/enumproc.xmlАвтор(ы): Александр Федотов
Дата: 23.10.2001
В статье рассматривается несколько способов перечисления процессов
в Windows различных версий, включая методы, пригодные для перечисления
процессов на другом компьютере.
Здравствуйте, Alex Fedotov, Вы писали:
AF>http://www.rsdn.ru/?article/qna/baseserv/enumproc.xmlАвтор(ы): Александр Федотов
Дата: 23.10.2001
В статье рассматривается несколько способов перечисления процессов
в Windows различных версий, включая методы, пригодные для перечисления
процессов на другом компьютере.
Всем откликнувшимся — СПАСИБО!
Проблема не в получении списка процессов (В данный момент прога имеет 2 версии — под 9х и NT). В OnInitDialog() я определяю семейство Win, далее создаю либо объект своего класса CInfoNT, либо своего класса CInfo9x. И использую его метод для получения списка процессов. В проект добавлены psapi.h, Tlhelp32.h, psapi.lib. В Win2k, WinXP всё работает, т.к. в них действуют оба способа и все функции работают. Как я понял, исполняемый файл перед выполнением проверяет все функции объявленные в проекте и т.о. в Win9x прога требует PSAPI, а в WinNT — ToolHelp. Возникает вышеобозначенный вопрос — КАК БЫТЬ?
Здравствуйте, KoMikadze, Вы писали:
KM>Проблема не в получении списка процессов (В данный момент прога имеет 2 версии — под 9х и NT). В OnInitDialog() я определяю семейство Win, далее создаю либо объект своего класса CInfoNT, либо своего класса CInfo9x. И использую его метод для получения списка процессов. В проект добавлены psapi.h, Tlhelp32.h, psapi.lib. В Win2k, WinXP всё работает, т.к. в них действуют оба способа и все функции работают. Как я понял, исполняемый файл перед выполнением проверяет все функции объявленные в проекте и т.о. в Win9x прога требует PSAPI, а в WinNT — ToolHelp. Возникает вышеобозначенный вопрос — КАК БЫТЬ?
Делать динамический импорт необходимых функций из соответствующих библиотек путем LoadLibrary() и GetProcAddress().
... << RSDN@Home 1.1.3 stable >>
Здравствуйте, KoMikadze, Вы писали:
AF>>http://www.rsdn.ru/?article/qna/baseserv/enumproc.xmlАвтор(ы): Александр Федотов
Дата: 23.10.2001
В статье рассматривается несколько способов перечисления процессов
в Windows различных версий, включая методы, пригодные для перечисления
процессов на другом компьютере.
KM>Всем откликнувшимся — СПАСИБО!
KM>Проблема не в получении списка процессов (В данный момент прога имеет 2 версии — под 9х и NT). В OnInitDialog() я определяю семейство Win, далее создаю либо объект своего класса CInfoNT, либо своего класса CInfo9x. И использую его метод для получения списка процессов. В проект добавлены psapi.h, Tlhelp32.h, psapi.lib. В Win2k, WinXP всё работает, т.к. в них действуют оба способа и все функции работают. Как я понял, исполняемый файл перед выполнением проверяет все функции объявленные в проекте и т.о. в Win9x прога требует PSAPI, а в WinNT — ToolHelp. Возникает вышеобозначенный вопрос — КАК БЫТЬ?
Ну так почитайте статью внимательно:
Обратите внимание, что мы связываемся с PSAPI.DLL динамически, загружая библиотеку с помощью LoadLibrary и получая адреса необходимых функций посредством GetProcAddress. Это позволит нам в дальнейшем включить эту функцию в программу, которая должна выполняться в том числе и на Windows 9x/Me, где PSAPI.DLL отстутствует. При реализации других способов перечисления процессов мы поступаем таким же образом.
И в конце:
Используя эту таблицу и приведенные выше функции, несложно написать функцию перечисления процессов, которая будет работать на всех версиях Windows. Например, если мы хотим использовать PSAPI при работе на Windows NT/2000/XP и ToolHelp32 API — на Windows 9x/Me, то функция будет выглядеть следующим образом:
BOOL
WINAPI
MyEnumProcesses(
IN PFNENUMPROC pfnEnumProc,
IN LPARAM lParam
)
{
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(osvi);
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
return EnumProcesses_ToolHelp(pfnEnumProc, lParam);
else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
return EnumProcesses_PsApi(pfnEnumProc, lParam);
else
return SetLastError(ERROR_CALL_NOT_IMPLEMENTED), FALSE;
}