Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Проблема с Toolhelp32


Автор: Mishail 16.6.2007, 01:40
Доброго всем здравия!

Чем больше я пытась познать С++ тем больше удивляюсь. По большей части удивления приятные, но:

Задача: получить модули выбранного процесса.
Решение (точнее его часть, взято из примеров):
Код

void CAllprocDlg::OnButton1() 

{
    m_List1.ResetContent(); 
    HANDLE hSnap;
    hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnap == NULL) 
    {
        AfxMessageBox("Error Load ToolHelp");
    }
    PROCESSENTRY32 proc;
    if (Process32First(hSnap, &proc))
    {
        m_List1.AddString(proc.szExeFile);
        while (Process32Next(hSnap, &proc)) 
        {
        m_List1.AddString(proc.szExeFile);
        }
    }
}


void CAllprocDlg::OnButton2() 
{
int inIndex;
inIndex=m_List1.GetCurSel();
if (inIndex!=LB_ERR)
{
    CString csExName;
    m_List1.GetText(inIndex,csExName); 
    HANDLE hSnap1;
    hSnap1 = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnap1 == NULL) 
    {
        AfxMessageBox("Error Load ToolHelp");
    }
    else
    {
    PROCESSENTRY32 proc;
    if (Process32First(hSnap1, &proc))
    {
    while (Process32Next(hSnap1, &proc)) 
    {
    if (csExName==proc.szExeFile)
    {
        m_List1.ResetContent(); 
        HANDLE hSnap;
        hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,
                proc.th32ProcessID);
        if (hSnap == NULL) 
        {
            AfxMessageBox("Error Load ToolHelp");
        }
        else
        {
        MODULEENTRY32 mod;
        if (Module32First(hSnap, &mod))
        {
            m_List1.AddString(mod.szExePath);
            while (Module32Next(hSnap, &mod)) 
            {
                m_List1.AddString(mod.szExePath );
            }
        }
        CloseHandle(hSnap);
        }
    }
    }
    }
     CloseHandle(hSnap1);
    }
}
else AfxMessageBox("Select Process");
}




По нажатию Button1 - получаем в ListBox список процессов.
По нажатию Button2 - получаем список модулей выбранного процесса.

Не знаю есть ли ошибка в коде, но он успешно компилируется и даже работает, но далеко не на всех компьютерах! smile 

Единственная закономерность, которую мне пока удалось установить - это то, что программа успешно работает на компьютерах с WinXP SP1. Со вторым же сервис паком ХР ситуация следующая: процессы находятся нормально, а вот модули в них - ну никак smile 

Собственно вопрос: неужели версия ОС может так сильно влиять? Или это проблема в компиляторе (VC++ 6.0). Может настройки какие хитрые покрутить?

Удивительно, но аналогичная программка написанная на VB (с использованием этих же функций) успешно работает на всех, принимавших участие в тестировании, компьютерах независимо от версии ОС.

С надеждой, Михаил




Автор: Greeen 16.6.2007, 10:17
MSDN говорит что перед вызовом Module32First надо у структуры MODULEENTRY32 заполнить поле swSize. Может в этом проблема (хотя вряд ли)
Код

me32.dwSize = sizeof(MODULEENTRY32);

Автор: Mishail 16.6.2007, 14:31
Цитата

MSDN говорит что перед вызовом Module32First надо у структуры MODULEENTRY32 заполнить поле swSize. Может в этом проблема (хотя вряд ли)


Не помогло smile 

Может всетаки что-то с компилятором (диск столетней давности... мож сервис пак какой поставить?)? У VB проблем же нет... 

Михаил

Автор: W4FhLF 16.6.2007, 15:11
Код

int main(int argc, char* argv[])
{
    MODULEENTRY32 Module;
    Module.dwSize = sizeof(MODULEENTRY32);
    DWORD pID = GetCurrentProcessId();
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pID);
    if (hSnapshot)
    {
        Module32First(hSnapshot, &Module);
        do {
            cout << Module.szExePath << endl;
        } while (Module32Next(hSnapshot, &Module));
    }
    CloseHandle(hSnapshot);
    getche();
    return 0;
}


Вот самый простой пример, работает на SP1/SP2 без проблем. 

Автор: Mishail 16.6.2007, 16:26
Спасибо большое!

Но, видимо, проблема всетаки в настройках компилятора.

Как всегда - совершенно случайно обнаружилось что Debug-версия программы РАБОТАЕТ!!! Правда на компьютере без VC++ требует библиотеку MFC42D.DLL.

Разбираюсь пока Project -> Settings, но пока березультатно smile а так хочется запустить Release версию...

Может будут какие соображения?

С надеждой, Михаил. 

Автор: DigitSphinx 16.6.2007, 17:24
Если release версия не работает, а debug работает , то может быть из-за не инициализированных переменных

Добавлено через 13 минут и 12 секунд
Для того чтобы запустить прогу на компе без VStudio 
Открой погу программой dependency walker (входит в комплект VS) и посмотри от каких библотек зависит твоя прога , и самое простое решение это таскать эти либы с прогой !
А в конфигурации проекта надо поставить Use Static Library (и для релиза и для дебага)

Автор: Mishail 16.6.2007, 17:54
Заранее прошу прощения если буду задавать глупые вопросы (в C - новичек поэтому некотрые категории и понятия, возможно, неправильно понимаю).

Что под собой подразумевает инициализация переменных? (параллельно ищу ответ на этот вопрос в интернете smile )
Просто как-то интересно получается на одном компьютере работает на другом нет...

Вцелом же проект создавался следующим образом: MFC AppWizard далее ListBox, 2 кнопки, m_List1. Затем:  #include "tlhelp32.h" и код (пример см. 1-ое сообщение). 


Мысль по поводу "таскания" библиотек была, но - не хотелось бы, не правильно это как-то получается, хотя если это будет единственный выход - то, наверное придется smile 

Цитата

А в конфигурации проекта надо поставить Use Static Library (и для релиза и для дебага)


Не дано такого варианта - только Use MFC in a Shred DLL. Может не там настраиваю? (Project -> Settings General)/

С уважением, Михаил.


P/S видимо всетаки проблема в VC. 
Пошел качать SP5.

Автор: DigitSphinx 16.6.2007, 19:39
Я имел ввиду «Use MFC in a Static Library»  smile 
и если твоя прога зависит только от MFC то таскать ничего не надо !
Инициализировать значит давать значение при создании переменной
в особенности указатели , если указатель не инициализирован то при работе сним ты получишь ошибку типа “Access violation” и твоя прога завершает работу
но это только догадки ! , надо смотреть код на наличие ляпов .

Добавлено через 2 минуты и 19 секунд
P.S. Раз пошел качать то лучше сразу “КУПИ” VS2005 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)