Мне нужно изменить функциональность приложения на основе имени исполняемого файла. Ничего особенного, просто меняются отображаемые строки и некоторые внутренние идентификаторы. Приложение написано на смеси собственного кода и кода .Net C++ - CLI.
Я рассмотрел два способа: проанализировать функцию GetCommandLine () в Win32 и заполнить ее AppDomain и другими вещами в .Net. Однако использование GetCommandLine не всегда будет работать, поскольку при запуске из отладчика командная строка пуста. И материал .Net AppDomain, похоже, требует много доработки.
Итак, каков самый лучший / самый простой / самый эффективный способ определения имени исполняемого файла в C++ / CLI? (Я как бы надеюсь, что пропустил что-то простое, доступное в .Net.)
Обновлено: я должен упомянуть, что это приложение с графическим интерфейсом Windows, использующее C++ / CLI, поэтому нет доступа к традиционной основной функции стиля C, оно использует функцию Windows WinMain ().





Вызовите GetModuleFileName (), используя 0 в качестве дескриптора модуля.
Примечание: вы может также используете параметр argv[0] для основного или вызываете GetCommandLine(), если основного нет. Однако имейте в виду, что эти методы не обязательно дадут вам полный путь к исполняемому файлу. Они вернут ту же строку символов, которая использовалась для запуска программы. Вместо этого вызов GetModuleFileName() всегда даст вам полный путь и имя файла.
Используйте аргумент argv для main:
int main(int argc, char* argv[])
{
printf("%s\n", argv[0]); //argv[0] will contain the name of the app.
return 0;
}
Возможно, вам потребуется просканировать строку, чтобы удалить информацию о каталоге и / или расширения, но имя будет там.
Да, это так, хотя я не ищу кроссплатформенный, а только для Windows с использованием Win32 или .Net.
-1, в некоторых случаях не работает. Например, введите только имя инструмента (игнорируйте расширение .exe) в командной строке.
В сборке есть статический метод, который получит его в .NET.
Assembly.GetEntryAssembly().FullName
Обновлено: я не понимал, что вам нужно имя файла ... вы также можете получить это, позвонив:
Assembly.GetEntryAssembly().CodeBase
Это даст вам полный путь к сборке (включая имя файла).
Хотя изначально это казалось правильным вариантом, на практике он не работает, поскольку имя сборки остается неизменным независимо от того, какое имя исполняемого файла присвоено.
Ферруччо ответил хорошо. Вот пример кода:
TCHAR exepath[MAX_PATH+1];
if (0 == GetModuleFileName(0, exepath, MAX_PATH+1))
MessageBox(_T("Error!"));
MessageBox(exepath, _T("My executable name"));
Из msdn: If the function fails, the return value is 0 (zero), так что да ... вы можете использовать == вместо != в своем условном выражении
Используйте __argv [0]
Самый простой и лучший ответ.
Только если программа запускалась с main или WinMain, а не wmain, wWinMain. Если "w" main является точкой входа, то должен использоваться __wargv. Другой "argv" останется нулевым.
Я могу подтвердить, что он работает под win64 / visual studio 2017 / MFC
TCHAR szFileName[MAX_PATH + 1];
GetModuleFileName(NULL, szFileName, MAX_PATH + 1);
auto exe = CString(szFileName);
exe содержит полный путь к exe.
Согласно MSDN:
The global variable
_pgmptris automatically initialized to the full path of the executable file, and can be used to retrieve the full path name of an executable file.
Это решение имеет дополнительное преимущество в том, что оно кроссплатформенное.