2014-01-17 9 views
0

내가 휴지통에 저장된 ShellObject (ShellFile 또는 ShellFolder)에 undelete 동사를 호출 할 수있는 방법을 알고하는 C# 또는 Vb.NET 솔루션을 찾고 있어요.Windows API 코드 팩을 사용하여 ShellFile/ShellFolder/ShellObject 객체에서 Verb를 호출하는 방법은 무엇입니까?

필자가 작성한 휴지통 부분은 삭제 된 항목에서 동사를 호출하는 방법을 알고 있어야합니다.

내가 Shell32 인터페이스를 사용하여 동사를 호출 어떻게의 예를 보여 드리겠습니다 나를 더 잘 이해하기 위해,하지만 난 내가 사용에 관심 해요 Windows API Code Pack 라이브러리의 ShellObject/ShellFile/ShellFolder 항목에 대한 유사한 방법을 찾을 수 없습니다 :

Private SH As New Shell 
Private RecycleBin As Folder = 
     SH.NameSpace(ShellSpecialFolderConstants.ssfBITBUCKET) 

Dim RandomDeletedItem As FolderItem = RecycleBin.Items.Cast(Of FolderItem)(1) 

RandomDeletedItem.InvokeVerb("undelete") 

그리고이 여기

Private Shared RecycleBin As IKnownFolder = KnownFolders.RecycleBin 

Dim RandomDeletedItem As ShellObject = RecycleBin(1) 
Dim RandomDeletedFile As ShellFile = RecycleBin(1) 
Dim RandomDeletedFolder As ShellFolder = RecycleBin(1) 

' Here I need to know how to invoke the "undelete" verb on each object above... 

답변

1

의 분석 이름 주어진 재활용 휴지통에있는 파일을 삭제를 취소 ShellExecuteEx에 사용하는 방법 : (

' some file we got from the recycle bin iterating through the IShellItems: 
    Dim sParsing As String = _ 
     "E:\$RECYCLE.BIN\S-1-5-21-2546332361-822210090-45395533-1001\$RTD2G1Z.PNG" 
    Dim shex As New SHELLEXECUTEINFO 
    shex.cbSize = Marshal.SizeOf(shex) 

    ' Here we want ONLY the file name. 
    shex.lpFile = Path.GetFileName(sParsing) 

    ' Here we want the exact directory from the parsing name 
    shex.lpDirectory = Path.GetDirectoryName(sParsing) 
    shex.nShow = SW_SHOW ' = 5 
    '' here the verb is undelete, not restore. 
    shex.lpVerb = "undelete" 

    ShellExecuteEx(shex) 
+0

SW_NORMAL에 대한 참조 문서를 다른 상수와 함께 제공 할 수 있습니까? 나는 그것을 테스트하기 위해 그들의 가치를 알 필요가있다. – ElektroStudios

+0

5. SW_NORMAL은 5이다. –

+0

솔직하게 나는 그 매개 변수가 무엇이든 될 수 있다고 생각한다. –

3

(VB.NET)입니다 Windows API Code Pack 완료되지 않은 동일해야 당신이 어떤 쉘 거기에 어떤 동사를 호출 할 수 있도록 몇 가지 유틸리티 코드 여자 이름. 난 아직도 Windows API Code Pack를 사용하여 동사를 호출 할 수있는 방법을 찾고

IKnownFolder folder = KnownFolders.RecycleBin; 
foreach (ShellObject deleted in folder) 
{ 
    if (...) // whatever 
    { 
     CallShellItemVerb(deleted.Properties.System.ParsingPath.Value, "undelete"); 
    } 
} 

public static void CallShellItemVerb(string parsingPath, string verb) 
{ 
    if (parsingPath == null) 
     throw new ArgumentNullException("parsingPath"); 

    if (verb == null) 
    { 
     verb = "open"; 
    } 

    // get an item from the path 
    IShellItem item; 
    int hr = SHCreateItemFromParsingName(parsingPath, IntPtr.Zero, typeof(IShellItem).GUID, out item); 
    if (hr < 0) 
     throw new Win32Exception(hr); 

    // get the context menu from the item 
    IContextMenu menu; 
    Guid BHID_SFUIObject = new Guid("{3981e225-f559-11d3-8e3a-00c04f6837d5}"); 
    hr = item.BindToHandler(IntPtr.Zero, BHID_SFUIObject, typeof(IContextMenu).GUID, out menu); 
    if (hr < 0) 
     throw new Win32Exception(hr); 

    // build a fake context menu so we can scan it for the verb's menu id 
    ContextMenu cm = new ContextMenu(); 
    hr = menu.QueryContextMenu(cm.Handle, 0, 0, -1, CMF_NORMAL); 
    if (hr < 0) 
     throw new Win32Exception(hr); 

    int count = GetMenuItemCount(cm.Handle); 
    int verbId = -1; 
    for (int i = 0; i < count; i++) 
    { 
     int id = GetMenuItemID(cm.Handle, i); 
     if (id < 0) 
      continue; 

     StringBuilder sb = new StringBuilder(256); 
     hr = menu.GetCommandString(id, GCS_VERBW, IntPtr.Zero, sb, sb.Capacity); 
     if (sb.ToString() == verb) 
     { 
      verbId = id; 
      break; 
     } 
    } 

    if (verbId < 0) 
     throw new Win32Exception("Verb '" + verb + "' is not supported by the item"); 

    // call that verb 
    CMINVOKECOMMANDINFO ci = new CMINVOKECOMMANDINFO(); 
    ci.cbSize = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFO)); 
    ci.lpVerb = (IntPtr)verbId; 
    hr = menu.InvokeCommand(ref ci); 
    if (hr < 0) 
     throw new Win32Exception(hr); 
} 

[ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
private interface IShellItem 
{ 
    // NOTE: only partially defined, don't use in other contexts 
    [PreserveSig] 
    int BindToHandler(IntPtr pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid bhid, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IContextMenu ppv); 
} 

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214e4-0000-0000-c000-000000000046")] 
private interface IContextMenu 
{ 
    [PreserveSig] 
    int QueryContextMenu(IntPtr hmenu, int iMenu, int idCmdFirst, int idCmdLast, int uFlags); 

    [PreserveSig] 
    int InvokeCommand(ref CMINVOKECOMMANDINFO pici); 

    [PreserveSig] 
    int GetCommandString(int idCmd, int uFlags, IntPtr pwReserved, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMax); 
} 

[DllImport("user32.dll")] 
private static extern int GetMenuItemCount(IntPtr hMenu); 

[DllImport("user32.dll")] 
private static extern int GetMenuItemID(IntPtr hMenu, int nPos); 

[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 
private static extern int SHCreateItemFromParsingName(string path, IntPtr pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IShellItem item); 

private const int CMF_NORMAL = 0x00000000; 
private const int GCS_VERBW = 4; 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
private struct CMINVOKECOMMANDINFO 
{ 
    public int cbSize; 
    public int fMask; 
    public IntPtr hwnd; 
    public IntPtr lpVerb; 
    public string lpParameters; 
    public string lpDirectory; 
    public int nShow; 
    public int dwHotKey; 
    public IntPtr hIcon; 
} 
+0

감사합니다, 그것은 일반적인 사용에 대한 정말 좋은 솔루션입니다,하지만 난 하드 코딩하는 것보다 기본 방법을 사용하여 동사를 호출에-1 라인 용액 shell32를를 사용하는 역자 주 대안을 알고 400 줄 솔루션 (필요한 XML 문서의 합계에 포함)을 변경할 수있는 GUID가 있거나 ANSI-UNICODE 동사 구문 분석과 같은 문제가있을 수있는 곳 (문제가 발생할 수 있는지 여부는 알 수 없음)) ... 죄송하지만 WindowsAPICodePack을 사용하여이를 수행하는 방법을 찾고 있습니다. 공지 사항 : IShellItem 인터페이스는 WindowsAPICodePack에 포함되어 있습니다. 다시 한 번 감사드립니다! – ElektroStudios

+0

여기에 "하드 코드 된"것은 없습니다. 이 지침은 절대로 바뀌지 않을 것입니다. 이전 Windows 95로 작업하지 않는 한 유니 코드에 문제가 없어야합니다. IContextMenu라는 개념이 없기 때문에 Windows API 코드 팩을 사용하여 수행 할 수 있다고는 생각지 않습니다. IShellItem이 포함되어 있지만 내부로 정의되어 있다는 것을 알고 있습니다. 그들은 심지어 ShellObject의 기본 IShellItem에 접근 할 수있는 방법을 제공하지 않습니다 ... –

+0

이 경우 명확한 설명을 주신 덕분에 받아 들였습니다.추신 : 내 나쁜 영어를 용서하십시오. 내가 명확하지 않은 것 중 하나는 'CallShellItemVerb'와 함께'open' 동사를 사용하려고하면'동사가 항목에서 지원되지 않습니다. '라는 예외를 throw하지만, 같은'open' 동사를 사용하면 'shell32 interface'의'invokeverb' 메소드는 잘 작동하고 휴지통에있는 삭제 된 항목의 속성을 엽니 다. 그러면'open' 동사가이 코드에서 작동하지 않는 이유는 무엇입니까? (나는'open' 대신에'properties'를 사용해야합니다.) – ElektroStudios

0

:이 Recycle Bin 폴더에 작은 샘플과 undelete 정식 동사입니다.

이 답변은 VB.NET으로 번역 된 @Simon Mourier의 코드를 공유하는 것입니다. 누군가가이 geeneric 솔루션을 사용하고자한다면 문서를 추가하십시오.

그에 대한 크레딧.

''' <summary> 
''' Exposes methods that retrieve information about a Shell item. 
''' IShellItem and IShellItem2 are the preferred representations of items in any new code. 
''' </summary> 
<ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> 
Interface IShellItem 

    REM NOTE: This interface is only partially defined, don't use it in other contexts. 

    ''' <summary> 
    ''' Binds to a handler for an item as specified by the handler ID value (BHID). 
    ''' </summary> 
    ''' <param name="pbc"> 
    ''' A pointer to an IBindCtx interface on a bind context object. 
    ''' Used to pass optional parameters to the handler. 
    ''' The contents of the bind context are handler-specific. 
    ''' For example, when binding to BHID_Stream, the STGM flags in the bind context indicate the 
    ''' mode of access desired (read or read/write).</param> 
    ''' <param name="bhid"> 
    ''' Reference to a GUID that specifies which handler will be created. 
    ''' One of the following values defined in Shlguid.h.</param> 
    ''' <param name="riid"> 
    ''' IID of the object type to retrieve. 
    ''' </param> 
    ''' <param name="ppv"> 
    ''' When this method returns, 
    ''' contains a pointer of type riid that is returned by the handler specified by rbhid. 
    ''' </param> 
    ''' <returns>System.Int32.</returns> 
    <PreserveSig> 
    Function BindToHandler(
      ByVal pbc As IntPtr, 
      <MarshalAs(UnmanagedType.LPStruct)> ByVal bhid As Guid, 
      <MarshalAs(UnmanagedType.LPStruct)> ByVal riid As Guid, 
      ByRef ppv As IContextMenu 
    ) As Integer 
End Interface 

''' <summary> 
''' Exposes methods that either create or merge a shortcut menu associated with a Shell object. 
''' </summary> 
<ComImport, Guid("000214e4-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> 
Interface IContextMenu 

    ''' <summary> 
    ''' Adds commands to a shortcut menu. 
    ''' </summary> 
    ''' <param name="hmenu"> 
    ''' A handle to the shortcut menu. 
    ''' The handler should specify this handle when adding menu items. 
    ''' </param> 
    ''' <param name="iMenu"> 
    ''' The zero-based position at which to insert the first new menu item. 
    ''' </param> 
    ''' <param name="idCmdFirst"> 
    ''' The minimum value that the handler can specify for a menu item identifier. 
    ''' </param> 
    ''' <param name="idCmdLast"> 
    ''' The maximum value that the handler can specify for a menu item identifier. 
    ''' </param> 
    ''' <param name="uFlags"> 
    ''' Optional flags that specify how the shortcut menu can be changed. 
    ''' The remaining bits of the low-order word are reserved by the system. 
    ''' The high-order word can be used for context-specific communications. 
    ''' The CMF_RESERVED value can be used to mask the low-order word.</param> 
    ''' <returns>System.Int32.</returns> 
    <PreserveSig> 
    Function QueryContextMenu(
      ByVal hmenu As IntPtr, 
      ByVal iMenu As Integer, 
      ByVal idCmdFirst As Integer, 
      ByVal idCmdLast As Integer, 
      ByVal uFlags As QueryContextMenuFlags 
    ) As Integer 

    ''' <summary> 
    ''' Carries out the command associated with a shortcut menu item. 
    ''' </summary> 
    ''' <param name="pici"> 
    ''' A pointer to a CMINVOKECOMMANDINFO or CMINVOKECOMMANDINFOEX structure that contains 
    ''' specifics about the command.</param> 
    ''' <returns>System.Int32.</returns> 
    <PreserveSig> 
    Function InvokeCommand(
      ByRef pici As CMINVOKECOMMANDINFO 
    ) As Integer 

    ''' <summary> 
    ''' Gets information about a shortcut menu command, 
    ''' including the help string and the language-independent, or canonical, name for the command. 
    ''' </summary> 
    ''' <param name="idCmd"> 
    ''' Menu command identifier offset. 
    ''' </param> 
    ''' <param name="uFlags"> 
    ''' Flags specifying the information to return. 
    ''' </param> 
    ''' <param name="pwReserved"> 
    ''' Reserved. 
    ''' Applications must specify NULL when calling this method and 
    ''' handlers must ignore this parameter when called. 
    ''' </param> 
    ''' <param name="pszName"> 
    ''' The address of the buffer to receive the null-terminated string being retrieved. 
    ''' </param> 
    ''' <param name="cchMax"> 
    ''' Size of the buffer, in characters, to receive the null-terminated string. 
    ''' </param> 
    ''' <returns>System.Int32.</returns> 
    <PreserveSig> 
    Function GetCommandString(
      ByVal idCmd As Integer, 
      ByVal uFlags As GetCommandStringFlags, 
      ByVal pwReserved As IntPtr, 
      <MarshalAs(UnmanagedType.LPWStr)> ByVal pszName As StringBuilder, 
      ByVal cchMax As Integer) As Integer 
End Interface 



''' <summary> 
''' Determines the number of items in the specified menu. 
''' </summary> 
''' <param name="hMenu">A handle to the menu to be examined.</param> 
''' <returns> 
''' If the function succeeds, the return value specifies the number of items in the menu. 
''' If the function fails, the return value is -1.</returns> 
<DllImport("user32.dll")> 
Public Shared Function GetMenuItemCount(
       ByVal hMenu As IntPtr 
) As Integer 
End Function 

''' <summary> 
''' Retrieves the menu item identifier of a menu item located at the specified position in a menu. 
''' </summary> 
''' <param name="hMenu"> 
''' A handle to the menu that contains the item whose identifier is to be retrieved. 
''' </param> 
''' <param name="nPos"> 
''' The zero-based relative position of the menu item whose identifier is to be retrieved. 
''' </param> 
''' <returns> 
''' The return value is the identifier of the specified menu item. 
''' If the menu item identifier is NULL or if the specified item opens a submenu, the return value is -1. 
''' </returns> 
<DllImport("user32.dll")> _ 
Public Shared Function GetMenuItemID(
       ByVal hMenu As IntPtr, 
       ByVal nPos As Integer 
) As Integer 
End Function 

''' <summary> 
''' Creates and initializes a Shell item object from a parsing name. 
''' </summary> 
''' <param name="path"> 
''' A pointer to a display name. 
''' </param> 
''' <param name="pbc"> 
''' Optional. 
''' A pointer to a bind context used to pass parameters as inputs and outputs to the parsing function. 
''' These passed parameters are often specific to the data source and are documented by the data source owners. 
''' </param> 
''' <param name="riid"> 
''' A reference to the IID of the interface to retrieve through ppv, 
''' typically IID_IShellItem or IID_IShellItem2. 
''' </param> 
''' <param name="item"> 
''' When this method returns successfully, contains the interface pointer requested in riid. 
''' This is typically IShellItem or IShellItem2.</param> 
''' <returns>System.Int32.</returns> 
<DllImport("shell32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _ 
Public Shared Function SHCreateItemFromParsingName(
       ByVal path As String, 
       ByVal pbc As IntPtr, <MarshalAs(UnmanagedType.LPStruct)> 
       ByVal riid As Guid, 
       ByRef item As IShellItem 
) As Integer 
End Function 

''' <summary> 
''' Optional flags that specify how a shortcut menu can be changed. 
''' </summary> 
<Description("'uFlags' parameter used in 'QueryContextMenu' function")> 
Public Enum QueryContextMenuFlags As Integer 

    REM NOTE: This Enum is only partially defined, don't use it in other contexts. 

    ''' <summary> 
    ''' Indicates normal operation. 
    ''' A shortcut menu extension, namespace extension, or drag-and-drop handler can add all menu items. 
    ''' </summary> 
    CMF_NORMAL = &H0 

End Enum 

''' <summary> 
''' Flags specifying the information to return. 
''' </summary> 
<Description("'uFlags' parameter used in 'GetCommandString' function")> 
Public Enum GetCommandStringFlags As Integer 

    REM NOTE: This Enum is only partially defined, don't use it in other contexts. 

    ''' <summary> 
    ''' Sets pszName to a Unicode string containing the language-independent command name for the menu item. 
    ''' </summary> 
    GCS_VERBW = &H4 

End Enum 

''' <summary> 
''' Contains information needed by IContextMenu::InvokeCommand to invoke a shortcut menu command. 
''' </summary> 
<Description("'pici' parameter used in 'InvokeCommand' function")> 
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> 
Structure CMINVOKECOMMANDINFO 

    ''' <summary> 
    ''' The size of this structure, in bytes. 
    ''' </summary> 
    Public cbSize As Integer 

    ''' <summary> 
    ''' Zero, or one or more of the CMINVOKECOMMANDINFO flags. 
    ''' </summary> 
    Public fMask As Integer 

    ''' <summary> 
    ''' A handle to the window that is the owner of the shortcut menu. 
    ''' An extension can also use this handle as the owner of any message boxes or dialog boxes it displays. 
    ''' </summary> 
    Public hwnd As IntPtr 

    ''' <summary> 
    ''' The address of a null-terminated string that specifies the language-independent name 
    ''' of the command to carry out. 
    ''' This member is typically a string when a command is being activated by an application. 
    ''' The system provides predefined constant values for the following command strings. 
    ''' </summary> 
    Public lpVerb As IntPtr 

    ''' <summary> 
    ''' An optional string containing parameters that are passed to the command. 
    ''' The format of this string is determined by the command that is to be invoked. 
    ''' This member is always NULL for menu items inserted by a Shell extension. 
    ''' </summary> 
    Public lpParameters As String 

    ''' <summary> 
    ''' An optional working directory name. 
    ''' This member is always NULL for menu items inserted by a Shell extension. 
    ''' </summary> 
    Public lpDirectory As String 

    ''' <summary> 
    ''' A set of SW_ values to pass to the ShowWindow function if the command 
    ''' displays a window or starts an application. 
    ''' </summary> 
    Public nShow As Integer 

    ''' <summary> 
    ''' An optional keyboard shortcut to assign to any application activated by the command. 
    ''' If the fMask parameter does not specify CMIC_MASK_HOTKEY, this member is ignored. 
    ''' </summary> 
    Public dwHotKey As Integer 

    ''' <summary> 
    ''' An icon to use for any application activated by the command. 
    ''' If the fMask member does not specify CMIC_MASK_ICON, this member is ignored. 
    ''' </summary> 
    Public hIcon As IntPtr 

End Structure 

    ''' <summary> 
    ''' Invokes a verb on a ShellObject item. 
    ''' </summary> 
    ''' <param name="ShellObject"> 
    ''' Indicates the item. 
    ''' </param> 
    ''' <param name="Verb"> 
    ''' Indicates the verb to invoke on the item. 
    ''' </param> 
    ''' <exception cref="System.ArgumentNullException">ParsingPath</exception> 
    ''' <exception cref="System.ComponentModel.Win32Exception"> 
    ''' </exception> 
    Public Shared Sub InvokeItemVerb(ByVal [ShellObject] As ShellObject, 
            ByVal Verb As String) 

     Dim [ShellItem] As NativeMethods.IShellItem = Nothing 
     Dim menu As NativeMethods.IContextMenu = Nothing 
     Dim ci As New NativeMethods.CMINVOKECOMMANDINFO 
     Dim cm As New ContextMenu 
     Dim sb As New StringBuilder(256) 
     Dim hr As Integer = -1 
     Dim count As Integer = -1 
     Dim verbId As Integer = -1 
     Dim id As Integer = -1 
     Dim BHID_SFUIObject As Guid = Nothing 

     If Verb Is Nothing Then 
      Verb = "open" 
     End If 

     ' Get an item from the item parsing-path 
     hr = NativeMethods.SHCreateItemFromParsingName([ShellObject].Properties.System.ParsingPath.Value, 
                 IntPtr.Zero, 
                 GetType(NativeMethods.IShellItem).GUID, 
                 [ShellItem]) 

     If hr < 0 Then 
      Throw New Win32Exception(hr) 
     End If 

     ' Get the context menu from the item 
     BHID_SFUIObject = New Guid("{3981e225-f559-11d3-8e3a-00c04f6837d5}") 
     hr = [ShellItem].BindToHandler(IntPtr.Zero, BHID_SFUIObject, 
             GetType(NativeMethods.IContextMenu).GUID, 
             menu) 

     If hr < 0 Then 
      Throw New Win32Exception(hr) 
     End If 

     ' Build a fake context menu so we can scan it for the verb's menu id. 
     hr = menu.QueryContextMenu(cm.Handle, 0, 0, -1, 
            NativeMethods.QueryContextMenuFlags.CMF_NORMAL) 

     If hr < 0 Then 
      Throw New Win32Exception(hr) 
     End If 

     count = NativeMethods.GetMenuItemCount(cm.Handle) 

     For i As Integer = 0 To count - 1 

      id = NativeMethods.GetMenuItemID(cm.Handle, i) 

      If id < 0 Then 
       Continue For 
      End If 

      hr = menu.GetCommandString(id, NativeMethods.GetCommandStringFlags.GCS_VERBW, 
             IntPtr.Zero, sb, sb.Capacity) 

      If sb.ToString().Equals(Verb, StringComparison.InvariantCultureIgnoreCase) Then 
       verbId = id 
       Exit For 
      End If 

     Next i 

     If verbId < 0 Then 
      Throw New Win32Exception(String.Format("Verb '{0}' is not supported by the item.", Verb)) 
     End If 

     ' Invoke the Verb. 
     With ci 
      .cbSize = Marshal.SizeOf(GetType(NativeMethods.CMINVOKECOMMANDINFO)) 
      .lpVerb = New IntPtr(verbId) 
     End With 

     hr = menu.InvokeCommand(ci) 

     If hr < 0 Then 
      Throw New Win32Exception(hr) 
     End If 

    End Sub 
+0

이 코드의 문제점은 무엇입니까? –

+0

@Nathan M 코드 문제는 미적 문제입니다. Shell32 인터페이스의 사용을 WindowsAPiCodePack 메서드를 통해 휴지통으로 가져 오는 것을 피하고했습니다. 그런 다음 이제는 200을 사용하고 싶지 않습니다. WindowsAPICodePack 라이브러리 내에서 문서화되지 않은 메서드로 수행 할 수있는 해결책이 있지만 지금은 WindowsAPICodePack을 사용하여 동사를 호출하는 방법을 알지 못합니다. – ElektroStudios

+0

Windows API Code Pack을 변경하고 다시 컴파일하면됩니다. :-) 사실, 너무 오래 전 실제 셸 팝업 메뉴를 실제로 끌어 내려고 노력했지만, IContextMenu2와 IContextMenu3은 관리되는 코드로 정렬 된 WndProc에서 올바르게 실행되지 않습니다. 작은 C++/CLI 라이브러리가 필요할 수도있는 좀 더 섬세한 쉘 기능을 처리합니다. 동사를 호출하는 경우 ShellExecuteEx()를 사용할 수 있어야합니다. 그걸 시도하지 않았 니? –

1

이 @Nathan M 솔루션의 단지 적응 ShellObject 객체 제대로 작동 할 수있는 ShellItem 또는 ShellFolder 또는 기타 일 수 있습니다.

WindowsAPICodePack 라이브러리는 ShellExecuteInfo 구조에 사용 된 열거 형을 제공하므로 문서를 쓸 필요가 없습니다. 여기

은 다음과 같습니다

''' <summary> 
''' Performs an operation on a specified file.. 
''' </summary> 
''' <param name="lpExecInfo"> 
''' A pointer to a 'ShellExecuteInfo' structure that contains and receives information about 
''' the application being executed. 
''' </param> 
''' <returns><c>true</c> if successful, <c>false</c> otherwise.</returns> 
<DllImport("Shell32", CharSet:=CharSet.Auto, SetLastError:=True)> _ 
Public Shared Function ShellExecuteEx(
       ByRef lpExecInfo As ShellExecuteInfo 
) As Boolean 
End Function 

''' <summary> 
''' Contains information used by 'ShellExecuteEx' function. 
''' </summary> 
<Description("'lpExecInfo' parameter used in 'ShellExecuteEx' function")> 
Public Structure ShellExecuteInfo 

    ''' <summary> 
    ''' Required. 
    ''' The size of this structure, in bytes. 
    ''' </summary> 
    Public cbSize As Integer 

    ''' <summary> 
    ''' Flags that indicate the content and validity of the other structure members. 
    ''' </summary> 
    Public fMask As Integer 

    ''' <summary> 
    ''' Optional. 
    ''' A handle to the parent window, 
    ''' used to display any message boxes that the system might produce while executing this function. 
    ''' This value can be NULL. 
    ''' </summary> 
    Public hwnd As IntPtr 

    ''' <summary> 
    ''' A string, referred to as a verb, that specifies the action to be performed. 
    ''' The set of available verbs depends on the particular file or folder. 
    ''' Generally, the actions available from an object's shortcut menu are available verbs. 
    ''' This parameter can be NULL, in which case the default verb is used if available. 
    ''' If not, the "open" verb is used. 
    ''' If neither verb is available, the system uses the first verb listed in the registry. 
    ''' </summary> 
    <MarshalAs(UnmanagedType.LPTStr)> Public lpVerb As String 

    ''' <summary> 
    ''' The address of a null-terminated string that specifies the name of the file 
    ''' or object on which ShellExecuteEx will perform the action specified by the lpVerb parameter. 
    ''' The system registry verbs that are supported by the ShellExecuteEx function include "open" 
    ''' for executable files and document files and "print" for document files 
    ''' for which a print handler has been registered. 
    ''' Other applications might have added Shell verbs through the system registry, 
    ''' such as "play" for .avi and .wav files. 
    ''' To specify a Shell namespace object, pass the fully qualified parse name 
    ''' and set the SEE_MASK_INVOKEIDLIST flag in the fMask parameter. 
    ''' </summary> 
    <MarshalAs(UnmanagedType.LPTStr)> Public lpFile As String 

    ''' <summary> 
    ''' Optional. 
    ''' The address of a null-terminated string that contains the application parameters. 
    ''' The parameters must be separated by spaces. 
    ''' If the lpFile member specifies a document file, lpParameters should be NULL. 
    ''' </summary> 
    <MarshalAs(UnmanagedType.LPTStr)> Public lpParameters As String 

    ''' <summary> 
    ''' Optional. 
    ''' The address of a null-terminated string that specifies the name of the working directory. 
    ''' If this member is NULL, the current directory is used as the working directory. 
    ''' </summary> 
    <MarshalAs(UnmanagedType.LPTStr)> Public lpDirectory As String 

    ''' <summary> 
    ''' Required. 
    ''' Flags that specify how an application is to be shown when it is opened; 
    ''' one of the SW_ values listed for the ShellExecute function. 
    ''' If lpFile specifies a document file, the flag is simply passed to the associated application. 
    ''' It is up to the application to decide how to handle it. 
    ''' </summary> 
    Dim nShow As WindowShowCommand 

    ''' <summary> 
    ''' If SEE_MASK_NOCLOSEPROCESS is set and the ShellExecuteEx call succeeds, 
    ''' it sets this member to a value greater than 32. 
    ''' If the function fails, it is set to an SE_ERR_XXX error value that indicates the cause of the failure. 
    ''' Although hInstApp is declared as an HINSTANCE for compatibility with 16-bit Windows applications, 
    ''' it is not a true HINSTANCE. 
    ''' It can be cast only to an int and compared to either 32 or the following SE_ERR_XXX error codes. 
    ''' </summary> 
    Dim hInstApp As IntPtr 

    ''' <summary> 
    ''' The address of an absolute ITEMIDLIST structure (PCIDLIST_ABSOLUTE) 
    ''' to contain an item identifier list that uniquely identifies the file to execute. 
    ''' This member is ignored if the fMask member does not include SEE_MASK_IDLIST or SEE_MASK_INVOKEIDLIST. 
    ''' </summary> 
    Dim lpIDList As IntPtr 

    ''' <summary> 
    ''' The address of a null-terminated string that specifies one of the following 
    ''' A ProgId. For example, "Paint.Picture". 
    ''' A URI protocol scheme. For example, "http". 
    ''' A file extension. For example, ".txt". 
    ''' A registry path under HKEY_CLASSES_ROOT that names a subkey that contains one or more Shell verbs. 
    ''' This key will have a subkey that conforms to the Shell verb registry schema, such as shell\verb name. 
    ''' </summary> 
    <MarshalAs(UnmanagedType.LPTStr)> Public lpClass As String 

    ''' <summary> 
    ''' A handle to the registry key for the file type. 
    ''' The access rights for this registry key should be set to KEY_READ. 
    ''' This member is ignored if fMask does not include SEE_MASK_CLASSKEY. 
    ''' </summary> 
    Public hkeyClass As IntPtr 

    ''' <summary> 
    ''' A keyboard shortcut to associate with the application. 
    ''' The low-order word is the virtual key code, and the high-order word is a modifier flag (HOTKEYF_). 
    ''' For a list of modifier flags, see the description of the WM_SETHOTKEY message. 
    ''' This member is ignored if fMask does not include SEE_MASK_HOTKEY. 
    ''' </summary> 
    Public dwHotKey As Integer 

    ''' <summary> 
    ''' A handle to the icon for the file type. 
    ''' This member is ignored if fMask does not include SEE_MASK_ICON. 
    ''' This value is used only in Windows XP and earlier. 
    ''' It is ignored as of Windows Vista. 
    ''' </summary> 
    Public hIcon As IntPtr 

    ''' <summary> 
    ''' A handle to the monitor upon which the document is to be displayed. 
    ''' This member is ignored if fMask does not include SEE_MASK_HMONITOR. 
    ''' </summary> 
    Public hProcess As IntPtr 

End Structure 

''' <summary> 
''' Invokes a verb on a ShellObject item. 
''' </summary> 
''' <param name="ShellObject"> 
''' Indicates the item. 
''' </param> 
''' <param name="Verb"> 
''' Indicates the verb to invoke on the item. 
''' </param> 
Public Shared Sub InvokeItemVerb(ByVal [ShellObject] As ShellObject, 
           ByVal Verb As String) 

    Dim FileName As String = [ShellObject].ParsingName.Split("\").Last 
    Dim FileDir As String = IO.Path.GetDirectoryName([ShellObject].ParsingName) 

    Dim sei As New ShellExecuteInfo 

    With sei 

     .cbSize = Marshal.SizeOf(sei) 

     ' Here we want ONLY the filename (without the path). 
     .lpFile = FileName 

     ' Here we want the exact directory from the parsing name. 
     .lpDirectory = FileDir 

     ' Here the show command. 
     .nShow = WindowShowCommand.Show 

     ' Here the verb to invoke. 
     .lpVerb = Verb 

    End With 

    ' Invoke the verb. 
    ShellExecuteEx(sei) 

End Sub