Суть проблемы: на Windows Server 2008 R2 нужно открывать картинки из используемой программы.
Делается это так:
var fileName = @"C:\Users\Admin\Desktop\TEST.JPG";
Process.Start(fileName);
Выполнение этого кода приводит к ошибке:
т.к. на сервере не установлен пакет User Experience.
Решил посмотреть какие shell verb`ы вообще заданы для объекта jpegfile:
Возникает вопрос: почему при программном вызове (Process.Start()) вылезает ошибка, а при открытии файла по double click`у в explorer`e нужный файл открывается в MS Paint.
Какой verb срабатывает на событии double click? Сориентируйте, пожалуйста, в какую сторону копать?
Re: Какой verb вызывается в windows explorer`e по двойному клику?
Здравствуйте, Gepard_vvk, Вы писали:
G_>Суть проблемы: на Windows Server 2008 R2 нужно открывать картинки из используемой программы. G_>Делается это так:
G_>
G_>Выполнение этого кода приводит к ошибке: G_>
G_>т.к. на сервере не установлен пакет User Experience. G_>Решил посмотреть какие shell verb`ы вообще заданы для объекта jpegfile: G_>
G_>Возникает вопрос: почему при программном вызове (Process.Start()) вылезает ошибка, а при открытии файла по double click`у в explorer`e нужный файл открывается в MS Paint. G_>Какой verb срабатывает на событии double click? Сориентируйте, пожалуйста, в какую сторону копать?
Здравствуйте, saf_e, Вы писали:
_>Здравствуйте, Gepard_vvk, Вы писали:
G_>>Суть проблемы: на Windows Server 2008 R2 нужно открывать картинки из используемой программы. G_>>Делается это так:
G_>>
G_>>Выполнение этого кода приводит к ошибке: G_>>
G_>>т.к. на сервере не установлен пакет User Experience. G_>>Решил посмотреть какие shell verb`ы вообще заданы для объекта jpegfile: G_>>
G_>>Возникает вопрос: почему при программном вызове (Process.Start()) вылезает ошибка, а при открытии файла по double click`у в explorer`e нужный файл открывается в MS Paint. G_>>Какой verb срабатывает на событии double click? Сориентируйте, пожалуйста, в какую сторону копать?
_>Вам нужна семантика ShellExecute, смотрите здесь: http://stackoverflow.com/questions/258416/shellexecute-equivalent-in-net
Возможно я не очень внятно сформулировал вопрос, но причем тут семантика ShellExecute?
В документации очень четко описано поведение ShellExecute — в зависимости от заданного verb`a читается определенный ключ реестра. Если Verb не задан, то по умолчанию выбирается "open", если таковой имеется, либо первый из имеющихся в противном случае. В данном примере явно видно, что определен только "printto". Это объясняет почему приложение пытается открыть изображение при помощи Windows Photo Viewer, но не объясняет механизм открытия файла из эксплорера по дабл клику.
Именно это меня и интересует: почему по double click открывается ассоциация image->OpenWith, а не jpegfile->shell->printto?
Re[3]: Какой verb вызывается в windows explorer`e по двойному клику?
Здравствуйте, Gepard_vvk, Вы писали:
G_>Возможно я не очень внятно сформулировал вопрос, но причем тут семантика ShellExecute? G_>В документации очень четко описано поведение ShellExecute — в зависимости от заданного verb`a читается определенный ключ реестра. Если Verb не задан, то по умолчанию выбирается "open", если таковой имеется, либо первый из имеющихся в противном случае. В данном примере явно видно, что определен только "printto". Это объясняет почему приложение пытается открыть изображение при помощи Windows Photo Viewer, но не объясняет механизм открытия файла из эксплорера по дабл клику. G_>Именно это меня и интересует: почему по double click открывается ассоциация image->OpenWith, а не jpegfile->shell->printto?
Ок, согласен ответил не на тот вопрос.
Вопрос встречный, как давно у вас для jpegfile нет open, как я понимаю был удален вручную?
Re: Какой verb вызывается в windows explorer`e по двойному клику?
У эксплорера есть свой секретный ключий от счастья: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts
А в восьмерке видимо все старые разработчики, знавшие про него ушли и новые придумали еще чтото, но деталей я не знаю.
Как много веселых ребят, и все делают велосипед...
Re[3]: Какой verb вызывается в windows explorer`e по двойному клику?
Здравствуйте, saf_e, Вы писали:
_>Здравствуйте, Gepard_vvk, Вы писали:
G_>>Возможно я не очень внятно сформулировал вопрос, но причем тут семантика ShellExecute? G_>>В документации очень четко описано поведение ShellExecute — в зависимости от заданного verb`a читается определенный ключ реестра. Если Verb не задан, то по умолчанию выбирается "open", если таковой имеется, либо первый из имеющихся в противном случае. В данном примере явно видно, что определен только "printto". Это объясняет почему приложение пытается открыть изображение при помощи Windows Photo Viewer, но не объясняет механизм открытия файла из эксплорера по дабл клику. G_>>Именно это меня и интересует: почему по double click открывается ассоциация image->OpenWith, а не jpegfile->shell->printto?
_>Ок, согласен ответил не на тот вопрос.
_>Вопрос встречный, как давно у вас для jpegfile нет open, как я понимаю был удален вручную?
Да нет, это на чистой системе без установленного пакета User Experience.
Re[4]: Какой verb вызывается в windows explorer`e по двойному клику?
Здравствуйте, Aniskin, Вы писали:
A>Здравствуйте, Gepard_vvk, Вы писали:
G_>>почему по double click открывается ассоциация image->OpenWith, а не jpegfile->shell->printto?
A>Что прописано в HKEY_CLASSES_ROOT\SystemFileAssociations\.jpg ?
А можно как-то программно заставить вызывать именно эту ассоциацию, не залезая при этом в реестр? Ну т.е. явно попросить эксплорер открыть этот файл?
Re[4]: Какой verb вызывается в windows explorer`e по двойному клику?
Здравствуйте, Aniskin, Вы писали:
A>Здравствуйте, Gepard_vvk, Вы писали:
G_>>почему по double click открывается ассоциация image->OpenWith, а не jpegfile->shell->printto?
A>Что прописано в HKEY_CLASSES_ROOT\SystemFileAssociations\.jpg ?
А вот что:
Re[5]: Какой verb вызывается в windows explorer`e по двойному клику?
Здравствуйте, Gepard_vvk, Вы писали:
G_>А можно как-то программно заставить вызывать именно эту ассоциацию, не залезая при этом в реестр? Ну т.е. явно попросить эксплорер открыть этот файл?
Получить IContextMenu для файла (напримемр SHParseDisplayName + SHGetDesktopFolder + IShellFolder::GetUIObjectOf(..IID_IContextMenu))
Вызвать IContextMenu::QueryContextMenu с флагом CMF_DEFAULTONLY (внимательнее с возвращаемым HRESULT)
Вызвать IContextMenu::InvokeCommand для первой команды (иногда их там бывает несколько, но первая — всегда default)
Именно так в проводнике реализовано "открытие" файла по double click'у — это просто инициирование действия 'по умолчанию' (визуально оно выделено в контекстном меню).
А вот как будет выглядеть сама операция открытия — зависит от реализации IContextMenu... Другой похожий вариант — IExplorerCommand, но он может не работать со сторонними NSE
И еще — дефолтная реализация IContextMenu::QueryContextMenu умеет загружать context menu shell extensions, которые теоритически могут изменить обычное поведение.
Re[6]: Какой verb вызывается в windows explorer`e по двойному клику?
Здравствуйте, Aniskin, Вы писали:
A>Здравствуйте, Gepard_vvk, Вы писали:
A>>>Что прописано в HKEY_CLASSES_ROOT\SystemFileAssociations\.jpg ? G_>>А вот что:
A>Я имел в виду, есть ли там ветка OpenWithProgID или OpenWithList или shell с командами?
Есть только shell с подключем setdesktopwallpaper.
Re[7]: Какой verb вызывается в windows explorer`e по двойному клику?
Здравствуйте, Gepard_vvk, Вы писали:
A>>>>Что прописано в HKEY_CLASSES_ROOT\SystemFileAssociations\.jpg ? G_>>>А вот что:
A>>Я имел в виду, есть ли там ветка OpenWithProgID или OpenWithList или shell с командами? G_>Есть только shell с подключем setdesktopwallpaper.
Тогда остается смотреть описанный в соседней ветке ключ HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.jpg\UserChoice и прописанное там значение ProgID.
Re: Какой verb вызывается в windows explorer`e по двойному клику?
От:
Аноним
Дата:
02.06.13 06:41
Оценка:
Здравствуйте, Gepard_vvk, Вы писали:
... G_>Какой verb срабатывает на событии double click? Сориентируйте, пожалуйста, в какую сторону копать?
Т.к. у вас кроме printto ничего нет выполняется он.
Добавь в shell open и будет отквывать нормально.
Re[6]: Какой verb вызывается в windows explorer`e по двойному клику?
Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>Здравствуйте, Gepard_vvk, Вы писали:
G_>>А можно как-то программно заставить вызывать именно эту ассоциацию, не залезая при этом в реестр? Ну т.е. явно попросить эксплорер открыть этот файл?
ЮЖ>Получить IContextMenu для файла (напримемр SHParseDisplayName + SHGetDesktopFolder + IShellFolder::GetUIObjectOf(..IID_IContextMenu)) ЮЖ>Вызвать IContextMenu::QueryContextMenu с флагом CMF_DEFAULTONLY (внимательнее с возвращаемым HRESULT) ЮЖ>Вызвать IContextMenu::InvokeCommand для первой команды (иногда их там бывает несколько, но первая — всегда default)
ЮЖ>Именно так в проводнике реализовано "открытие" файла по double click'у — это просто инициирование действия 'по умолчанию' (визуально оно выделено в контекстном меню). ЮЖ>А вот как будет выглядеть сама операция открытия — зависит от реализации IContextMenu... Другой похожий вариант — IExplorerCommand, но он может не работать со сторонними NSE
ЮЖ>И еще — дефолтная реализация IContextMenu::QueryContextMenu умеет загружать context menu shell extensions, которые теоритически могут изменить обычное поведение.
Нашел еще более простое решение:
using System.Runtime.InteropServices;
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SHELLEXECUTEINFO
{
public int cbSize;
public uint fMask;
public IntPtr hwnd;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpVerb;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpFile;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpParameters;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpDirectory;
public int nShow;
public IntPtr hInstApp;
public IntPtr lpIDList;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpClass;
public IntPtr hkeyClass;
public uint dwHotKey;
public IntPtr hIcon;
public IntPtr hProcess;
}
private const int SW_SHOW = 5;
private const uint SEE_MASK_INVOKEIDLIST = 12;
public static bool ShowFileProperties(string Filename)
{
SHELLEXECUTEINFO info = new SHELLEXECUTEINFO();
info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(info);
info.lpFile = Filename;
info.nShow = SW_SHOW;
info.fMask = SEE_MASK_INVOKEIDLIST;
return ShellExecuteEx(ref info);
}
// button clickprivate void button1_Click(object sender, EventArgs e)
{
string path = @"C:\Users\test\Documents\test.text";
ShowFileProperties(path);
}
Этот код откроет файл приложением, которое определено как приложение по умолчанию в контекстом меню.
Т.е. вместо огромной имплементации тех функций, что Вы указали, можно просто вызывать ShellEx со специально сформированной структурой SHELLEXECUTEINFO.
Вся соль в