Определение текущего местонахождения exe

Тема в разделе "WASM.BEGINNERS", создана пользователем heed, 4 янв 2010.

  1. heed

    heed New Member

    Публикаций:
    0
    Регистрация:
    16 авг 2009
    Сообщения:
    21
    Подскажите как можно вычислить путь к exe из самого exe.

    Программа при кликании по exe должна открывать файл путь к которому относительный
    (даже нет никакого пути, просто file.ini)
    , но она ищет файл в текущем каталоге.
    Если Например открыть папку эксполорером или тоталКомандером
    , то всё нормально работает, текущий каталог тот из которого запускается.
    А если например кликнуть из панели инструментов в раскрывающемся дереве каталогов, то текущий каталог совсем другой.

    Буква диска постоянно меняется , и нужно запускать не создавая ярлык.
     
  2. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    http://msdn.microsoft.com/en-us/library/ms683197(VS.85).aspx
     
  3. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    почитай про GetPrivateProfileString и WritePrivateProfileString.
    Если последним параметром этим функциям передать просто имя файла, без пути, то он создаться/откроется в C:\Windows по умолчанию.
     
  4. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.625
    Адрес:
    Russia
    в досе в переменных окружения после 2 нулей в конце шел полный путь запущенного файла
     
  5. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    фак. сслыка не кликабельной получилась :dntknw: дайте редактирование!
     
  6. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    С другой стороны можно попробовать ExtractFilePath(GetCommandLine)+'file.ini'
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    RamMerLabs
    Уже много раз упоминалось, что самый точные результаты даёт GetMappedFileName/ZwQueryVirtualMemory(MemorySectionName). Такие ф-ии, как GetModuleFileName или те же Toolhelp-API не гарантируют правильный путь к образу.
     
  8. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    GetModuleFileNameEx, наверное. CreateProcess позволяет подсунуть совершенно любую командную строку, поэтому GetCommandLine не полностью надёжен.
     
  9. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    l_inc
    учитывая, как был сформулирован вопрос, GetModuleFileName хватит за глаза. а потом уже приступать к NativeAPI и разбору содержимого АП процесса в поисках загруженных модулей. имхо)
     
  10. heed

    heed New Member

    Публикаций:
    0
    Регистрация:
    16 авг 2009
    Сообщения:
    21
    >GetPrivateProfileString и WritePrivateProfileString

    я чего-то другим путём пошёл , просто через ReadFile() считываю

    спасибо за ссылку

    DWORD WINAPI GetModuleFileName(
    __in_opt HMODULE hModule,
    __out LPTSTR lpFilename,
    __in DWORD nSize
    );

    If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.

    читал через строку, и думал что всё понял :)
     
  11. heed

    heed New Member

    Публикаций:
    0
    Регистрация:
    16 авг 2009
    Сообщения:
    21
    >GetCommandLine

    GetCommandLine тоже пробую :)

    интересно что если при запуске из bat-файла без параметров, как просто
    start this.exe
    после имени файла вместо '\0' идут два байта 0x03
     
  12. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    RamMerLabs
    Там через слэш варианты выписаны, а не все необходимые вызовы. :) Так что Native API не обязательны.
    Хотя с тем, что "хватит за глаза", согласен. :) Да я бы и ничего не сказал, если б это кто-нибудь другой написал. :)
     
  13. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    <offtop>
    буду иметь ввиду :) спасибо, что открыто сказали об этом :)
    </offtop>
     
  14. heed

    heed New Member

    Публикаций:
    0
    Регистрация:
    16 авг 2009
    Сообщения:
    21
    не знаю может стоило заводить отдельную тему, просто всё с той-же утилитой никак не разберусь.
    Текущий каталог получил из GetCommandLine.
    Прикрепил бинарник, потомучто код стыдно показать :)

    Но теперь не пойму как правильно останавливать процессы. Утилиту делал когда появилось желание вынести все сервера (Apache, mysqld, ...) на отдельный HD и что-то не сросталось делать так при помощи денвера, vhosts все самодельные.

    Запущенные из под утилиты процессы убиваются простым TeminateProcess() , даже быстрее чем я думал. Там просто не многое должно устанавливаться как сервисы виндовс, хотел это как-то обойти.
    Теперь если я, не убив все эти процессы, пытаюсь выключить виндовс. Появляется и висит просьба подтвердить остановку программы. (Возможно потомучто httpd.exe запустил другой httpd.exe который в свою очередь запустил perl.exe как fastcgi-сервер ) И что-то показалось виндовс начинает дольше останавливаться, если я пользовался серверами. Процессы потомки уничтожаются все.

    Не смог найти как правильнее остановить процесс, В msdn показалось какие-то неподходящие api , и написано что-то вроде того что если так как я придушивать процессы , остаются невыгруженными из памяти dll, которые должны уведомляться что-ли как-то если процесс сам себя выключает. Ничего не понял вобщем.

    И самое главное не понял есть-ли другой способ выключений. Или всётаки придётся при включении программы регистрировать сервисы и разрегистрировать при выключении ?
    Второе мне кажется так-же не всегда будет срабатывать.

    // потом подумал может из-за того что у меня не освободились какие-то переменные, по сообщению WM_DESTROY освобождается массив структур, Shell_NotifyIcon(NIM_DELETE,&nid); , DestroyMenu(hTrayMenu);
    А подменю которые динамически добавлялись к основному меню
    уничтожаются. Их обязательно уничтожать ?



    // перезалил файл 17.10.2010
    фиксил
    подвисание окна при первом старте
    пропадание иконки в трее при перезапуске explorer
    добавил /GS- и самодельную memset для уменьшения размера exe
     
  15. heed

    heed New Member

    Публикаций:
    0
    Регистрация:
    16 авг 2009
    Сообщения:
    21
    Нашёл здесь такое:

    Значит-ли это что то что в обработчике WM_DESTROY совсем не выполняется при остановке виндовс?


    upd://
    Код (Text):
    1.     case WM_QUERYENDSESSION:
    2.     case WM_DESTROY:
    3. DESTROY:
    4.         stopping( zsett , -2);
    5.         Shell_NotifyIcon(NIM_DELETE,&nid);
    6.         DestroyMenu(hTrayMenu);
    7.         PostQuitMessage(0);
    8.         return (message ==  WM_QUERYENDSESSION) ? 1:0;
    9.     }
    10.     return DefWindowProc(hwnd,message,wParam,lParam);
    11. }
    ???
     
  16. Babyshamble

    Babyshamble New Member

    Публикаций:
    0
    Регистрация:
    2 май 2010
    Сообщения:
    67
    GetMappedFileName(ExeMain...)
     
  17. heed

    heed New Member

    Публикаций:
    0
    Регистрация:
    16 авг 2009
    Сообщения:
    21
    If the function succeeds, the return value specifies the length of the string copied to the buffer, in characters.

    я читал 04-01-2010 22:15:08

    но на win64XP , win32XP win32x7 win32Server2008 и кажется ещё где-то GetCommandLine() пока не ошибалась :)
     
  18. Babyshamble

    Babyshamble New Member

    Публикаций:
    0
    Регистрация:
    2 май 2010
    Сообщения:
    67
    Запусти ехе и переименуй/перемести его (в карантин) и увидешь.
     
  19. heed

    heed New Member

    Публикаций:
    0
    Регистрация:
    16 авг 2009
    Сообщения:
    21
    Не смог успеть переместить в карантин :) Там именно при запуске определяется текущёё нахождение.

    Насчёт
    проблема похоже в в чём-то другом. Снёс антивирус, отключил планировщик заданий, раз 15 перезагрузил, зависания при остановке виндовс вроде на одном уровне.

    Осталось только понять как ещё можно останавливать демонов ( особенно httpd ) кроме TeminateProcess().