Как найти родительский exe из dll внутри dll? - PullRequest
6 голосов
/ 09 июня 2011

Мне нужно сделать кое-что в dll, основываясь на том, какой процесс его загрузил. Так как я относительно новичок в программировании Windows, мне нужно помочь понять, как найти исполняемый файл, который загрузил текущую DLL. До сих пор я жестко кодировал имя exe-файла, что глупее всего делать: D

1) Кто-то предложил использовать функцию GetModuleFileName(). Но, похоже, это приводит к сбою моего приложения. (Я использовал 0 в качестве дескриптора модуля). Я не делаю ничего особенного. Я использовал следующий синтаксис

GetModuleFileName(0,&fileName,MAX_PATH)

РЕДАКТИРОВАТЬ: Я понял из здесь , что я не могу получить имя .exe с этим вызовом, поскольку он возвращает только имя DLL: (*

2) Это хорошая идея сделать это в DllMain ?? Я знаю, что DllMain не место для сложных вещей. Я также понимаю проблемы, связанные с блокировкой загрузчика. Все, что мне нужно, это найти имя родительского процесса.

Я ценю ваше время!

ДОБАВИТЬ: я пытался использовать GetProcessImageFileName после получения идентификатора родительского процесса. Я получаю ошибку нарушения доступа. При попытке отладки я заметил, что вызов openProcess оставляет мой аргумент результата (путь к файлу изображения-LPTSTR) как неверный указатель.
Код ошибки 87-НЕВЕРНЫЙ ПАРАМЕТР возвращается вызовом GetProcessImageFileName.
Но текущий идентификатор процесса является действительным идентификатором.
Вот код

LPTSTR fileName={0};  
HANDLE hP=OpenProcess(PROCESS_QUERY_INFORMATION ,FALSE, processes[i]) ;
GetProcessImageFileName(hP,fileName,(DWORD)MAX_PATH+1);

Что я делаю не так ??

Спасибо

РЕДАКТИРОВАТЬ ВАЖНО:

Я обнаружил, что я пытаюсь использовать openprocess в незанятом процессе. (т. Е.) Я забыл, что мой родительский процесс, возможно, ждет меня в режиме ожидания, поскольку я синхронизирую его. Так что теперь я получил плохую новость, что я не могу открыть пустой процесс с помощью OpenProcess. Как еще я могу посмотреть на объект неактивного процесса ?? (я точно знаю, что он бездействует, потому что не смог найти его в моментальном снимке. Мне пришлось использовать enumerateprocess, чтобы найти его идентификатор; но я использую обычное перечисление процессов из моментального снимка, чтобы сначала найти идентификатор родительского процесса)

Ответы [ 3 ]

3 голосов
/ 16 декабря 2013

Если вы объявили свою переменную fileName как что-то вроде char fileName или char fileName[MAX_PATH], вы можете получить сообщение об ошибке, так как ваш параметр неверен: вы используете адрес переменной (хотя вы не указываете, является ли онаошибка во время компиляции или ошибка во время выполнения, вы говорите, что это приводит к сбою в вашем приложении, поэтому я остановился на Ричарде, вы не указали свою переменную).

Я попробовал следующий код, который работает как внутри DLL(он получает имя исполняемого файла, а не модуля DLL) или из самого исполняемого файла.
(Примечание: код обновлен на основе комментариев Реми ниже, спасибо)

WCHAR exePath[MAX_PATH + 1];
DWORD len = GetModuleFileNameW(NULL, exePath, MAX_PATH);
if (len > 0) {
    wcout 
       << L"Exe path" 
       << (len == MAX_PATH) ? L" (truncated):" : L":" 
       << exePath 
       << endl;
} else {
    wcout 
       << L"Error getting exe path: " 
       << GetLastError() 
       << endl;
}

Примечание: если буфер недостаточно велик, GetModuleFileName урежет результат и вернет nSize.

Подробнее о обработке имен файловв Win32 .

2 голосов
/ 17 августа 2015

Обратитесь к следующей ссылке , чтобы узнать о синтаксисе и подробном описании GetModuleFileName ()

Шаги, которые необходимо сделать:

Сначала получите полный путь к исполняемому файлу с помощью кода:

TCHAR szEXEPath[2048];
char actualpath[2048];
GetModuleFileName ( NULL, szEXEPath, 2048 );
for(int j=0; szEXEPath[j]!=0; j++)
{
    actualpath[j]=szEXEPath[j];
}

Из полного пути к исполняемому файлу разделите строку, чтобы получить только имя исполняемого файла, используя встроенную функциюstr.find_last_of()

std::string str (actualpath);
std::size_t found = str.find_last_of("/\\");
std::cout<< str.substr(found+1) << '\n';

Теперь вы можете получить только имя исполняемого файла.

0 голосов
/ 09 июня 2011

Я предполагаю, что вы кодируете на языке C. Скорее всего, вы не выделили MAX_PATH + 1 символ для имени файла.

...