Узнать путь к приложению из диалога "Открыть с помощью"
От: Carc Россия https://vk.com/gosha_mazov
Дата: 03.09.21 10:12
Оценка:
Как узнать путь к приложению из диалога "Открыть с помощью"

Т.е. получить путь к приложению, которое пользователь выбрал для файла в диалоге "Открыть с помощью"?

То бишь для диалога, показываемого функцией SHOpenWithDialog,

или же ее старый вариант для XP через
('rundll32.exe'), TEXT("shell32.dll,OpenAs_RunDLL " + lpszFileName


Запустить приложение то легко, а вот как узнать чем именно был открыт файл, какое приложение выбрал пользователь в диалоге "Открыть с помощью"?
Aml Pages Home
Отредактировано 03.09.2021 10:16 Carc . Предыдущая версия . Еще …
Отредактировано 03.09.2021 10:13 Carc . Предыдущая версия .
Re: Узнать путь к приложению из диалога "Открыть с помощью"
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 03.09.21 16:12
Оценка:
Здравствуйте, Carc, Вы писали:

C>как узнать чем именно был открыт файл, какое приложение выбрал пользователь


Что значит "как узнать"? Кто именно будет узнавать, и в какой момент?
Re: Узнать путь к приложению из диалога "Открыть с помощью"
От: qaz77  
Дата: 06.09.21 08:30
Оценка:
Здравствуйте, Carc, Вы писали:

C>Как узнать путь к приложению из диалога "Открыть с помощью"

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


C>Т.е. получить путь к приложению, которое пользователь выбрал для файла в диалоге "Открыть с помощью"?

Зная id процесса можно получить полный путь к exe через QueryFullProcessImageName.
Только для этого у вызывающего потока должна быть выставлена привилегия SE_DEBUG_NAME (OpenThreadToken + AdjustTokenPrivileges).
Re[2]: Узнать путь к приложению из диалога "Открыть с помощью"
От: Carc Россия https://vk.com/gosha_mazov
Дата: 08.09.21 13:38
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, Carc, Вы писали:


C>>как узнать чем именно был открыт файл, какое приложение выбрал пользователь


ЕМ>Что значит "как узнать"? Кто именно будет узнавать, и в какой момент?

Узнать должен вызывающий код.
Aml Pages Home
Re[2]: Узнать путь к приложению из диалога "Открыть с помощью"
От: Carc Россия https://vk.com/gosha_mazov
Дата: 08.09.21 13:41
Оценка:
Здравствуйте, qaz77, Вы писали:

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


C>>Как узнать путь к приложению из диалога "Открыть с помощью"

Q>Наверное, только отслеживать создание новых процессов с помощью какого-то хука.
Вот этого то как раз и не хотелось… Хуки, привилегии…
Q>Вот такой громоздкий пример удалось найти для юзер мода:
Q>
Aml Pages Home
Re[3]: Узнать путь к приложению из диалога "Открыть с помощью"
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.09.21 14:12
Оценка:
Здравствуйте, Carc, Вы писали:

C>>>как узнать чем именно был открыт файл, какое приложение выбрал пользователь

ЕМ>>Что значит "как узнать"? Кто именно будет узнавать, и в какой момент?

C>Узнать должен вызывающий код.


Откуда этот код будет вызываться, в какое время, в каких условиях?
Re[4]: Узнать путь к приложению из диалога "Открыть с помощью"
От: Carc Россия https://vk.com/gosha_mazov
Дата: 08.09.21 14:22
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, Carc, Вы писали:


C>>>>как узнать чем именно был открыт файл, какое приложение выбрал пользователь

ЕМ>>>Что значит "как узнать"? Кто именно будет узнавать, и в какой момент?

C>>Узнать должен вызывающий код.


ЕМ>Откуда этот код будет вызываться, в какое время, в каких условиях?

User mode, по команде пользователя (кнопка, команда меню).

1) Тут как вариант или же SHOpenWithDialog, но эта функция не вернет ни выбранного приложения, ни пути к нему.

2) Или же старый вариант, через ShellExecuteEx ('rundll32.exe'), TEXT("shell32.dll,OpenAs_RunDLL " + lpszFileName.
Но это тоже не годится.
В этом варианте вернется в структуре SHELLEXECUTEEX хендл процесса именно что самого rundll32.exe. А он мне нафиг не нужен.

Суть задачи, дождаться в фоновом потоке завершения выбранного пользователем приложения, и соответственно, что-то там проверить на предмет изменений приложению файлу (lpszFileName).
Aml Pages Home
Re[5]: Узнать путь к приложению из диалога "Открыть с помощью"
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 09.09.21 09:17
Оценка:
Здравствуйте, Carc, Вы писали:

ЕМ>>Откуда этот код будет вызываться, в какое время, в каких условиях?

C>User mode, по команде пользователя (кнопка, команда меню).
C>дождаться в фоновом потоке завершения выбранного пользователем приложения

Все равно непонятно. Это Ваш код будет вызывать SHOpenWithDialog? Или Ваш код будет просто работать в совершенно левом процессе, и как-то мониторить такие события?

В любом случае, без хаков/хуков тут не обойтись, и это нормально. Система возвращает информацию о приложении, когда Вы запускаете его непосредственно, через CreateProcess или ShellExecute. А SHOpenWithDialog — это просто способ дернуть стандартную функцию из своего кода, она вообще может выполняться в контексте Explorer'а, и не предполагает подробного отчета о результате.
Re[5]: Узнать путь к приложению из диалога "Открыть с помощью"
От: Stanislav V. Zudin Россия  
Дата: 09.09.21 09:36
Оценка:
Здравствуйте, Carc, Вы писали:

C>Суть задачи, дождаться в фоновом потоке завершения выбранного пользователем приложения, и соответственно, что-то там проверить на предмет изменений приложению файлу (lpszFileName).


Дык может сделать свой диалог "Open with..."? Информация о зарегистрированных в системе расширениях доступна.
Все данные оказываются под контролем — запускай что хочешь, проверяй как хочешь.
_____________________
С уважением,
Stanislav V. Zudin
Re[6]: Узнать путь к приложению из диалога "Открыть с помощь
От: Carc Россия https://vk.com/gosha_mazov
Дата: 09.09.21 11:37
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, Carc, Вы писали:


ЕМ>>>Откуда этот код будет вызываться, в какое время, в каких условиях?

C>>User mode, по команде пользователя (кнопка, команда меню).
C>>дождаться в фоновом потоке завершения выбранного пользователем приложения

ЕМ>Все равно непонятно. Это Ваш код будет вызывать SHOpenWithDialog? Или Ваш код будет просто работать в совершенно левом процессе, и как-то мониторить такие события?

Нет. Тут всё предельно четко: мой код будет вызываться из моего же процесса (моим же кодом).

ЕМ>В любом случае, без хаков/хуков тут не обойтись, и это нормально. Система возвращает информацию о приложении, когда Вы запускаете его непосредственно, через CreateProcess или ShellExecute.

Именно это меня и интересует. ShellExecute(EX) может мне вернуть HANDLE процесса, который она запустит. Но только без окна выбора OpenWith. А именно оно мне и нужно.

ЕМ> А SHOpenWithDialog — это просто способ дернуть стандартную функцию из своего кода, она вообще может выполняться в контексте Explorer'а, и не предполагает подробного отчета о результате.

А нахрена тогда она — функция SHOpenWithDialog — нужна?

Если убрать флаг OAIF_EXEC, то SHOpenWithDialog ничего не запустит, даже в случае выбора приложения пользователем + кнопка ОК. Но и путь к выбранному приложению, тоже не вернет. На кой тогда оно надо?
Aml Pages Home
Отредактировано 09.09.2021 11:40 Carc . Предыдущая версия .
Re[6]: Узнать путь к приложению из диалога "Открыть с помощью"
От: Carc Россия https://vk.com/gosha_mazov
Дата: 09.09.21 11:47
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

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


C>>Суть задачи, дождаться в фоновом потоке завершения выбранного пользователем приложения, и соответственно, что-то там проверить на предмет изменений приложению файлу (lpszFileName).


SVZ>Дык может сделать свой диалог "Open with..."?

Ну теоретически то я могу… Только юзабилити такого диалога будет ещё то.
а) не привычно пользователю
б) ограниченный UI

C>> Информация о зарегистрированных в системе расширениях доступна.

Я так понимаю, речь идет о QueryAssocString что ли? Так?

SVZ>Все данные оказываются под контролем — запускай что хочешь, проверяй как хочешь.


Ну дык такой вариант у меня есть, и кодить там немного… Но все таки хотелось бы именно, что достучаться до стандартного диалога OpenWith с возможностью получить путь к выбранному пользователем приложению…

Ибо в стандартном диалоге больше возможностей, выглядит привычно, выглядит наглядно (иконки приложений и все такое). В моем варианте диалога так не получится (хотя бы те же иконки приложений, хрен я их там нарисую).
Aml Pages Home
Re[5]: Узнать путь к приложению из диалога "Открыть с помощью"
От: pilgrim_ Россия  
Дата: 09.09.21 13:23
Оценка: +3
Здравствуйте, Carc, Вы писали:

C>Суть задачи, дождаться в фоновом потоке завершения выбранного пользователем приложения, и соответственно, что-то там проверить на предмет изменений приложению файлу (lpszFileName).


Имхо даже получив PID запущенного процесса такой подход не универсален, напр. в случае MDI редакторов (Notepad++, VS), редакторов использующих один запущенный процесс на все открываемые файлы (напр. Word). В случае notepad++, если он уже был запущен, свежезапущенный с пом Open With процесс передаёт путь к открываемому файлу уже запущенному процессу, и завершается. Уже запущенная Visual Studio/Word получает путь к файлу через COM (или DDE, хз), т.е. новый devenv/winword не запускается.
И даже если выбранный в Open With такой редактор не был запущен ранее, пользователь может просто закрыть в нём сам файл, не закрывая сам редактор.

Более универсальный способ это отслеживать изменения самого файла (так делает notepad++), но тоже имеет недостатки, в случае если редактор монопольно держит открытый файл, а пользователь сохраняет в нём изменения.
Re[7]: Узнать путь к приложению из диалога "Открыть с помощь
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 09.09.21 13:34
Оценка:
Здравствуйте, Carc, Вы писали:

C>Тут всё предельно четко: мой код будет вызываться из моего же процесса (моим же кодом).


Это для Вас четко, поскольку это Ваша идея. А я, например, до сих пор толком не понял, какой процесс какие действия будет делать, чего ждать и что анализировать.

ЕМ>> А SHOpenWithDialog — это просто способ дернуть стандартную функцию


C>А нахрена тогда она — функция SHOpenWithDialog — нужна?


Судя по тому, что ввели ее в висте, и за прошедшие пятнадцать лет на моей памяти таких проблем еще не возникало, некоторый смысл в ней все-таки есть.

Смысл этой функции в том, чтобы попросить систему открыть файл, дав пользователю возможность выбора, чем его открывать. Запуск приложения в этой схеме — дело сугубо вторичное, вспомогательное. То есть, Вы хотите странного. В такой ситуации вряд ли стоит удивляться, что система не предлагает готовых и удобных API.
Re[7]: Узнать путь к приложению из диалога "Открыть с помощь
От: удусекшл  
Дата: 09.09.21 13:48
Оценка:
Здравствуйте, Carc, Вы писали:

C>Именно это меня и интересует. ShellExecute(EX) может мне вернуть HANDLE процесса, который она запустит. Но только без окна выбора OpenWith. А именно оно мне и нужно.


Хукни CreateProcess. Вряд ли SH* функция дергает напрямую родное NTёвое zw* API
Re[6]: Узнать путь к приложению из диалога "Открыть с помощью"
От: Carc Россия https://vk.com/gosha_mazov
Дата: 09.09.21 14:56
Оценка:
Здравствуйте, pilgrim_, Вы писали:

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


C>>Суть задачи, дождаться в фоновом потоке завершения выбранного пользователем приложения, и соответственно, что-то там проверить на предмет изменений приложению файлу (lpszFileName).


[skipped]

_>Более универсальный способ это отслеживать изменения самого файла (так делает notepad++), но тоже имеет недостатки, в случае если редактор монопольно держит открытый файл, а пользователь сохраняет в нём изменения.

Это то все понятно… Как так сделать я знаю, да и делал ни по разу уже. Но не в этом моем текущем конкретном случае.

В моем случае всё это лишнее. Мне не нужно контролировать изменения постоянно, и актуально получать все изменения прям вот сразу тоже не нужно.

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

ЗЫ: ну за мысли все равно спасибо!
Aml Pages Home
Re[7]: Узнать путь к приложению из диалога "Открыть с помощью"
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 09.09.21 15:04
Оценка: 1 (1)
Здравствуйте, Carc, Вы писали:

C>Достаточно знать, кто открыл такой файл


При нынешних тенденциях плодить прокси-процессы, информация о первичном запущенном приложении Вам мало что даст. Будет работать в общем случае, но исключения со временем будут множиться.
Re[8]: Узнать путь к приложению из диалога "Открыть с помощь
От: Carc Россия https://vk.com/gosha_mazov
Дата: 09.09.21 15:09
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, Carc, Вы писали:


C>>Тут всё предельно четко: мой код будет вызываться из моего же процесса (моим же кодом).


ЕМ>Это для Вас четко, поскольку это Ваша идея. А я, например, до сих пор толком не понял, какой процесс какие действия будет делать, чего ждать и что анализировать.

Дык я ж вроде написал: кто, что, зачем и когда? Что запускается, кем, когда и что мне нужно…

Что непонятного?
Про анализ я ни слова, кстати, не писал. Это за рамками вопроса.

ЕМ>>> А SHOpenWithDialog — это просто способ дернуть стандартную функцию


C>>А нахрена тогда она — функция SHOpenWithDialog — нужна?


ЕМ>Судя по тому, что ввели ее в висте, и за прошедшие пятнадцать лет на моей памяти таких проблем еще не возникало, некоторый смысл в ней все-таки есть.

Удивительное наблюдение, Ваш КО.
Ну видимо, какой-то смысл есть… Но какой?

ЕМ>Смысл этой функции в том, чтобы попросить систему открыть файл, дав пользователю возможность выбора, чем его открывать. Запуск приложения в этой схеме — дело сугубо вторичное, вспомогательное. То есть, Вы хотите странного. В такой ситуации вряд ли стоит удивляться, что система не предлагает готовых и удобных API.


Странное наблюдение. Странное, если не сказать больше! ©

Нафига нужна функция, которая показывает диалог OpenWith, но не отдает в результатах, что именно выбрал пользователь?
Все равно, что OpenFileDialog звать, который будет отвечать: TRUE\FALSE (выбрали файл и нажали ОК, или отменили выбор файла), но не отвечать что именно пользователь выбрал.

Тут у историков не два, а только один вопрос: «нах*ра?»

PS: в оригинале у историков было два вопроса: "«как и нах*ра?»", но в данном случае вопрос только один. Потому как ответ на первый вопрос ("как?") тут попросту очевиден
Aml Pages Home
Отредактировано 09.09.2021 15:11 Carc . Предыдущая версия .
Re[8]: Узнать путь к приложению из диалога "Открыть с помощь
От: Carc Россия https://vk.com/gosha_mazov
Дата: 09.09.21 15:40
Оценка:
Здравствуйте, удусекшл, Вы писали:

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


C>>Именно это меня и интересует. ShellExecute(EX) может мне вернуть HANDLE процесса, который она запустит. Но только без окна выбора OpenWith. А именно оно мне и нужно.


У>Хукни CreateProcess. Вряд ли SH* функция дергает напрямую родное NTёвое zw* API


Та не парни. Вы меня не поняли, не прочувствоали что ли…

Как сие отловить я знаю. Можно просечь появление нового процесса, вариантов туча — это не проблема.
Но! Хоцца другого… Показать стандартный диалог OpenWith и как-то узнать, какое приложение выбрал пользователь…

Что мне важно
1) Диалог должен быть стандартным от винды. Т.к. диалог должен быть привычным для пользователя…
Свои поделки я и так накручу. Вариантов у меня есть. Там работы на полчаса клиентского кода в конечном проекте, и еще часок максимум на ревью тире доводку. Тут вариантов кучи.

2) Очень не хочется прикручивать хуки, и прочия.
Причин этому несколько
  • Во первых задача в конкретном в этом вот проекте даже не третье-, а четвертостепенная.
  • Все эти хуки, даже и полулегальные очень не нравятся анвирям. Уж про вирусТотал вообще молчу.

    История, леденящая дущу: (из этого самого, моего конкретного проекта, где мне всё это понадобилось.
    А именно: приложение пасет клавиатуарный ввод. Причем делает это легально, стандартным хуком, причем только в рамках своего процесса.

    Казалось бы, ну что такого то? Чего "нихарошего"? (© к\ф Покровские ворота)
    Пасу свой ввод, только в рамках моего же процесса. Пасу легально, никаких хаков.

    Результат: пара-тройка антивирей на VirusTotal визжат до усёру просто.
    "Поймал, поймал. Вирус"! Кейлогггер"

    Одно слово, придурки блин! Ну чего с индусни взять.

    PS: а нужен этот клавиатурный пасёк для нетривиальных горячих клавиш в приложении. Вот попробуйте вы отловить какое-нить банальное двойное, быстрое нажатие Ctrl+Ctrl. Безо всяких там дополнительных клавиш-букоф-циферь и прочия. Хрен вам!
    Тут не RegisterHotkey не помогёт (а он и вовсе тут ни к селу, не нах не нужно глобально ставить обработку), Ни аксели обрабатывать — тоже придется мутный код тогда писать. Написать не проблема, но как его потом поддерживать и развивать!?! Это ж полный «ЛП» и «Ёпырш» будет, истинно вангую

    А причем все эти двойные нажатия обрабатывать централизовано, а не в каждую оконную процедуру внутри своего адресного пространства лазить и вылезать без конца.

    PPS: некоторым чудаковатым подделкам в VT всё это не нравится. А вот пользователям моим даже наоборот, кто попробовал — все в восторге просто.

  • Aml Pages Home
    Re[8]: Узнать путь к приложению из диалога "Открыть с помощью"
    От: Carc Россия https://vk.com/gosha_mazov
    Дата: 09.09.21 15:53
    Оценка:
    Здравствуйте, Евгений Музыченко, Вы писали:

    ЕМ>Здравствуйте, Carc, Вы писали:


    C>>Достаточно знать, кто открыл такой файл


    ЕМ>При нынешних тенденциях плодить прокси-процессы, информация о первичном запущенном приложении Вам мало что даст. Будет работать в общем случае, но исключения со временем будут множиться.


    Это то я распрекрасно понимаю…

    Но в моем случае все-таки исключения скорее будут настолько редки, что можно и положить на них болт. Причем исключения в смысле пользовательских сценариев, как именно делает и что хочет получить пользователь. Если пользователь "годнЫй" (свой, любимый, платящий — нужное подчеркнуть), то в таком конкретном случае я могу и кастомизнуть код под конкретный случай. Такое уж доводилось делать
    (хитроопый парсинг некоторых гиперссылок понадобился, для одного старинного, можно сказать "любимого" пользователя).

    Ну вот на досуге и поковырялся в стиле как невинность соблюсти, и капитал приобрести… То бишь как и общую архитектуру не ломать, и конкретный случай кастомизнуть, но так чтобы он вписывался уже как расширение архитектуры. В общем задачка была непростая, а значь и интересная… Хоть и третьеразрядная по приоритетам.
    Aml Pages Home
    Re[9]: Узнать путь к приложению из диалога "Открыть с помощь
    От: Евгений Музыченко Франция https://software.muzychenko.net/ru
    Дата: 09.09.21 20:17
    Оценка: -1
    Здравствуйте, Carc, Вы писали:

    C>Что непонятного?


    Непонятно было, сами Вы вызываете SHOpenWithDialog, ShellExecute и прочее, или их будет вызывать какой-нибудь другой код, а Вам надо за этим следить сбоку.

    C>Про анализ я ни слова, кстати, не писал.


    Разбор результата выполнения операции — это и есть анализ.

    C>Ну видимо, какой-то смысл есть… Но какой?


    Открывать файл. Нет?

    C>Нафига нужна функция, которая показывает диалог OpenWith, но не отдает в результатах, что именно выбрал пользователь?


    Еще раз: ее задача не в этом, а в том, чтобы пользователь мог это сделать. В системе есть и другие функции, задача которых — просто активировать определенную системную возможность, без отчета вызывающему коду о подробностях выполнения.

    C>Все равно, что OpenFileDialog звать, который будет отвечать: TRUE\FALSE (выбрали файл и нажали ОК, или отменили выбор файла), но не отвечать что именно пользователь выбрал.


    Задача OpenFileDialog именно в том, чтобы получить сведения о выборе пользователя. Ничего другого эта функция не делает.

    C>Тут у историков не два, а только один вопрос: «нах*ра?»


    Вряд ли здесь имеет смысл обобщать — у других я такого вопроса не встречал.
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.