Перейти к содержимому

Как получить имя exe файла в си

  • автор:

Как получить имя исполняемого файла по идентификатору процесса

Нужно получить полное имя исполняемого файла (exe) зная идентификатор процесса. Основываясь на утверждении, что сам экзешник является первым (главным) модулем приложения, написал такой код:

HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); MODULEENTRY32 meModuleEntry; meModuleEntry.dwSize = sizeof(MODULEENTRY32); Module32First(hSnapshot, &meModuleEntry); if (INVALID_HANDLE_VALUE == hSnapshot) MessageBox(NULL, _T("ERROR"), _T("Information"), MB_ICONINFORMATION); else MessageBox(NULL, meModuleEntry.szExePath, _T("Information"), MB_ICONINFORMATION); 

Таким образом, если в pid передавать идентификатор своего процесса, то все работает. Но если передать любой другой идентификатор (например explorer’a), то переменная hSnapshot принимает значение INVALID_HANDLE_VALUE . Что я делаю не так? Или таким образом нельзя просмотреть модули чужого процесса?

Отслеживать

397 2 2 золотых знака 10 10 серебряных знаков 39 39 бронзовых знаков

/Fe (именование EXE-файла)

Указывает имя и каталог для EXE-файла или DLL, созданного компилятором.

Синтаксис

Аргументы

Путь
Относительный или абсолютный путь и имя базового файла, или относительный или абсолютный путь к каталогу или базовому имени файла, используемого для созданного исполняемого файла.

Замечания

Параметр /Fe позволяет указать выходной каталог, выходное имя исполняемого файла или оба файла для созданного исполняемого файла. Если имя пути заканчивается разделителем пути ( \ ), предполагается, что укажите только выходной каталог. В противном случае последний компонент pathname используется в качестве имени базы выходных файлов, а остальная часть имени пути указывает выходной каталог. Если имя пути не содержит разделителей путей, предполагается указать имя выходного файла в текущем каталоге. Имя пути должно быть заключено в двойные кавычки («), если он содержит любые символы, которые не могут находиться в коротком пути, например пробелы, расширенные символы или компоненты пути более восьми символов.

Если параметр /Fe не указан или если имя базы файла не указано в имени пути, компилятор предоставляет выходной файл имя по умолчанию, используя базовое имя первого исходного или объектного файла, указанного в командной строке, и расширение .exe или DLL.

Установка данного параметра компилятора в среде разработки Visual Studio

  1. Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.
  2. Выберите страницу свойств>компоновщика >конфигурации «Общие свойства».
  3. Измените свойство Output File . Нажмите ОК, чтобы сохранить внесенные изменения.

Установка данного параметра компилятора программным способом

  • См. раздел OutputFile.

Примеры

Следующая командная строка компилирует и связывает все исходные файлы C в текущем каталоге. Полученный исполняемый файл называется PROCESS.exe и создается в каталоге «C:\Users\User Name\repos\My Project\bin».

CL /Fe"C:\Users\User Name\repos\My Project\bin\PROCESS" *.C 

В следующей командной строке создается исполняемый файл с тем же базовым именем, что и первый исходный файл C:\BIN в текущем каталоге:

CL /FeC:\BIN\ *.C 

Как узнать имя исполняемого файла?

Возвращает полный путь к файлу.
А как получить строчку только с именем исполняемого файла без лишних усилий.
Есть ли такая функция?

2 ответа

26 сентября 2007 года
1.5K / / 03.11.2005

GetCommandLine — если прога запущена без параметров, то полный путь к файлу
получить имя исполняемого файла на Delphi и Borland C++ можно через ExtractFileName

26 сентября 2007 года
303 / / 18.01.2006

ExtractFileName можно.
Но это не API функция.
А есть ли API, аналогичная ExtractFileName?
GetCommandLine, видимо даст тот же результат, что и GetModuleFileName.

Как получить имя exe файла в си

Нужна помощь. Существует задача — откомпилированный exe-файл должен открывать сам себя, при чем его имя может изменяться, для необходимо узнать имя (самого себя). Поделитесь идеями. Заранее благодарен

Re: Определение имени выполняемого файла

От: Кодт
Дата: 29.01.05 11:45
Оценка:

Здравствуйте, Roman529, Вы писали:

R>Нужна помощь. Существует задача — откомпилированный exe-файл должен открывать сам себя, при чем его имя может изменяться, для необходимо узнать имя (самого себя). Поделитесь идеями. Заранее благодарен

Как правило (верное для DOS/Windows/Linux) путь к исполняемому файлу лежит в нулевом аргументе разобранной командной строки. Т.е.

/* C */ int main(int argc, char* argv[]) < printf("%s has been started!\n", argv[0]); >
rem bat-file echo %0 has been started!
# pyton from sys import * print argv[0], " has been started!"

Кроме того, в виндах можно получить путь к каждому модулю (exe, dll) текущего процесса по хэндлу модуля.

HMODULE hInst = GetModuleHandle( NULL // имя файла модуля, или NULL чтобы получить хэндл главного модуля (exe) ); TCHAR tszFileName[PATH_MAX]; GetModuleFileName(hInst, tszFileName, PATH_MAX);

Как это делается в других операционных системах — затрудняюсь сказать.
Перекуём баги на фичи!
Re: Определение имени выполняемого файла

От: eao197 http://eao197.blogspot.com
Дата: 29.01.05 11:47
Оценка:

Здравствуйте, Roman529, Вы писали:

R>Нужна помощь. Существует задача — откомпилированный exe-файл должен открывать сам себя, при чем его имя может изменяться, для необходимо узнать имя (самого себя). Поделитесь идеями. Заранее благодарен

На какой платформе?

Если на Windows, то есть функция GetModuleFileName. Есть еще GetModuleFileNameEx, но я ей не пользовался, т.к. она появилась уже после GetModuleFileName.

SObjectizer: Агентно-ориентированное программирование на C++.
Re[2]: Определение имени выполняемого файла

От: eao197 http://eao197.blogspot.com
Дата: 29.01.05 11:57
Оценка: 20 (1)

Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Roman529, Вы писали:

R>>Нужна помощь. Существует задача — откомпилированный exe-файл должен открывать сам себя, при чем его имя может изменяться, для необходимо узнать имя (самого себя). Поделитесь идеями. Заранее благодарен

К>Как правило (верное для DOS/Windows/Linux) путь к исполняемому файлу лежит в нулевом аргументе разобранной командной строки. Т.е.
К>

К>/* C */ К>int main(int argc, char* argv[]) К> < К>printf("%s has been started!\n", argv[0]); К>> К>

Под Windows это действительно так, но под Unix-ами обычно это то имя, которое ввели в командной строке. Т.е., если ввели ps, то argv[0] будет ps, а не /usr/bin/ps.

Только что проверил под Slackware — argv[0] — это имя, введенное в командной строке, а не абсолютное.

SObjectizer: Агентно-ориентированное программирование на C++.
Re[3]: Определение имени выполняемого файла

От: eao197 http://eao197.blogspot.com
Дата: 29.01.05 12:31
Оценка: 20 (1)

Здравствуйте, eao197, Вы писали:

E>Под Windows это действительно так, но под Unix-ами обычно это то имя, которое ввели в командной строке. Т.е., если ввели ps, то argv[0] будет ps, а не /usr/bin/ps.

E>Только что проверил под Slackware — argv[0] — это имя, введенное в командной строке, а не абсолютное.

Сейчас проверил и под Windows. Могут быть случаи, когда argv[0] не содержит абсолютного пути к файлу. Например, когда дочерний процесс запускается из родительского через CreateProcess:

#include int main( int, char ** argv ) < std::cout "Hello, parent! I am: " return 0; >
#define WIN32_LEAN_AND_MEAN #include #include int main( int, char ** ) < for( int i = 0; i != 5; ++i ) < PROCESS_INFORMATION pi; STARTUPINFO si = < sizeof( STARTUPINFO ) >; if( CreateProcess( "child.exe", 0, 0, // lpProcessAttributes, 0, // lpThreadAttributes, FALSE, // bInheritHandles, 0, // dwCreationFlag, 0, // lpEnvironment, 0, // lpCurrentDirectory, &si, // lpStatupInfo, &pi ) ) < WaitForSingleObject( pi.hProcess, INFINITE ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); Sleep( 1000 ); >else break; > return 0; >

Результат работы (когда child.exe и parent.exe находятся в одном каталоге):

Hello, parent! I am: child.exe
Hello, parent! I am: child.exe
Hello, parent! I am: child.exe
Hello, parent! I am: child.exe
Hello, parent! I am: child.exe

Причем, если имя запускаемого файла указано первым параметром CreateProcess, то в PATH исполняемый модуль не ищется (см. MSDN). Для поиска в PATH нужно указать имя модуля вторым параметром CreateProcess:

 if( CreateProcess( 0, "child", 0, // lpProcessAttributes, 0, // lpThreadAttributes, FALSE, // bInheritHandles, 0, // dwCreationFlag, 0, // lpEnvironment, 0, // lpCurrentDirectory, &si, // lpStatupInfo, &pi ) ) 

Тогда печать так же будет без абсолютного имени:

Hello, parent! I am: child
Hello, parent! I am: child
Hello, parent! I am: child
Hello, parent! I am: child
Hello, parent! I am: child

Проверял на WinXP SP2.

SObjectizer: Агентно-ориентированное программирование на C++.
Re[4]: Определение имени выполняемого файла

От: Кодт
Дата: 29.01.05 13:45
Оценка:

Здравствуйте, eao197, Вы писали:

E>>Под Windows это действительно так, но под Unix-ами обычно это то имя, которое ввели в командной строке. Т.е., если ввели ps, то argv[0] будет ps, а не /usr/bin/ps.

E>>Только что проверил под Slackware -- argv[0] -- это имя, введенное в командной строке, а не абсолютное.

E>Сейчас проверил и под Windows. Могут быть случаи, когда argv[0] не содержит абсолютного пути к файлу. Например, когда дочерний процесс запускается из родительского через CreateProcess:

E>Причем, если имя запускаемого файла указано первым параметром CreateProcess, то в PATH исполняемый модуль не ищется (см. MSDN). Для поиска в PATH нужно указать имя модуля вторым параметром CreateProcess:

О как! Век живи, век учись.
Буду знать. Тогда остаётся лишь GetModuleFileName.
Впрочем, наверное, и его можно крякнуть (но уже из самого запущенного процесса).

Перекуём баги на фичи!
Re[2]: Определение имени выполняемого файла

От: latemic
Дата: 17.11.06 16:55
Оценка:

Здравствуйте, Кодт, Вы писали:

К>Кроме того, в виндах можно получить путь к каждому модулю (exe, dll) текущего процесса по хэндлу модуля.
К>[c]
К>HMODULE hInst = GetModuleHandle(
К> NULL // имя файла модуля, или NULL чтобы получить хэндл главного модуля (exe)
К> );

К>TCHAR tszFileName[PATH_MAX];
К>GetModuleFileName(hInst, tszFileName, PATH_MAX);

TCHAR tszFileName[PATH_MAX]; GetModuleFileName(NULL, tszFileName, PATH_MAX);

"Если нельзя, но очень хочется. то можно"
Re[3]: Определение имени выполняемого файла

От: Андрей Коростелев http://www.korostelev.net/
Дата: 17.11.06 23:37
Оценка:

Здравствуйте, eao197, Вы писали:

E>Здравствуйте, Кодт, Вы писали:

К>>Здравствуйте, Roman529, Вы писали:

R>>>Нужна помощь. Существует задача — откомпилированный exe-файл должен открывать сам себя, при чем его имя может изменяться, для необходимо узнать имя (самого себя). Поделитесь идеями. Заранее благодарен

В nix-ах: если argv недоступен, парсь вывод ps.

std::string mySelfName; char myCommand[128]; sprintf(myCommand, "ps -o comm= -p %d", getpid()); FILE* f = popen((myCommand, "r"); char myBuf[128]; while (!feof(f)) < size_t myRead = fread( myBuf, 1, sizeof(myBuf)-1, f); if (myRead) < myBuf[myRead] = '\0'; mySelfName += myBuf; > else break; > pclose(f);

Так получишь свое короткое имя. Если нужен полный путь, читай /proc//exe

Re: Определение имени выполняемого файла

От: korzhik
Дата: 20.11.06 12:02
Оценка:

Здравствуйте, Roman529, Вы писали:

R>Нужна помощь. Существует задача — откомпилированный exe-файл должен открывать сам себя, при чем его имя может изменяться, для необходимо узнать имя (самого себя). Поделитесь идеями. Заранее благодарен

Re: Определение имени выполняемого файла

От: Bork
Дата: 24.11.06 07:36
Оценка:

Здравствуйте, Roman529, Вы писали:

R>Нужна помощь. Существует задача — откомпилированный exe-файл должен открывать сам себя, при чем его имя может изменяться, для необходимо узнать имя (самого себя). Поделитесь идеями. Заранее благодарен

Eсть глобальня переменная, определенная а stdlib.h кажется _pgmptr (для юникода _wpgmptr) которая содержит полное имя исполняемого файла. для 2005 студии есть функции (get_pgmptr, get_wpgmptr).
Для винды это работает, для линуха не знаю.

Re[2]: Определение имени выполняемого файла

От: MaximE
Дата: 24.11.06 08:42
Оценка: 25 (1)

Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Roman529, Вы писали:

R>>Нужна помощь. Существует задача — откомпилированный exe-файл должен открывать сам себя, при чем его имя может изменяться, для необходимо узнать имя (самого себя). Поделитесь идеями. Заранее благодарен

К>Как правило (верное для DOS/Windows/Linux) путь к исполняемому файлу лежит в нулевом аргументе разобранной командной строки.

POSIX с тобой не согласится:

Early proposals required that the value of argc passed to main() be "one or greater". This was driven by the same requirement in drafts of the ISO C standard. In fact, historical implementations have passed a value of zero when no arguments are supplied to the caller of the exec functions. This requirement was removed from the ISO C standard and subsequently removed from this volume of IEEE Std 1003.1-2001 as well. The wording, in particular the use of the word should, requires a Strictly Conforming POSIX Application to pass at least one argument to the exec function, thus guaranteeing that argc be one or greater when invoked by such an application. In fact, this is good practice, since many existing applications reference argv[0] without first checking the value of argc.

The requirement on a Strictly Conforming POSIX Application also states that the value passed as the first argument be a filename associated with the process being started. Although some existing applications pass a pathname rather than a filename in some circumstances, a filename is more generally useful, since the common usage of argv[0] is in printing diagnostics. In some cases the filename passed is not the actual filename of the file; for example, many implementations of the login utility use a convention of prefixing a hyphen ( '-' ) to the actual filename, which indicates to the command interpreter being invoked that it is a "login shell".

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *