Определение имени выполняемого файла
От: Roman529  
Дата: 29.01.05 11:27
Оценка:
Нужна помощь. Существует задача — откомпилированный 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.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


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] -- это имя, введенное в командной строке, а не абсолютное.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


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 <iostream>

int
main( int, char ** argv )
    {
        std::cout << "Hello, parent! I am: " << argv[ 0 ] << std::endl;

        return 0;
    }


Родительский процесс:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include <iostream>

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.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


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/<pid>/exe
-- Андрей
Re: Определение имени выполняемого файла
От: korzhik Россия  
Дата: 20.11.06 12:02
Оценка:
Здравствуйте, Roman529, Вы писали:

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


http://blogs.msdn.com/oldnewthing/archive/2006/05/15/597984.aspx
Re: Определение имени выполняемого файла
От: Bork СССР  
Дата: 24.11.06 07:36
Оценка:
Здравствуйте, Roman529, Вы писали:

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


Eсть глобальня переменная, определенная а stdlib.h кажется _pgmptr (для юникода _wpgmptr) которая содержит полное имя исполняемого файла. для 2005 студии есть функции (get_pgmptr, get_wpgmptr).
Для винды это работает, для линуха не знаю.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Определение имени выполняемого файла
От: MaximE Великобритания  
Дата: 24.11.06 08:42
Оценка: 25 (1)
Здравствуйте, Кодт, Вы писали:

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


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


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


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

http://www.opengroup.org/onlinepubs/000095399/functions/exec.html

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".

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.