Какой verb вызывается в windows explorer`e по двойному клику?
От: Gepard_vvk  
Дата: 30.05.13 11:42
Оценка:
Суть проблемы: на 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 по двойному клику?
От: saf_e  
Дата: 30.05.13 11:55
Оценка:
Здравствуйте, Gepard_vvk, Вы писали:

G_>Суть проблемы: на Windows Server 2008 R2 нужно открывать картинки из используемой программы.

G_>Делается это так:

G_>
G_>var fileName = @"C:\Users\Admin\Desktop\TEST.JPG";
G_>Process.Start(fileName);
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
Re[2]: Какой verb вызывается в windows explorer`e по двойному клику?
От: Gepard_vvk  
Дата: 30.05.13 12:36
Оценка:
Здравствуйте, saf_e, Вы писали:

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


G_>>Суть проблемы: на Windows Server 2008 R2 нужно открывать картинки из используемой программы.

G_>>Делается это так:

G_>>
G_>>var fileName = @"C:\Users\Admin\Desktop\TEST.JPG";
G_>>Process.Start(fileName);
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 по двойному клику?
От: saf_e  
Дата: 30.05.13 12:42
Оценка:
Здравствуйте, 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 по двойному клику?
От: ononim  
Дата: 30.05.13 12:48
Оценка:
У эксплорера есть свой секретный ключий от счастья: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts
А в восьмерке видимо все старые разработчики, знавшие про него ушли и новые придумали еще чтото, но деталей я не знаю.
Как много веселых ребят, и все делают велосипед...
Re[3]: Какой verb вызывается в windows explorer`e по двойному клику?
От: Aniskin  
Дата: 30.05.13 19:10
Оценка:
Здравствуйте, Gepard_vvk, Вы писали:

G_>почему по double click открывается ассоциация image->OpenWith, а не jpegfile->shell->printto?


Что прописано в HKEY_CLASSES_ROOT\SystemFileAssociations\.jpg ?
Re[4]: Какой verb вызывается в windows explorer`e по двойному клику?
От: Gepard_vvk  
Дата: 31.05.13 08:09
Оценка:
Здравствуйте, 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 по двойному клику?
От: Gepard_vvk  
Дата: 31.05.13 08:11
Оценка:
Здравствуйте, Aniskin, Вы писали:

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


G_>>почему по double click открывается ассоциация image->OpenWith, а не jpegfile->shell->printto?


A>Что прописано в HKEY_CLASSES_ROOT\SystemFileAssociations\.jpg ?

А можно как-то программно заставить вызывать именно эту ассоциацию, не залезая при этом в реестр? Ну т.е. явно попросить эксплорер открыть этот файл?
Re[4]: Какой verb вызывается в windows explorer`e по двойному клику?
От: Gepard_vvk  
Дата: 31.05.13 08:14
Оценка:
Здравствуйте, Aniskin, Вы писали:

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


G_>>почему по double click открывается ассоциация image->OpenWith, а не jpegfile->shell->printto?


A>Что прописано в HKEY_CLASSES_ROOT\SystemFileAssociations\.jpg ?

А вот что:
Re[5]: Какой verb вызывается в windows explorer`e по двойному клику?
От: Aniskin  
Дата: 31.05.13 09:22
Оценка:
Здравствуйте, Gepard_vvk, Вы писали:

A>>Что прописано в HKEY_CLASSES_ROOT\SystemFileAssociations\.jpg ?

G_>А вот что:

Я имел в виду, есть ли там ветка OpenWithProgID или OpenWithList или shell с командами?
Re[5]: Какой verb вызывается в windows explorer`e по двойному клику?
От: Юрий Жмеренецкий ICQ 380412032
Дата: 31.05.13 11:11
Оценка: 2 (1)
Здравствуйте, 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 по двойному клику?
От: Gepard_vvk  
Дата: 31.05.13 11:30
Оценка:
Здравствуйте, Aniskin, Вы писали:

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


A>>>Что прописано в HKEY_CLASSES_ROOT\SystemFileAssociations\.jpg ?

G_>>А вот что:

A>Я имел в виду, есть ли там ветка OpenWithProgID или OpenWithList или shell с командами?

Есть только shell с подключем setdesktopwallpaper.
Re[7]: Какой verb вызывается в windows explorer`e по двойному клику?
От: Aniskin  
Дата: 31.05.13 18:56
Оценка:
Здравствуйте, 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  
Дата: 05.06.13 11:53
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Здравствуйте, 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 click
private void button1_Click(object sender, EventArgs e)
{
    string path = @"C:\Users\test\Documents\test.text";
    ShowFileProperties(path);
}


Этот код откроет файл приложением, которое определено как приложение по умолчанию в контекстом меню.
Т.е. вместо огромной имплементации тех функций, что Вы указали, можно просто вызывать ShellEx со специально сформированной структурой SHELLEXECUTEINFO.
Вся соль в
info.fMask = SEE_MASK_INVOKEIDLIST;


Надо было просто более подробно вчитываться в MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/bb759784(v=vs.85).aspx
Спасибо всем за помощь.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.