Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Операции с заданным типом вектора 
V
    Опции темы
TheDestroyer
Дата 30.5.2009, 02:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет



Здравствуйте. 
Не получается правильно получать значения из вектора своего типа:
Объявил тип:
Код

typedef struct process{
    string path;
    DWORD pid;
process(string path,DWORD pid){
    this->path = path;
    this->pid = pid;
    }
} PROCESS;

Создаю в классе вектор этого типа:
Код

class ProcUtil{
vector<PROCESS> GetList();
};

Чтобы записывать в вектор пришлось сделать конструктор структуре (см. первый код). В функции заполняю вектор следующим образом:
Код

vector<PROCESS> ProcUtil::GetList()
{
vector<PROCESS> p_list;
p_list.push_back(PROCESS("процесс",ProcessId));
return p_list;
}

А вот теперь надо работать с полученным вектором. Хочу найти в нем запись, делаю так:
Код

vector<PROCESS> lst = GetList();
if(find(lst.begin(), lst.end(), proc_path) != lst.end())
{return true;}

Это неправильно. А вот как правильно?
Также по этой теме интересуют следующие вопросы:
1. Обязательно ли добавлять в векор значения через конструктор определенного типа? Хотелось бы просто так: p_list.push_back.path("процесс"); ...
2. Смысл - иметь в векторе две записи для одного индекса. Может не структурой, а как-то подругому?
PM MAIL   Вверх
andrew_121
Дата 30.5.2009, 06:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 10
Всего: 33



Цитата(TheDestroyer @  30.5.2009,  02:14 Найти цитируемый пост)
Создаю в классе вектор этого типа:

Это называется - метод возвращающий вектор PROCESS-ов.


Код

vector<PROCESS> ProcUtil::GetList()
{
   vector<PROCESS> p_list;
   p_list.push_back(PROCESS("процесс",ProcessId));
   return p_list;
}

Здесь ты создаешь вектор с временем жизни равным телу этой функции. При возврате из функции вектор p_list уничтожается. Ты получаешь копию, в которой всегда содержится один элемент.


Код

vector<PROCESS> lst = GetList();
if(find(lst.begin(), lst.end(), proc_path) != lst.end())
{return true;}

Здесь ты правильно делаешь. Но учитывая что вектор ВСЕГДА будет содержать ОДИН элемент, зачем его искать? smile 


Цитата(TheDestroyer @  30.5.2009,  02:14 Найти цитируемый пост)
Это неправильно.

А что нужно? Не понятно же.


Цитата(TheDestroyer @  30.5.2009,  02:14 Найти цитируемый пост)
Обязательно ли добавлять в векор значения через конструктор определенного типа?

Нет. Можно так:
Код

Object o(...);
...
vector.push_back(o);



Цитата(TheDestroyer @  30.5.2009,  02:14 Найти цитируемый пост)
Смысл - иметь в векторе две записи для одного индекса.

Если этого не нужно, проверяй, есть ли этот элемент в векторе.


Цитата(TheDestroyer @  30.5.2009,  02:14 Найти цитируемый пост)
Может не структурой, а как-то подругому? 

Если объекты вектора имеют больше одного поля данных - только объектом.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
xvr
Дата 30.5.2009, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(TheDestroyer @ 30.5.2009,  02:14)
Здравствуйте. 
Не получается правильно получать значения из вектора своего типа:
Объявил тип:
Код

typedef struct process{
    string path;
    DWORD pid;
process(string path,DWORD pid){
    this->path = path;
    this->pid = pid;
    }
} PROCESS;


Еще нужен конструктор по умолчанию (без параметров).
Цитата

Чтобы записывать в вектор пришлось сделать конструктор структуре (см. первый код). В функции заполняю вектор следующим образом:
Код

vector<PROCESS> ProcUtil::GetList()
{
vector<PROCESS> p_list;
p_list.push_back(PROCESS("процесс",ProcessId));
return p_list;
}

Возвращать вектор (равно как и любой stl контейнер) by-value - не самая удачная идея, будет массовое копирование данных

Цитата

А вот теперь надо работать с полученным вектором. Хочу найти в нем запись, делаю так:
Код

vector<PROCESS> lst = GetList();
if(find(lst.begin(), lst.end(), proc_path) != lst.end())
{return true;}

Это неправильно. А вот как правильно?
А откуда компилятор узнает, по какому именно полю вы собираетесь 'find'? Определите своей структуре operator bool(const string&) const; - будет искать

Цитата

1. Обязательно ли добавлять в векор значения через конструктор определенного типа? Хотелось бы просто так: p_list.push_back.path("процесс"); ...
Сделайте конструктор от const string& (или от const char*) - будет можно
Цитата

2. Смысл - иметь в векторе две записи для одного индекса. Может не структурой, а как-то подругому?
По другому - не вектором, а например multimap


Это сообщение отредактировал(а) xvr - 30.5.2009, 10:41
PM MAIL   Вверх
TheDestroyer
Дата 30.5.2009, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет



Цитата(andrew_121 @  30.5.2009,  06:20 Найти цитируемый пост)
А что нужно? Не понятно же

Цитата(TheDestroyer @  30.5.2009,  02:14 Найти цитируемый пост)
Хочу найти в нем запись,

А точнее конкретное поле записи.
Цитата(andrew_121 @  30.5.2009,  06:20 Найти цитируемый пост)
Ты получаешь копию, в которой всегда содержится один элемент.

Наверное неправильно выразился, но, естесственно, я заполняю вектор в цикле множеством записей:
Код

vector<PROCESS> ProcUtil::GetList()
{
   vector<PROCESS> p_list;
for (int i=0; i<10;++i)
{
   p_list.push_back(PROCESS("процесс",ProcessId));
}
   return p_list;
}

Цитата(xvr @  30.5.2009,  10:40 Найти цитируемый пост)
Возвращать вектор (равно как и любой stl контейнер) by-value - не самая удачная идея, будет массовое копирование данных

Лучше возвращать указатель?
Код

vector<PROCESS> ProcUtil::GetList()
{
vector<PROCESS> p_list;
p_list.push_back(PROCESS("процесс",ProcessId));
return *p_list;
}

Цитата(xvr @  30.5.2009,  10:40 Найти цитируемый пост)
А откуда компилятор узнает, по какому именно полю вы собираетесь 'find'? Определите своей структуре operator bool(const string&) const; - будет искать

В том-то и дело, что я не понимаю как указать поле записи по которому нужно искать, если это вообще возможно. Похоже, необходимо сделать переменную типа PROCESS, в которой указать искомые поля и искать ее в векторе:
Код

vector<PROCESS> lst = GetList();
PROCESS item;
item.path = "искомое поле1";
item.pid = "искомое поле2";
if(find(lst.begin(), lst.end(),item) != lst.end())
{return true;}

Но как поступить с поиском если известно только одно поле item.path, и надо найти в векторе по этому полю запись, чтобы выяснить какое значение имеет у найденной записи поле item.pid? Остается перебирать в цикле все записи вектора:
Код

vector<PROCESS> lst = GetList();
vector<PROCESS>::const_iterator i;
PROCESS item;
item.path = "искомое поле1";
item.pid = "искомое поле2";
for (i=lst .begin(); i!=lst .end(); ++i)
{
if (*i.path =="искомое поле1") {DWORD found_pid = *i.pid; break;}
}

Или можно все-таки с find?
PM MAIL   Вверх
xvr
Дата 30.5.2009, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(TheDestroyer @ 30.5.2009,  13:27)
Цитата(xvr @  30.5.2009,  10:40 Найти цитируемый пост)
Возвращать вектор (равно как и любой stl контейнер) by-value - не самая удачная идея, будет массовое копирование данных

Лучше возвращать указатель?

Лучше передавать параметром by-ref
Код

void ProcUtil::GetList(vector<PROCESS>& ret_val)
{
ret_val.push_back(PROCESS("процесс",ProcessId));
}

Цитата

Цитата(xvr @  30.5.2009,  10:40 Найти цитируемый пост)
А откуда компилятор узнает, по какому именно полю вы собираетесь 'find'? Определите своей структуре operator bool(const string&) const; - будет искать

В том-то и дело, что я не понимаю как указать поле записи по которому нужно искать, если это вообще возможно. 
Никак. Алгоритм find использует простое сравнение (operator ==) для поиска. Который совпадет, тот и есть. 
(Я кстати описался, надо реализовывать не operator bool а operator ==)
Цитата

Похоже, необходимо сделать переменную типа PROCESS, в которой указать искомые поля и искать ее в векторе:
Неа, надо реализовать класс предикат (или несколько - для каждого поля, по которому нужно искать) и воспользоваться алгоритмом find_if
Цитата

Но как поступить с поиском если известно только одно поле item.path, и надо найти в векторе по этому полю запись, чтобы выяснить какое значение имеет у найденной записи поле item.pid? 
Использовать не vector а map (или multimap)

PM MAIL   Вверх
andrew_121
Дата 30.5.2009, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 10
Всего: 33



TheDestroyer, Выложите полный код. Поправлю, положу обратно. Пусть остальным польза будет.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
TheDestroyer
Дата 31.5.2009, 01:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет



Последовал совету xvr, использую map для составления списка: процесс, PID.
Пришлось объявить глобальную переменную map<string,DWORD> p_list; Наверное можно и без глобальной, просто передавать ее при вызове функции, и очищать ее каждый раз не надо будет.
Как просили, выкладываю код, (поиск списка процессов взять из примеров в инете). Его цель - поиск заданного процесса по пути запущенного файла и возвращение PID найденного процесса.
Код

class ProcUtil{
void GetList(map<string,DWORD>& p_list);
public:
DWORD monitor(string proc_path);
bool kill(DWORD pid);
bool exec(string proc_path);
};

// функция запуска процесса
bool ProcUtil::exec(string proc_path)
{
if((UINT)ShellExecute(
NULL,
"open",
proc_path.c_str(),
NULL,
NULL,
SW_SHOWNORMAL) <= 32) 
{
// обработка ошибок
error(0,"Не удалось запустить фаил!");
return false;
}
else
{return true;}
} // bool ProcUtil::exec(string proc_path)

// функция завершения процесса
bool ProcUtil::kill(DWORD pid)
{
HANDLE hProc;
if(!(hProc = OpenProcess(PROCESS_TERMINATE, 0, pid))) return FALSE;
return TerminateProcess(hProc, -1);
} // bool ProcUtil::kill(string proc_path)

map<string,DWORD> p_lis
// функция мониторинга процессов, поиск заданного процесса, возвращает PID искомого процесса
DWORD ProcUtil::monitor(string proc_path)
{
DWORD pid;
// получим список запущенных процессов
GetList(p_list);
// проверим есть ли искомый процесс в списке запущенных
map<string,DWORD>::iterator iter=p_list.find(proc_path);
if (iter!=p_list.end()) 
   {   pid = iter->second;   }
else
   {   pid = 0;   }
p_list.clear();
return pid;
}// bool ProcUtil::monitor(string proc_path)

void ProcUtil::GetList(map<string,DWORD>& p_list)
{
    HINSTANCE hPsApi;
    BOOL (WINAPI * _EnumProcesses)(DWORD *, DWORD, DWORD *);
    BOOL (WINAPI * _EnumProcessModules)(HANDLE, HMODULE *, DWORD, DWORD *);
    BOOL (WINAPI * _GetModuleFileNameEx)(HANDLE, HMODULE, LPTSTR, DWORD);

    // загружаем PSAPI.DLL
    hPsApi = LoadLibrary(_T("psapi.dll"));
    if (hPsApi == NULL)
        throw std::runtime_error("Error:LoadLibrary psapi.dll failed");

    // находим нужные функции в PSAPI.DLL
    *(FARPROC *)&_EnumProcesses = 
        GetProcAddress(hPsApi, "EnumProcesses");
    *(FARPROC *)&_EnumProcessModules =
        GetProcAddress(hPsApi, "EnumProcessModules");
#ifdef UNICODE
    *(FARPROC *)&_GetModuleFileNameEx =
        GetProcAddress(hPsApi, "GetModuleFileNameExW");
#else
    *(FARPROC *)&_GetModuleFileNameEx =
        GetProcAddress(hPsApi, "GetModuleFileNameExA");
#endif

    if (_EnumProcesses == NULL ||
        _EnumProcessModules == NULL ||
        _GetModuleFileNameEx == NULL)
    {
        FreeLibrary(hPsApi);
        SetLastError(ERROR_PROC_NOT_FOUND);
        throw std::runtime_error("Error:Cant find some entry points in psapi.dll");
    }

    // получаем описатель кучи процесса по умолчанию
    HANDLE hHeap = GetProcessHeap();

    DWORD dwError;
    DWORD cbReturned;
    DWORD cbAlloc = 128;
    DWORD * pdwIds = NULL;

    OSVERSIONINFO osvi;
    osvi.dwOSVersionInfoSize = sizeof(osvi);
    GetVersionEx(&osvi);

    DWORD dwSystemId = (osvi.dwMajorVersion < 5) ? 2 : 8;
    if(osvi.dwMajorVersion) dwSystemId=4;

    do
    {
        cbAlloc *= 2;
        if (pdwIds != NULL)
            HeapFree(hHeap, 0, pdwIds);

        // выделяем память для массива идентификаторов
        pdwIds = (DWORD *)HeapAlloc(hHeap, 0, cbAlloc);
        if (pdwIds == NULL)
        {
            FreeLibrary(hPsApi);
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            throw std::runtime_error("Error:HeapAlloc failed, cant allocate memory for array<ID>");
        }

        // получаем идентификаторы процессов
        if (!_EnumProcesses(pdwIds, cbAlloc, &cbReturned))
        {
            dwError = GetLastError();

            HeapFree(hHeap, 0, pdwIds);
            FreeLibrary(hPsApi);
            SetLastError(dwError);
            throw std::runtime_error("Error:EnumProcesses failed");
        }
    }
    while (cbReturned == cbAlloc);

    // теперь перечисляем все идентификаторы в массиве и вызываем
    // пользовательскую функцию для каждого процесса
    for (DWORD i = 0; i < cbReturned / sizeof(DWORD); i++)
    {
        DWORD dwProcessId = pdwIds[i];

        // обрабатываем два специальных случая: процесс Idle (0) и
        // процесс System (8)
        if (dwProcessId == 0)
        {
            p_list["Idle"]=dwProcessId;
        }
        else if (dwProcessId == dwSystemId)
        {
            p_list["System"]=dwProcessId;
        }
        else
        {
            HANDLE hProcess;
            HMODULE hExeModule;
            DWORD cbNeeded;
            TCHAR szModulePath[MAX_PATH];
            LPTSTR pszProcessName = NULL;

            // открываем описатель процесса
            hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
                FALSE, dwProcessId);
            if (hProcess != NULL)
            {
                if (_EnumProcessModules(hProcess, &hExeModule,
                    sizeof(HMODULE), &cbNeeded))
                {
                    if (_GetModuleFileNameEx(hProcess, hExeModule,
                        szModulePath, MAX_PATH))
                    {
                        pszProcessName = _tcsrchr(szModulePath, _T('\\'));
                        // szModulePath - полный путь процесса
                        // pszProcessName - имя исполняемого файла процесса
                        if (pszProcessName == NULL)
                            pszProcessName = szModulePath;
                    }
                }
            }
            CloseHandle(hProcess);
            p_list[szModulePath]=dwProcessId;
        }
    }
    HeapFree(hHeap, 0, pdwIds);
    FreeLibrary(hPsApi);
}
// пример использования
DWORD pid; // PID искомого процесса
ProcUtil proc_util;
string p = "C:\\Program Files\\Notepad2\\Notepad2.exe";
// проверка процесса на запущенность
pid = proc_util.monitor(p);
if (pid != 0 )
{// найден запущенный процесс
// завершене процесса
proc_util.kill(pid);
} // if (pid != 0 )

// запуск приложения
proc_util.exec(p);


Это сообщение отредактировал(а) TheDestroyer - 31.5.2009, 01:01
PM MAIL   Вверх
xvr
Дата 31.5.2009, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Немного неверный дизайн класса ProcUtil - 
  •  map p_list нужно сделать членом класса
  •  Заполнять p_list нужно один раз - в конструкторе (а не каждый раз в monitor). Можно еще предусмотреть специальный метод для перечитывания списка процессов, если они вдруг поменялись. При этом надо не забыть почистить map перед повторным заполнением (p_list.clear())
В остальном вполне ок (Не считая недочищенных хвостов из построения списка процессов, типа вычисления переменной pszProcessName , которая потом не используется)



PM MAIL   Вверх
andrew_121
Дата 31.5.2009, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 10
Всего: 33



xvr, уже сделал smile 


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
TheDestroyer
Дата 31.5.2009, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет



Спасибо, разобрался.
PM MAIL   Вверх
andrew_121
Дата 31.5.2009, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 10
Всего: 33



TheDestroyer, Ну так выложи, чтоб остальным польза была.



--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
TheDestroyer
Дата 31.5.2009, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет



Выкладываю, единственное отличие от предыдущего выложенного кода - закомментированая переменная pszProcessName (может кому пригодится) и map<string,DWORD> p_list перенесен в private раздел класса. Конструктор делать не стал, т.к. назначение класса немного шире, чем просто получение списка процессов и каждый раз при объявлении не нужно получать этот список.
Код

class ProcUtil{
map<string,DWORD> p_list
void GetList(map<string,DWORD>& p_list);
public:
DWORD monitor(string proc_path);
bool kill(DWORD pid);
bool exec(string proc_path);
};

// функция запуска процесса
bool ProcUtil::exec(string proc_path)
{
if((UINT)ShellExecute(
NULL,
"open",
proc_path.c_str(),
NULL,
NULL,
SW_SHOWNORMAL) <= 32) 
{
// обработка ошибок
error(0,"Не удалось запустить фаил!");
return false;
}
else
{return true;}
} // bool ProcUtil::exec(string proc_path)

// функция завершения процесса
bool ProcUtil::kill(DWORD pid)
{
HANDLE hProc;
if(!(hProc = OpenProcess(PROCESS_TERMINATE, 0, pid))) return FALSE;
return TerminateProcess(hProc, -1);
} // bool ProcUtil::kill(string proc_path)

// функция мониторинга процессов, поиск заданного процесса, возвращает PID искомого процесса
DWORD ProcUtil::monitor(string proc_path)
{
DWORD pid;
// получим список запущенных процессов
GetList(p_list);
// проверим есть ли искомый процесс в списке запущенных
map<string,DWORD>::iterator iter=p_list.find(proc_path);
if (iter!=p_list.end()) 
   {   pid = iter->second;   }
else
   {   pid = 0;   }
p_list.clear();
return pid;
}// bool ProcUtil::monitor(string proc_path)

void ProcUtil::GetList(map<string,DWORD>& p_list)
{
    HINSTANCE hPsApi;
    BOOL (WINAPI * _EnumProcesses)(DWORD *, DWORD, DWORD *);
    BOOL (WINAPI * _EnumProcessModules)(HANDLE, HMODULE *, DWORD, DWORD *);
    BOOL (WINAPI * _GetModuleFileNameEx)(HANDLE, HMODULE, LPTSTR, DWORD);

    // загружаем PSAPI.DLL
    hPsApi = LoadLibrary(_T("psapi.dll"));
    if (hPsApi == NULL)
        throw std::runtime_error("Error:LoadLibrary psapi.dll failed");

    // находим нужные функции в PSAPI.DLL
    *(FARPROC *)&_EnumProcesses = 
        GetProcAddress(hPsApi, "EnumProcesses");
    *(FARPROC *)&_EnumProcessModules =
        GetProcAddress(hPsApi, "EnumProcessModules");
#ifdef UNICODE
    *(FARPROC *)&_GetModuleFileNameEx =
        GetProcAddress(hPsApi, "GetModuleFileNameExW");
#else
    *(FARPROC *)&_GetModuleFileNameEx =
        GetProcAddress(hPsApi, "GetModuleFileNameExA");
#endif

    if (_EnumProcesses == NULL ||
        _EnumProcessModules == NULL ||
        _GetModuleFileNameEx == NULL)
    {
        FreeLibrary(hPsApi);
        SetLastError(ERROR_PROC_NOT_FOUND);
        throw std::runtime_error("Error:Cant find some entry points in psapi.dll");
    }

    // получаем описатель кучи процесса по умолчанию
    HANDLE hHeap = GetProcessHeap();

    DWORD dwError;
    DWORD cbReturned;
    DWORD cbAlloc = 128;
    DWORD * pdwIds = NULL;

    OSVERSIONINFO osvi;
    osvi.dwOSVersionInfoSize = sizeof(osvi);
    GetVersionEx(&osvi);

    DWORD dwSystemId = (osvi.dwMajorVersion < 5) ? 2 : 8;
    if(osvi.dwMajorVersion) dwSystemId=4;

    do
    {
        cbAlloc *= 2;
        if (pdwIds != NULL)
            HeapFree(hHeap, 0, pdwIds);

        // выделяем память для массива идентификаторов
        pdwIds = (DWORD *)HeapAlloc(hHeap, 0, cbAlloc);
        if (pdwIds == NULL)
        {
            FreeLibrary(hPsApi);
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            throw std::runtime_error("Error:HeapAlloc failed, cant allocate memory for array<ID>");
        }

        // получаем идентификаторы процессов
        if (!_EnumProcesses(pdwIds, cbAlloc, &cbReturned))
        {
            dwError = GetLastError();

            HeapFree(hHeap, 0, pdwIds);
            FreeLibrary(hPsApi);
            SetLastError(dwError);
            throw std::runtime_error("Error:EnumProcesses failed");
        }
    }
    while (cbReturned == cbAlloc);

    // теперь перечисляем все идентификаторы в массиве и вызываем
    // пользовательскую функцию для каждого процесса
    for (DWORD i = 0; i < cbReturned / sizeof(DWORD); i++)
    {
        DWORD dwProcessId = pdwIds[i];

        // обрабатываем два специальных случая: процесс Idle (0) и
        // процесс System (8)
        if (dwProcessId == 0)
        {
            p_list["Idle"]=dwProcessId;
        }
        else if (dwProcessId == dwSystemId)
        {
            p_list["System"]=dwProcessId;
        }
        else
        {
            HANDLE hProcess;
            HMODULE hExeModule;
            DWORD cbNeeded;
            TCHAR szModulePath[MAX_PATH];
            //LPTSTR pszProcessName = NULL;

            // открываем описатель процесса
            hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
                FALSE, dwProcessId);
            if (hProcess != NULL)
            {
                if (_EnumProcessModules(hProcess, &hExeModule,
                    sizeof(HMODULE), &cbNeeded))
                {
                    if (_GetModuleFileNameEx(hProcess, hExeModule,
                        szModulePath, MAX_PATH))
                    {
                        //pszProcessName = _tcsrchr(szModulePath, _T('\\'));
                        // szModulePath - полный путь процесса
                        // pszProcessName - имя исполняемого файла процесса
                        //if (pszProcessName == NULL)
                        //    pszProcessName = szModulePath;
                    }
                }
            }
            CloseHandle(hProcess);
            p_list[szModulePath]=dwProcessId;
        }
    }
    HeapFree(hHeap, 0, pdwIds);
    FreeLibrary(hPsApi);
}
// пример использования
DWORD pid; // PID искомого процесса
ProcUtil proc_util;
string p = "C:\\Program Files\\Notepad2\\Notepad2.exe";
// проверка процесса на запущенность
pid = proc_util.monitor(p);
if (pid != 0 )
{// найден запущенный процесс
// завершене процесса
proc_util.kill(pid);
} // if (pid != 0 )

// запуск приложения
proc_util.exec(p);

PM MAIL   Вверх
xvr
Дата 31.5.2009, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Тем более его не нужно получать каждый раз при вызове  метода monitor, достаточно одного раза - первого

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0601 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.