Здравствуйте, Carc, Вы писали:
C>Как узнать путь к приложению из диалога "Открыть с помощью"
Наверное, только отслеживать создание новых процессов с помощью какого-то хука.
Вот такой громоздкий пример удалось найти для юзер мода:
C>Т.е. получить путь к приложению, которое пользователь выбрал для файла в диалоге "Открыть с помощью"?
Зная id процесса можно получить полный путь к exe через QueryFullProcessImageName.
Только для этого у вызывающего потока должна быть выставлена привилегия SE_DEBUG_NAME (OpenThreadToken + AdjustTokenPrivileges).
Re[2]: Узнать путь к приложению из диалога "Открыть с помощью"
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Carc, Вы писали:
C>>как узнать чем именно был открыт файл, какое приложение выбрал пользователь
ЕМ>Что значит "как узнать"? Кто именно будет узнавать, и в какой момент?
Узнать должен вызывающий код.
Здравствуйте, qaz77, Вы писали:
Q>Здравствуйте, Carc, Вы писали:
C>>Как узнать путь к приложению из диалога "Открыть с помощью" Q>Наверное, только отслеживать создание новых процессов с помощью какого-то хука.
Вот этого то как раз и не хотелось… Хуки, привилегии… Q>Вот такой громоздкий пример удалось найти для юзер мода: Q>
Здравствуйте, Carc, Вы писали:
C>>>как узнать чем именно был открыт файл, какое приложение выбрал пользователь ЕМ>>Что значит "как узнать"? Кто именно будет узнавать, и в какой момент?
C>Узнать должен вызывающий код.
Откуда этот код будет вызываться, в какое время, в каких условиях?
Re[4]: Узнать путь к приложению из диалога "Открыть с помощью"
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Carc, Вы писали:
C>>>>как узнать чем именно был открыт файл, какое приложение выбрал пользователь ЕМ>>>Что значит "как узнать"? Кто именно будет узнавать, и в какой момент?
C>>Узнать должен вызывающий код.
ЕМ>Откуда этот код будет вызываться, в какое время, в каких условиях?
User mode, по команде пользователя (кнопка, команда меню).
1) Тут как вариант или же SHOpenWithDialog, но эта функция не вернет ни выбранного приложения, ни пути к нему.
2) Или же старый вариант, через ShellExecuteEx ('rundll32.exe'), TEXT("shell32.dll,OpenAs_RunDLL " + lpszFileName.
Но это тоже не годится.
В этом варианте вернется в структуре SHELLEXECUTEEX хендл процесса именно что самого rundll32.exe. А он мне нафиг не нужен.
Суть задачи, дождаться в фоновом потоке завершения выбранного пользователем приложения, и соответственно, что-то там проверить на предмет изменений приложению файлу (lpszFileName).
Здравствуйте, Carc, Вы писали:
ЕМ>>Откуда этот код будет вызываться, в какое время, в каких условиях? C>User mode, по команде пользователя (кнопка, команда меню). C>дождаться в фоновом потоке завершения выбранного пользователем приложения
Все равно непонятно. Это Ваш код будет вызывать SHOpenWithDialog? Или Ваш код будет просто работать в совершенно левом процессе, и как-то мониторить такие события?
В любом случае, без хаков/хуков тут не обойтись, и это нормально. Система возвращает информацию о приложении, когда Вы запускаете его непосредственно, через CreateProcess или ShellExecute. А SHOpenWithDialog — это просто способ дернуть стандартную функцию из своего кода, она вообще может выполняться в контексте Explorer'а, и не предполагает подробного отчета о результате.
Re[5]: Узнать путь к приложению из диалога "Открыть с помощью"
Здравствуйте, Carc, Вы писали:
C>Суть задачи, дождаться в фоновом потоке завершения выбранного пользователем приложения, и соответственно, что-то там проверить на предмет изменений приложению файлу (lpszFileName).
Дык может сделать свой диалог "Open with..."? Информация о зарегистрированных в системе расширениях доступна.
Все данные оказываются под контролем — запускай что хочешь, проверяй как хочешь.
_____________________
С уважением,
Stanislav V. Zudin
Re[6]: Узнать путь к приложению из диалога "Открыть с помощь
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Carc, Вы писали:
ЕМ>>>Откуда этот код будет вызываться, в какое время, в каких условиях? C>>User mode, по команде пользователя (кнопка, команда меню). C>>дождаться в фоновом потоке завершения выбранного пользователем приложения
ЕМ>Все равно непонятно. Это Ваш код будет вызывать SHOpenWithDialog? Или Ваш код будет просто работать в совершенно левом процессе, и как-то мониторить такие события?
Нет. Тут всё предельно четко: мой код будет вызываться из моего же процесса (моим же кодом).
ЕМ>В любом случае, без хаков/хуков тут не обойтись, и это нормально. Система возвращает информацию о приложении, когда Вы запускаете его непосредственно, через CreateProcess или ShellExecute.
Именно это меня и интересует. ShellExecute(EX) может мне вернуть HANDLE процесса, который она запустит. Но только без окна выбора OpenWith. А именно оно мне и нужно.
ЕМ> А SHOpenWithDialog — это просто способ дернуть стандартную функцию из своего кода, она вообще может выполняться в контексте Explorer'а, и не предполагает подробного отчета о результате.
А нахрена тогда она — функция SHOpenWithDialog — нужна?
Если убрать флаг OAIF_EXEC, то SHOpenWithDialog ничего не запустит, даже в случае выбора приложения пользователем + кнопка ОК. Но и путь к выбранному приложению, тоже не вернет. На кой тогда оно надо?
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>Здравствуйте, Carc, Вы писали:
C>>Суть задачи, дождаться в фоновом потоке завершения выбранного пользователем приложения, и соответственно, что-то там проверить на предмет изменений приложению файлу (lpszFileName).
SVZ>Дык может сделать свой диалог "Open with..."?
Ну теоретически то я могу… Только юзабилити такого диалога будет ещё то.
а) не привычно пользователю
б) ограниченный UI
C>> Информация о зарегистрированных в системе расширениях доступна.
Я так понимаю, речь идет о QueryAssocString что ли? Так?
SVZ>Все данные оказываются под контролем — запускай что хочешь, проверяй как хочешь.
Ну дык такой вариант у меня есть, и кодить там немного… Но все таки хотелось бы именно, что достучаться до стандартного диалога OpenWith с возможностью получить путь к выбранному пользователем приложению…
Ибо в стандартном диалоге больше возможностей, выглядит привычно, выглядит наглядно (иконки приложений и все такое). В моем варианте диалога так не получится (хотя бы те же иконки приложений, хрен я их там нарисую).
Здравствуйте, Carc, Вы писали:
C>Суть задачи, дождаться в фоновом потоке завершения выбранного пользователем приложения, и соответственно, что-то там проверить на предмет изменений приложению файлу (lpszFileName).
Имхо даже получив PID запущенного процесса такой подход не универсален, напр. в случае MDI редакторов (Notepad++, VS), редакторов использующих один запущенный процесс на все открываемые файлы (напр. Word). В случае notepad++, если он уже был запущен, свежезапущенный с пом Open With процесс передаёт путь к открываемому файлу уже запущенному процессу, и завершается. Уже запущенная Visual Studio/Word получает путь к файлу через COM (или DDE, хз), т.е. новый devenv/winword не запускается.
И даже если выбранный в Open With такой редактор не был запущен ранее, пользователь может просто закрыть в нём сам файл, не закрывая сам редактор.
Более универсальный способ это отслеживать изменения самого файла (так делает notepad++), но тоже имеет недостатки, в случае если редактор монопольно держит открытый файл, а пользователь сохраняет в нём изменения.
Re[7]: Узнать путь к приложению из диалога "Открыть с помощь
Здравствуйте, Carc, Вы писали:
C>Тут всё предельно четко: мой код будет вызываться из моего же процесса (моим же кодом).
Это для Вас четко, поскольку это Ваша идея. А я, например, до сих пор толком не понял, какой процесс какие действия будет делать, чего ждать и что анализировать.
ЕМ>> А SHOpenWithDialog — это просто способ дернуть стандартную функцию
C>А нахрена тогда она — функция SHOpenWithDialog — нужна?
Судя по тому, что ввели ее в висте, и за прошедшие пятнадцать лет на моей памяти таких проблем еще не возникало, некоторый смысл в ней все-таки есть.
Смысл этой функции в том, чтобы попросить систему открыть файл, дав пользователю возможность выбора, чем его открывать. Запуск приложения в этой схеме — дело сугубо вторичное, вспомогательное. То есть, Вы хотите странного. В такой ситуации вряд ли стоит удивляться, что система не предлагает готовых и удобных API.
Re[7]: Узнать путь к приложению из диалога "Открыть с помощь
Здравствуйте, Carc, Вы писали:
C>Именно это меня и интересует. ShellExecute(EX) может мне вернуть HANDLE процесса, который она запустит. Но только без окна выбора OpenWith. А именно оно мне и нужно.
Хукни CreateProcess. Вряд ли SH* функция дергает напрямую родное NTёвое zw* API
Re[6]: Узнать путь к приложению из диалога "Открыть с помощью"
Здравствуйте, pilgrim_, Вы писали:
_>Здравствуйте, Carc, Вы писали:
C>>Суть задачи, дождаться в фоновом потоке завершения выбранного пользователем приложения, и соответственно, что-то там проверить на предмет изменений приложению файлу (lpszFileName).
[skipped]
_>Более универсальный способ это отслеживать изменения самого файла (так делает notepad++), но тоже имеет недостатки, в случае если редактор монопольно держит открытый файл, а пользователь сохраняет в нём изменения.
Это то все понятно… Как так сделать я знаю, да и делал ни по разу уже. Но не в этом моем текущем конкретном случае.
В моем случае всё это лишнее. Мне не нужно контролировать изменения постоянно, и актуально получать все изменения прям вот сразу тоже не нужно.
Достаточно знать, кто открыл такой файл, и что-то предпринять, когда это приложение завершится (актуализировать изменения, удалить временный файл и.т.д.).
Здравствуйте, Carc, Вы писали:
C>Достаточно знать, кто открыл такой файл
При нынешних тенденциях плодить прокси-процессы, информация о первичном запущенном приложении Вам мало что даст. Будет работать в общем случае, но исключения со временем будут множиться.
Re[8]: Узнать путь к приложению из диалога "Открыть с помощь
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Carc, Вы писали:
C>>Тут всё предельно четко: мой код будет вызываться из моего же процесса (моим же кодом).
ЕМ>Это для Вас четко, поскольку это Ваша идея. А я, например, до сих пор толком не понял, какой процесс какие действия будет делать, чего ждать и что анализировать.
Дык я ж вроде написал: кто, что, зачем и когда? Что запускается, кем, когда и что мне нужно…
Что непонятного?
Про анализ я ни слова, кстати, не писал. Это за рамками вопроса.
ЕМ>>> А SHOpenWithDialog — это просто способ дернуть стандартную функцию
C>>А нахрена тогда она — функция SHOpenWithDialog — нужна?
ЕМ>Судя по тому, что ввели ее в висте, и за прошедшие пятнадцать лет на моей памяти таких проблем еще не возникало, некоторый смысл в ней все-таки есть.
Удивительное наблюдение, Ваш КО.
Ну видимо, какой-то смысл есть… Но какой?
ЕМ>Смысл этой функции в том, чтобы попросить систему открыть файл, дав пользователю возможность выбора, чем его открывать. Запуск приложения в этой схеме — дело сугубо вторичное, вспомогательное. То есть, Вы хотите странного. В такой ситуации вряд ли стоит удивляться, что система не предлагает готовых и удобных API.
Нафига нужна функция, которая показывает диалог OpenWith, но не отдает в результатах, что именно выбрал пользователь?
Все равно, что OpenFileDialog звать, который будет отвечать: TRUE\FALSE (выбрали файл и нажали ОК, или отменили выбор файла), но не отвечать что именно пользователь выбрал.
Тут у историков не два, а только один вопрос: «нах*ра?»
PS: в оригинале у историков было два вопроса: "«как и нах*ра?»", но в данном случае вопрос только один. Потому как ответ на первый вопрос ("как?") тут попросту очевиден
Здравствуйте, удусекшл, Вы писали:
У>Здравствуйте, Carc, Вы писали:
C>>Именно это меня и интересует. ShellExecute(EX) может мне вернуть HANDLE процесса, который она запустит. Но только без окна выбора OpenWith. А именно оно мне и нужно.
У>Хукни CreateProcess. Вряд ли SH* функция дергает напрямую родное NTёвое zw* API
Та не парни. Вы меня не поняли, не прочувствоали что ли…
Как сие отловить я знаю. Можно просечь появление нового процесса, вариантов туча — это не проблема.
Но! Хоцца другого… Показать стандартный диалог OpenWith и как-то узнать, какое приложение выбрал пользователь…
Что мне важно 1) Диалог должен быть стандартным от винды. Т.к. диалог должен быть привычным для пользователя…
Свои поделки я и так накручу. Вариантов у меня есть. Там работы на полчаса клиентского кода в конечном проекте, и еще часок максимум на ревью тире доводку. Тут вариантов кучи.
2) Очень не хочется прикручивать хуки, и прочия.
Причин этому несколько
Во первых задача в конкретном в этом вот проекте даже не третье-, а четвертостепенная.
Все эти хуки, даже и полулегальные очень не нравятся анвирям. Уж про вирусТотал вообще молчу.
История, леденящая дущу: (из этого самого, моего конкретного проекта, где мне всё это понадобилось.
А именно: приложение пасет клавиатуарный ввод. Причем делает это легально, стандартным хуком, причем только в рамках своего процесса.
Результат: пара-тройка антивирей на VirusTotal визжат до усёру просто.
"Поймал, поймал. Вирус"! Кейлогггер"
Одно слово, придурки блин! Ну чего с индусни взять.
PS: а нужен этот клавиатурный пасёк для нетривиальных горячих клавиш в приложении. Вот попробуйте вы отловить какое-нить банальное двойное, быстрое нажатие Ctrl+Ctrl. Безо всяких там дополнительных клавиш-букоф-циферь и прочия. Хрен вам!
Тут не RegisterHotkey не помогёт (а он и вовсе тут ни к селу, не нах не нужно глобально ставить обработку), Ни аксели обрабатывать — тоже придется мутный код тогда писать. Написать не проблема, но как его потом поддерживать и развивать!?! Это ж полный «ЛП» и «Ёпырш» будет, истинно вангую
А причем все эти двойные нажатия обрабатывать централизовано, а не в каждую оконную процедуру внутри своего адресного пространства лазить и вылезать без конца.
PPS: некоторым чудаковатым подделкам в VT всё это не нравится. А вот пользователям моим даже наоборот, кто попробовал — все в восторге просто.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Carc, Вы писали:
C>>Достаточно знать, кто открыл такой файл
ЕМ>При нынешних тенденциях плодить прокси-процессы, информация о первичном запущенном приложении Вам мало что даст. Будет работать в общем случае, но исключения со временем будут множиться.
Это то я распрекрасно понимаю…
Но в моем случае все-таки исключения скорее будут настолько редки, что можно и положить на них болт. Причем исключения в смысле пользовательских сценариев, как именно делает и что хочет получить пользователь. Если пользователь "годнЫй" (свой, любимый, платящий — нужное подчеркнуть), то в таком конкретном случае я могу и кастомизнуть код под конкретный случай. Такое уж доводилось делать
(хитроопый парсинг некоторых гиперссылок понадобился, для одного старинного, можно сказать "любимого" пользователя).
Ну вот на досуге и поковырялся в стиле как невинность соблюсти, и капитал приобрести… То бишь как и общую архитектуру не ломать, и конкретный случай кастомизнуть, но так чтобы он вписывался уже как расширение архитектуры. В общем задачка была непростая, а значь и интересная… Хоть и третьеразрядная по приоритетам.
Непонятно было, сами Вы вызываете SHOpenWithDialog, ShellExecute и прочее, или их будет вызывать какой-нибудь другой код, а Вам надо за этим следить сбоку.
C>Про анализ я ни слова, кстати, не писал.
Разбор результата выполнения операции — это и есть анализ.
C>Ну видимо, какой-то смысл есть… Но какой?
Открывать файл. Нет?
C>Нафига нужна функция, которая показывает диалог OpenWith, но не отдает в результатах, что именно выбрал пользователь?
Еще раз: ее задача не в этом, а в том, чтобы пользователь мог это сделать. В системе есть и другие функции, задача которых — просто активировать определенную системную возможность, без отчета вызывающему коду о подробностях выполнения.
C>Все равно, что OpenFileDialog звать, который будет отвечать: TRUE\FALSE (выбрали файл и нажали ОК, или отменили выбор файла), но не отвечать что именно пользователь выбрал.
Задача OpenFileDialog именно в том, чтобы получить сведения о выборе пользователя. Ничего другого эта функция не делает.
C>Тут у историков не два, а только один вопрос: «нах*ра?»
Вряд ли здесь имеет смысл обобщать — у других я такого вопроса не встречал.