Унификация получения списка процессов под WinNT и Win9x
От: KoMikadze Россия  
Дата: 04.07.04 10:18
Оценка:
Народ, проблема в следующем! Пишу прогу на VC++ 6.0 (MFC). В NT для получеия списка процессов используется psapi.dll, а в Win9x — ToolHelp. На этапе старта она определяет WinNT или Win9x и должна использовать тот или иной механизм для получения списка процессов. На практике получается, что прога даёт сбой при старте, пытаясь проверить функции ToolHelp в NT и PSAPI в 9x из соответствующих заголовочных файлов и, естественно, не находя их. Как обойти это?

23.07.05 02:38: Перенесено модератором из 'MFC' — SchweinDeBurg
Re: Унификация получения списка процессов под WinNT и Win9x
От: DiMidRoLL Россия www.hackcoding.h11.ru
Дата: 04.07.04 11:30
Оценка:
Исправлено форматирование текста.

Здравствуйте, 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);
Hello World!;
31 error(s) , 17 warning(s)
Re[2]: Унификация получения списка процессов под WinNT и Win
От: DiMidRoLL Россия www.hackcoding.h11.ru
Дата: 04.07.04 11:33
Оценка:
хм.......а здесь где-нить у вас на форуме можно редактировать сообщение? Я вот тег ccode забыл поставить.....
Hello World!;
31 error(s) , 17 warning(s)
Re: Унификация получения списка процессов под WinNT и Win9x
От: Alex Fedotov США  
Дата: 04.07.04 13:10
Оценка:
Здравствуйте, 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
Re[2]: Унификация получения списка процессов под WinNT и Win
От: KoMikadze Россия  
Дата: 05.07.04 19:25
Оценка:
Здравствуйте, 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. Возникает вышеобозначенный вопрос — КАК БЫТЬ?
Re[3]: Унификация получения списка процессов под WinNT и Win
От: Crypto Украина  
Дата: 05.07.04 20:00
Оценка:
Здравствуйте, 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 >>
Re[3]: Унификация получения списка процессов под WinNT и Win
От: Alex Fedotov США  
Дата: 05.07.04 20:08
Оценка:
Здравствуйте, 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;
}
-- Alex Fedotov
Re[4]: Унификация получения списка процессов под WinNT и Win
От: Аноним  
Дата: 07.07.04 14:05
Оценка:
Здравствуйте, Alex Fedotov, Вы писали:

AF>>>http://www.rsdn.ru/?article/qna/baseserv/enumproc.xml
Автор(ы): Александр Федотов
Дата: 23.10.2001
В статье рассматривается несколько способов перечисления процессов
в Windows различных версий, включая методы, пригодные для перечисления
процессов на другом компьютере.


Согласен, погорячился. Прошу прощения. Прочитал статью — хорошо написано. Сделал универсальную программу. Большое спасибо. Пока.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.