Как найти родительский exe из dll внутри dll?
Мне нужно сделать некоторые вещи в 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 ответа
Если вы объявили свою переменную 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.
Обратитесь к следующей ссылке, чтобы узнать о синтаксисе и подробном описании 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';
Теперь вы можете получить только имя исполняемого файла.
Я предполагаю, что вы пишете код на языке C. Скорее всего, вы не выделили MAX_PATH + 1 символ для имени файла.