Advertisement
Guest User

FileAssocUti.vb - By Elektro

a guest
Jun 21st, 2015
329
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 63.75 KB | None | 0 0
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 21-June-2015
  4. ' ***********************************************************************
  5. ' <copyright file="FileAssocUtil.vb" company="Elektro Studios">
  6. '     Copyright (c) Elektro Studios. All rights reserved.
  7. ' </copyright>
  8. ' ***********************************************************************
  9.  
  10. #Region " Public Members Summary "
  11.  
  12. #Region " Functions "
  13.  
  14. ' FileAssocUtil.GetFileExtensionInfo(String) As FileExtensionInfo
  15. ' FileAssocUtil.IsRegistered(String) As Boolean
  16.  
  17. #End Region
  18.  
  19. #Region " Methods "
  20.  
  21. ' FileAssocUtil.Register(RegistryUser, String, String, String, String, Integer, String, String)
  22.  
  23. #End Region
  24.  
  25. #Region " Types "
  26.  
  27. ' FileAssocUtil.FileExtensionInfo
  28.  
  29. #End Region
  30.  
  31. #End Region
  32.  
  33. #Region " Option Statements "
  34.  
  35. Option Strict On
  36. Option Explicit On
  37. Option Infer Off
  38.  
  39. #End Region
  40.  
  41. #Region " Imports "
  42.  
  43. Imports Microsoft.Win32
  44. Imports System
  45. Imports System.ComponentModel
  46. Imports System.Linq
  47. Imports System.Runtime.InteropServices
  48. Imports System.Text
  49. Imports System.Reflection
  50. Imports System.Linq.Expressions
  51. Imports System.IO
  52.  
  53. #End Region
  54.  
  55. #Region " User-Accoun tUtil "
  56.  
  57. ''' <summary>
  58. ''' Contains related Windows file association utilities.
  59. ''' </summary>
  60. Public NotInheritable Class FileAssocUtil
  61.  
  62. #Region " P/Invoking "
  63.  
  64.     ''' ----------------------------------------------------------------------------------------------------
  65.     ''' <summary>
  66.     ''' Platform Invocation methods (P/Invoke), access unmanaged code.
  67.     ''' This class does not suppress stack walks for unmanaged code permission.
  68.     ''' <see cref="System.Security.SuppressUnmanagedCodeSecurityAttribute"/> must not be applied to this class.
  69.     ''' This class is for methods that can be used anywhere because a stack walk will be performed.
  70.     ''' </summary>
  71.     ''' ----------------------------------------------------------------------------------------------------
  72.     ''' <remarks>http://msdn.microsoft.com/en-us/library/ms182161.aspx</remarks>
  73.     ''' ----------------------------------------------------------------------------------------------------
  74.     Private NotInheritable Class NativeMethods
  75.  
  76. #Region " Functions "
  77.  
  78.         ''' ----------------------------------------------------------------------------------------------------
  79.         ''' <summary>
  80.         ''' Searches for and retrieves a file or protocol association-related string from the registry.
  81.         ''' </summary>
  82.         ''' ----------------------------------------------------------------------------------------------------
  83.         ''' <param name="flags">
  84.         ''' The flags that can be used to control the search. It can be any combination of ASSOCF values, except that only one ASSOCF_INIT value can be included.
  85.         ''' </param>
  86.         '''
  87.         ''' <param name="str">
  88.         ''' An <see cref="ASSOCSTR"/> value that specifies the type of string that is to be returned.
  89.         ''' </param>
  90.         '''
  91.         ''' <param name="pszAssoc">
  92.         ''' A pointer to a null-terminated string that is used to determine the root key.
  93.         ''' The following four types of strings can be used:
  94.         '''
  95.         ''' - A file name extension, such as '.txt'.
  96.         ''' - A CLSID GUID in the standard '{GUID}' format.
  97.         ''' - An application's ProgID, such as 'Word.Document.8.'
  98.         ''' - The name of an application's .exe file (The ASSOCF_OPEN_BYEXENAME flag must be set in flags).
  99.         ''' </param>
  100.         '''
  101.         ''' <param name="pszExtra">
  102.         ''' An optional null-terminated string with additional information about the location of the string.
  103.         ''' It is typically set to a Shell verb such as 'open'. Set this parameter to <c>Nothing</c> if it is not used.
  104.         ''' </param>
  105.         '''
  106.         ''' <param name="pszOut">
  107.         ''' Pointer to a null-terminated string that, when this function returns successfully, receives the requested string.
  108.         ''' Set this parameter to <c>Nothing</c> to retrieve the required buffer size.
  109.         ''' </param>
  110.         '''
  111.         ''' <param name="pcchOut">
  112.         ''' A pointer to a value that, when calling the function, is set to the number of characters in the <paramref name="pszOut"></paramref> buffer.
  113.         ''' When the function returns successfully, the value is set to the number of characters actually placed in the buffer.
  114.         '''
  115.         ''' If the ASSOCF_NOTRUNCATE flag is set in <paramref name="flags"></paramref> and the
  116.         ''' buffer specified in <paramref name="pszOut"></paramref> is too small,
  117.         ''' the function returns E_POINTER and the value is set to the required size of the buffer.
  118.         '''
  119.         ''' If <paramref name="pszOut"></paramref> is <c>Nothing</c>,
  120.         ''' the function returns S_FALSE and <paramref name="pcchOut"></paramref> points to the required size, in characters, of the buffer.
  121.         ''' </param>
  122.         ''' ----------------------------------------------------------------------------------------------------
  123.         ''' <returns>
  124.         ''' Returns a standard COM error value, including the following:
  125.         ''' S_OK: Success.
  126.         ''' E_POINTER: The pszOut buffer is too small to hold the entire string.
  127.         ''' S_FALSE: <paramref name="pszOut"></paramref> is <c>Nothing</c>, <paramref name="pcchOut"></paramref> contains the required buffer size.
  128.         ''' </returns>
  129.         ''' ----------------------------------------------------------------------------------------------------
  130.         ''' <remarks>https://msdn.microsoft.com/en-us/library/windows/desktop/bb773471%28v=vs.85%29.aspx</remarks>
  131.         ''' ----------------------------------------------------------------------------------------------------
  132.         <DllImport("Shlwapi.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
  133.         Friend Shared Function AssocQueryString(
  134.                                ByVal flags As AssocF,
  135.                                ByVal str As AssocStr,
  136.                                ByVal pszAssoc As String,
  137.                                ByVal pszExtra As String,
  138.                          <Out> ByVal pszOut As StringBuilder,
  139.                   <[In]> <Out> ByRef pcchOut As UInteger
  140.         ) As UInteger
  141.         End Function
  142.  
  143. #End Region
  144.  
  145. #Region " Methods "
  146.  
  147.         ''' ----------------------------------------------------------------------------------------------------
  148.         ''' <summary>
  149.         ''' Notifies the system of an event that an application has performed.
  150.         ''' An application should use this function if it performs an action that may affect the Shell.
  151.         ''' </summary>
  152.         ''' ----------------------------------------------------------------------------------------------------
  153.         ''' <param name="wEventId">
  154.         ''' Describes the event that has occurred.
  155.         ''' Typically, only one event is specified at a time.
  156.         ''' If more than one event is specified, the values contained in the dwItem1 and dwItem2 parameters must be the same, respectively, for all specified events.
  157.         ''' </param>
  158.         '''
  159.         ''' <param name="uFlags">
  160.         ''' Flags that, when combined bitwise with SHCNF_TYPE,
  161.         ''' indicate the meaning of the dwItem1 and dwItem2 parameters.
  162.         ''' </param>
  163.         '''
  164.         ''' <param name="dwItem1">
  165.         ''' Optional.
  166.         ''' First event-dependent value.
  167.         ''' </param>
  168.         '''
  169.         ''' <param name="dwItem2">
  170.         ''' Optional.
  171.         ''' Second event-dependent value.
  172.         ''' </param>
  173.         ''' ----------------------------------------------------------------------------------------------------
  174.         ''' <remarks>https://msdn.microsoft.com/en-us/library/windows/desktop/bb762118%28v=vs.85%29.aspx</remarks>
  175.         ''' ----------------------------------------------------------------------------------------------------
  176.         <DllImport("shell32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
  177.         Friend Shared Sub SHChangeNotify(
  178.                       ByVal wEventId As HChangeNotifyEventID,
  179.                       ByVal uFlags As HChangeNotifyFlags,
  180.                       ByVal dwItem1 As IntPtr,
  181.                       ByVal dwItem2 As IntPtr)
  182.         End Sub
  183.  
  184. #End Region
  185.  
  186. #Region " Enumerations "
  187.  
  188.         ''' ----------------------------------------------------------------------------------------------------
  189.         ''' <summary>
  190.         ''' Provides information to the IQueryAssociations interface methods.
  191.         ''' </summary>
  192.         ''' ----------------------------------------------------------------------------------------------------
  193.         ''' <remarks>https://msdn.microsoft.com/en-us/library/windows/desktop/bb762471%28v=vs.85%29.aspx</remarks>
  194.         ''' ----------------------------------------------------------------------------------------------------
  195.         <Flags>
  196.         Friend Enum AssocF As Integer
  197.  
  198.             ''' <summary>
  199.             ''' None of the following options are set.
  200.             ''' </summary>
  201.             None = &H0
  202.  
  203.             ''' <summary>
  204.             ''' Instructs IQueryAssociations interface methods not to map CLSID values to ProgID values.
  205.             ''' </summary>
  206.             InitNoRemapClsid = &H1
  207.  
  208.             ''' <summary>
  209.             ''' Identifies the value of the pwszAssoc parameter of IQueryAssociations::Init as an executable file name.
  210.             ''' If this flag is not set, the root key will be set to the ProgID associated with the .exe key instead of the executable file's ProgID.
  211.             ''' </summary>
  212.             InitByExeName = &H2
  213.  
  214.             ''' <summary>
  215.             ''' Identical to <see cref="AssocF.InitByExeName"/>.
  216.             ''' </summary>
  217.             OpenByExeName = &H2
  218.  
  219.             ''' <summary>
  220.             ''' Specifies that when an IQueryAssociations method does not find the requested value under the root key,
  221.             ''' it should attempt to retrieve the comparable value from the * subkey.
  222.             ''' </summary>
  223.             InitDefaultToStar = &H4
  224.  
  225.             ''' <summary>
  226.             ''' Specifies that when a IQueryAssociations method does not find the requested value under the root key,
  227.             ''' it should attempt to retrieve the comparable value from the Folder subkey.
  228.             ''' </summary>
  229.             InitDefaultToFolder = &H8
  230.  
  231.             ''' <summary>
  232.             ''' Specifies that only HKEY_CLASSES_ROOT should be searched, and that HKEY_CURRENT_USER should be ignored.
  233.             ''' </summary>
  234.             NoUserSettings = &H10
  235.  
  236.             ''' <summary>
  237.             ''' Specifies that the return string should not be truncated.
  238.             ''' Instead, return an error value and the required size for the complete string.
  239.             ''' </summary>
  240.             NoTruncate = &H20
  241.  
  242.             ''' <summary>
  243.             ''' Instructs IQueryAssociations methods to verify that data is accurate.
  244.             ''' This setting allows IQueryAssociations methods to read data from the user's hard disk for verification.
  245.             ''' For example, they can check the friendly name in the registry against the one stored in the .exe file.
  246.             ''' Setting this flag typically reduces the efficiency of the method.
  247.             ''' </summary>
  248.             Verify = &H40
  249.  
  250.             ''' <summary>
  251.             ''' Instructs IQueryAssociations methods to ignore Rundll.exe and return information about its target.
  252.             ''' Typically IQueryAssociations methods return information about the first .exe or .dll in a command string.
  253.             ''' If a command uses Rundll.exe, setting this flag tells the method to ignore Rundll.exe and return information about its target.
  254.             ''' </summary>
  255.             RemapRunDll = &H80
  256.  
  257.             ''' <summary>
  258.             ''' Instructs IQueryAssociations methods not to fix errors in the registry,
  259.             ''' such as the friendly name of a function not matching the one found in the .exe file.
  260.             ''' </summary>
  261.             NoFixUps = &H100
  262.  
  263.             ''' <summary>
  264.             ''' Specifies that the BaseClass value should be ignored.
  265.             ''' </summary>
  266.             IgnoreBaseClass = &H200
  267.  
  268.             ''' <summary>
  269.             ''' (Introduced in Windows 7)
  270.             ''' Specifies that the "Unknown" ProgID should be ignored; instead, fail.
  271.             ''' </summary>
  272.             IgnoreUnknown = &H400
  273.  
  274.             ''' <summary>
  275.             ''' (Introduced in Windows 8)
  276.             ''' Specifies that the supplied ProgID should be mapped using the system defaults, rather than the current user defaults.
  277.             ''' </summary>
  278.             InitFixedProgId = &H800
  279.  
  280.             ''' <summary>
  281.             ''' (Introduced in Windows 8)
  282.             ''' Specifies that the value is a protocol, and should be mapped using the current user defaults.
  283.             ''' </summary>
  284.             IsProtocol = &H1000
  285.  
  286.             ''' <summary>
  287.             ''' (Introduced in Windows 8.1)
  288.             ''' Specifies that the ProgID corresponds with a file extension based association.
  289.             ''' Use this flag together with <see cref="AssocF.InitFixedProgId"/>.
  290.             ''' </summary>
  291.             InitForFile = &H2000
  292.  
  293.         End Enum
  294.  
  295.         ''' ----------------------------------------------------------------------------------------------------
  296.         ''' <summary>
  297.         ''' Used by IQueryAssociations::GetString to define the type of string that is to be returned.
  298.         ''' </summary>
  299.         ''' ----------------------------------------------------------------------------------------------------
  300.         ''' <remarks>https://msdn.microsoft.com/en-us/library/windows/desktop/bb762475%28v=vs.85%29.aspx</remarks>
  301.         ''' ----------------------------------------------------------------------------------------------------
  302.         Friend Enum AssocStr As Integer
  303.  
  304.             ''' <summary>
  305.             ''' A command string associated with a Shell verb.
  306.             ''' </summary>
  307.             Command = 1
  308.  
  309.             ''' <summary>
  310.             ''' An executable from a Shell verb command string.
  311.             ''' For example, this string is found as the (Default) value for a subkey such as HKEY_CLASSES_ROOT\ApplicationName\shell\Open\command.
  312.             ''' If the command uses Rundll.exe, set the <see cref="AssocF.RemapRunDll"/> flag in the flags parameter of IQueryAssociations::GetString to retrieve the target executable.
  313.             ''' </summary>
  314.             Executable = 2
  315.  
  316.             ''' <summary>
  317.             ''' The friendly name of a document type.
  318.             ''' </summary>
  319.             FriendlyDocName = 3
  320.  
  321.             ''' <summary>
  322.             ''' The friendly name of an executable file.
  323.             ''' </summary>
  324.             FriendlyAppName = 4
  325.  
  326.             ''' <summary>
  327.             ''' Ignore the information associated with the open subkey.
  328.             ''' </summary>
  329.             NoOpen = 5
  330.  
  331.             ''' <summary>
  332.             ''' Look under the ShellNew subkey.
  333.             ''' </summary>
  334.             ShellNewValue = 6
  335.  
  336.             ''' <summary>
  337.             ''' A template for DDE commands.
  338.             ''' </summary>
  339.             DdeCommand = 7
  340.  
  341.             ''' <summary>
  342.             ''' The DDE command to use to create a process.
  343.             ''' </summary>
  344.             DdeIfExec = 8
  345.  
  346.             ''' <summary>
  347.             ''' The application name in a DDE broadcast.
  348.             ''' </summary>
  349.             DdeApplication = 9
  350.  
  351.             ''' <summary>
  352.             ''' The topic name in a DDE broadcast.
  353.             ''' </summary>
  354.             DdeTopic = 10
  355.  
  356.             ''' <summary>
  357.             ''' Corresponds to the InfoTip registry value.
  358.             ''' Returns an info tip for an item, or list of properties in the form of an IPropertyDescriptionList from which to create an info tip,
  359.             ''' such as when hovering the cursor over a file name.
  360.             ''' The list of properties can be parsed with PSGetPropertyDescriptionListFromString.
  361.             ''' </summary>
  362.             InfoTip = 11
  363.  
  364.             ''' <summary>
  365.             ''' Corresponds to the QuickTip registry value. Same as <see cref="AssocStr.InfoTip"/>,
  366.             ''' except that it always returns a list of property names in the form of an IPropertyDescriptionList.
  367.             ''' The difference between this value and <see cref="AssocStr.InfoTip"/> is that this returns properties that are
  368.             ''' safe for any scenario that causes slow property retrieval, such as offline or slow networks.
  369.             ''' Some of the properties returned from <see cref="AssocStr.InfoTip"/> might not be appropriate for slow property retrieval scenarios.
  370.             ''' The list of properties can be parsed with PSGetPropertyDescriptionListFromString.
  371.             ''' </summary>
  372.             QuickTip = 12
  373.  
  374.             ''' <summary>
  375.             ''' Corresponds to the TileInfo registry value.
  376.             ''' Contains a list of properties to be displayed for a particular file type in a Windows Explorer window that is in tile view.
  377.             ''' This is the same as <see cref="AssocStr.InfoTip"/>, but, like <see cref="AssocStr.QuickTip"/>, it also returns a list of property names in the
  378.             ''' form of an IPropertyDescriptionList.
  379.             ''' The list of properties can be parsed with PSGetPropertyDescriptionListFromString
  380.             ''' </summary>
  381.             TileInfo = 13
  382.  
  383.             ''' <summary>
  384.             ''' Describes a general type of MIME file association, such as image and bmp,
  385.             ''' so that applications can make general assumptions about a specific file type.
  386.             ''' </summary>
  387.             ContentType = 14
  388.  
  389.             ''' <summary>
  390.             ''' Returns the path to the icon resources to use by default for this association.
  391.             ''' Positive numbers indicate an index into the dll's resource table, while negative numbers indicate a resource ID.
  392.             ''' An example of the syntax for the resource is "c:\myfolder\myfile.dll,-1".
  393.             ''' </summary>
  394.             DefaultIcon = 15
  395.  
  396.             ''' <summary>
  397.             ''' For an object that has a Shell extension associated with it, you can use this to retrieve the CLSID of that Shell extension object
  398.             ''' by passing a string representation of the IID of the interface you want to retrieve as the pwszExtra parameter of IQueryAssociations::GetString.
  399.             ''' For example, if you want to retrieve a handler that implements the IExtractImage interface,
  400.             ''' you would specify "{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}", which is the IID of IExtractImage.
  401.             ''' </summary>
  402.             ShellExtension = 16
  403.  
  404.             ''' <summary>
  405.             ''' For a verb invoked through COM and the IDropTarget interface, you can use this flag to retrieve the IDropTarget object's CLSID.
  406.             ''' This CLSID is registered in the DropTarget subkey. The verb is specified in the pwszExtra parameter in the call to IQueryAssociations::GetString.
  407.             ''' </summary>
  408.             DropTarget = 17
  409.  
  410.             ''' <summary>
  411.             ''' For a verb invoked through COM and the IExecuteCommand interface, you can use this flag to retrieve the IExecuteCommand object's CLSID.
  412.             ''' This CLSID is registered in the verb's command subkey as the DelegateExecute entry.
  413.             ''' The verb is specified in the pwszExtra parameter in the call to IQueryAssociations::GetString.
  414.             ''' </summary>
  415.             DelegateExecute = 18
  416.  
  417.             ''' <summary>
  418.             ''' Introduced in Windows 8.
  419.             ''' There is no official documentation for this flag.
  420.             ''' </summary>
  421.             SupportedUriProtocols = 19
  422.  
  423.             ''' <summary>
  424.             ''' The maximum defined <see cref="AssocStr"/> value, used for validation purposes.
  425.             ''' </summary>
  426.             Max = 20
  427.  
  428.         End Enum
  429.  
  430.         ''' ----------------------------------------------------------------------------------------------------
  431.         ''' <summary>
  432.         ''' Flags for <paramref name="wEventId"/> parameter of <see cref="FileAssocUtil.NativeMethods.SHChangeNotify"/> method.
  433.         ''' </summary>
  434.         ''' ----------------------------------------------------------------------------------------------------
  435.         ''' <remarks>https://msdn.microsoft.com/en-us/library/windows/desktop/bb762118%28v=vs.85%29.aspx</remarks>
  436.         ''' ----------------------------------------------------------------------------------------------------
  437.         <Flags>
  438.         Friend Enum HChangeNotifyEventID As UInteger
  439.  
  440.             ' *****************************************************************************
  441.             '                            WARNING!, NEED TO KNOW...
  442.             '
  443.             '  THIS ENUMERATION IS PARTIALLY DEFINED JUST FOR THE PURPOSES OF THIS PROJECT
  444.             ' *****************************************************************************
  445.  
  446.             ''' <summary>
  447.             ''' All events have occurred.
  448.             ''' </summary>
  449.             AllEvents = &H7FFFFFFFUI
  450.  
  451.             ''' <summary>
  452.             ''' A file type association has changed.
  453.             ''' <see cref="FileAssocUtil.NativeMethods.HChangeNotifyFlags.IdList"/> must be specified in the <paramref name="uFlags"/> parameter.
  454.             ''' <paramref name="dwItem1"/> and <paramref name="dwItem2"/> are not used and must be set as <see cref="IntPtr.Zero"/>.
  455.             ''' </summary>
  456.             AssocChanged = &H8000000UI
  457.  
  458.         End Enum
  459.  
  460.         ''' ----------------------------------------------------------------------------------------------------
  461.         ''' <summary>
  462.         ''' Flags for <paramref name="uFlags"/> parameter of <see cref="FileAssocUtil.NativeMethods.SHChangeNotify"/> method.
  463.         ''' </summary>
  464.         ''' ----------------------------------------------------------------------------------------------------
  465.         ''' <remarks>https://msdn.microsoft.com/en-us/library/windows/desktop/bb762118%28v=vs.85%29.aspx</remarks>
  466.         ''' ----------------------------------------------------------------------------------------------------
  467.         <Flags>
  468.         Friend Enum HChangeNotifyFlags As UInteger
  469.  
  470.             ' *****************************************************************************
  471.             '                            WARNING!, NEED TO KNOW...
  472.             '
  473.             '  THIS ENUMERATION IS PARTIALLY DEFINED JUST FOR THE PURPOSES OF THIS PROJECT
  474.             ' *****************************************************************************
  475.  
  476.             ''' <summary>
  477.             ''' <paramref name="dwItem1"/> and <paramref name="dwItem2"/> are the addresses of 'ITEMIDLIST' structures that
  478.             ''' represent the item(s) affected by the change.
  479.             ''' Each 'ITEMIDLIST' must be relative to the desktop folder.
  480.             ''' </summary>
  481.             IdList = &H0UI
  482.  
  483.         End Enum
  484.  
  485. #End Region
  486.  
  487.     End Class
  488.  
  489. #End Region
  490.  
  491. #Region " Types "
  492.  
  493.     ''' <summary>
  494.     ''' Defines the system information of a file extension.
  495.     ''' </summary>
  496.     <Serializable>
  497.     Public NotInheritable Class FileExtensionInfo
  498.  
  499. #Region " Properties "
  500.  
  501.         ''' ----------------------------------------------------------------------------------------------------
  502.         ''' <summary>
  503.         ''' Gets the file extension name.
  504.         ''' </summary>
  505.         ''' ----------------------------------------------------------------------------------------------------
  506.         ''' <value>
  507.         ''' The file extension name.
  508.         ''' </value>
  509.         ''' ----------------------------------------------------------------------------------------------------
  510.         Public ReadOnly Property Name As String
  511.             Get
  512.                 Return Me.nameB
  513.             End Get
  514.         End Property
  515.         ''' <summary>
  516.         ''' (Backing Field)
  517.         ''' The file extension name.
  518.         ''' </summary>
  519.         Private ReadOnly nameB As String
  520.  
  521.         ''' ----------------------------------------------------------------------------------------------------
  522.         ''' <summary>
  523.         ''' Gets a command string associated with a Shell verb.
  524.         ''' </summary>
  525.         ''' ----------------------------------------------------------------------------------------------------
  526.         ''' <value>
  527.         ''' A command string associated with a Shell verb.
  528.         ''' </value>
  529.         ''' ----------------------------------------------------------------------------------------------------
  530.         Public Property Command As String
  531.  
  532.         ''' ----------------------------------------------------------------------------------------------------
  533.         ''' <summary>
  534.         ''' Gets an executable from a Shell verb command string.
  535.         ''' For example, this string is found as the (Default) value for a subkey such as HKEY_CLASSES_ROOT\ApplicationName\shell\Open\command.
  536.         ''' </summary>
  537.         ''' ----------------------------------------------------------------------------------------------------
  538.         ''' <value>
  539.         ''' An executable from a Shell verb command string.
  540.         ''' </value>
  541.         ''' ----------------------------------------------------------------------------------------------------
  542.         Public Property Executable As String
  543.  
  544.         ''' ----------------------------------------------------------------------------------------------------
  545.         ''' <summary>
  546.         ''' Gets the friendly name of a document type.
  547.         ''' </summary>
  548.         ''' ----------------------------------------------------------------------------------------------------
  549.         ''' <value>
  550.         ''' The friendly name of a document type.
  551.         ''' </value>
  552.         ''' ----------------------------------------------------------------------------------------------------
  553.         Public Property FriendlyDocName As String
  554.  
  555.         ''' ----------------------------------------------------------------------------------------------------
  556.         ''' <summary>
  557.         ''' Gets the friendly name of an executable file.
  558.         ''' </summary>
  559.         ''' ----------------------------------------------------------------------------------------------------
  560.         ''' <value>
  561.         ''' The friendly name of an executable type.
  562.         ''' </value>
  563.         ''' ----------------------------------------------------------------------------------------------------
  564.         Public Property FriendlyAppName As String
  565.  
  566.         ''' ----------------------------------------------------------------------------------------------------
  567.         ''' <summary>
  568.         ''' Gets a value indicating whether the association ignores the information associated with the 'open' subkey command.
  569.         ''' </summary>
  570.         ''' ----------------------------------------------------------------------------------------------------
  571.         ''' <value>
  572.         ''' A value indicating whether the association ignores the information associated with the 'open' subkey command.
  573.         ''' </value>
  574.         ''' ----------------------------------------------------------------------------------------------------
  575.         Public Property NoOpen As String
  576.  
  577.         ''' ----------------------------------------------------------------------------------------------------
  578.         ''' <summary>
  579.         ''' Look under the ShellNew subkey.
  580.         ''' </summary>
  581.         ''' ----------------------------------------------------------------------------------------------------
  582.         Public Property ShellNewValue As String
  583.  
  584.         ''' ----------------------------------------------------------------------------------------------------
  585.         ''' <summary>
  586.         ''' Gets a template for DDE commands.
  587.         ''' </summary>
  588.         ''' ----------------------------------------------------------------------------------------------------
  589.         ''' <value>
  590.         ''' A template for DDE commands.
  591.         ''' </value>
  592.         ''' ----------------------------------------------------------------------------------------------------
  593.         Public Property DdeCommand As String
  594.  
  595.         ''' ----------------------------------------------------------------------------------------------------
  596.         ''' <summary>
  597.         ''' Gets the DDE command to use to create a process.
  598.         ''' </summary>
  599.         ''' ----------------------------------------------------------------------------------------------------
  600.         ''' <value>
  601.         ''' The DDE command to use to create a process.
  602.         ''' </value>
  603.         ''' ----------------------------------------------------------------------------------------------------
  604.         Public Property DdeIfExec As String
  605.  
  606.         ''' ----------------------------------------------------------------------------------------------------
  607.         ''' <summary>
  608.         ''' Gets the application name in a DDE broadcast.
  609.         ''' </summary>
  610.         ''' ----------------------------------------------------------------------------------------------------
  611.         ''' <value>
  612.         ''' The application name in a DDE broadcast.
  613.         ''' </value>
  614.         ''' ----------------------------------------------------------------------------------------------------
  615.         Public Property DdeApplication As String
  616.  
  617.         ''' ----------------------------------------------------------------------------------------------------
  618.         ''' <summary>
  619.         ''' Gets the topic name in a DDE broadcast.
  620.         ''' </summary>
  621.         ''' ----------------------------------------------------------------------------------------------------
  622.         ''' <value>
  623.         ''' The topic name in a DDE broadcast.
  624.         ''' </value>
  625.         ''' ----------------------------------------------------------------------------------------------------
  626.         Public Property DdeTopic As String
  627.  
  628.         ''' ----------------------------------------------------------------------------------------------------
  629.         ''' <summary>
  630.         ''' Corresponds to the InfoTip registry value.
  631.         ''' Gets an info tip for an item, or list of properties in the form of an IPropertyDescriptionList from which to create an info tip,
  632.         ''' such as when hovering the cursor over a file name.
  633.         ''' The list of properties can be parsed with PSGetPropertyDescriptionListFromString.
  634.         ''' </summary>
  635.         ''' ----------------------------------------------------------------------------------------------------
  636.         Public Property InfoTip As String
  637.  
  638.         ''' ----------------------------------------------------------------------------------------------------
  639.         ''' <summary>
  640.         ''' Corresponds to the QuickTip registry value. Same as <see cref="FileAssocUtil.FileExtensionInfo.InfoTip"/>,
  641.         ''' except that it always returns a list of property names in the form of an IPropertyDescriptionList.
  642.         ''' The difference between this value and <see cref="FileAssocUtil.FileExtensionInfo.InfoTip"/> is that this returns properties that are
  643.         ''' safe for any scenario that causes slow property retrieval, such as offline or slow networks.
  644.         ''' Some of the properties returned from <see cref="FileAssocUtil.FileExtensionInfo.InfoTip"/> might not be appropriate for slow property retrieval scenarios.
  645.         ''' The list of properties can be parsed with PSGetPropertyDescriptionListFromString.
  646.         ''' </summary>
  647.         ''' ----------------------------------------------------------------------------------------------------
  648.         Public Property QuickTip As String
  649.  
  650.         ''' ----------------------------------------------------------------------------------------------------
  651.         ''' <summary>
  652.         ''' Corresponds to the TileInfo registry value.
  653.         ''' Contains a list of properties to be displayed for a particular file type in a Windows Explorer window that is in tile view.
  654.         ''' This is the same as <see cref="FileAssocUtil.FileExtensionInfo.InfoTip"/>, but, like <see cref="FileAssocUtil.FileExtensionInfo.QuickTip"/>, it also returns a list of property names in the
  655.         ''' form of an IPropertyDescriptionList.
  656.         ''' The list of properties can be parsed with PSGetPropertyDescriptionListFromString
  657.         ''' </summary>
  658.         ''' ----------------------------------------------------------------------------------------------------
  659.         Public Property TileInfo As String
  660.  
  661.         ''' ----------------------------------------------------------------------------------------------------
  662.         ''' <summary>
  663.         ''' Gets a general type of MIME file association, such as 'image' and 'bmp',
  664.         ''' so that applications can make general assumptions about a specific file type.
  665.         ''' </summary>
  666.         ''' ----------------------------------------------------------------------------------------------------
  667.         ''' <value>
  668.         ''' A general type of MIME file association, such as 'image' and 'bmp'.
  669.         ''' </value>
  670.         ''' ----------------------------------------------------------------------------------------------------
  671.         Public Property ContentType As String
  672.  
  673.         ''' ----------------------------------------------------------------------------------------------------
  674.         ''' <summary>
  675.         ''' Gets the path to the icon resources to use by default for this association.
  676.         ''' Positive numbers indicate an index into the dll's resource table, while negative numbers indicate a resource ID.
  677.         ''' An example of the syntax for the resource is "c:\myfolder\myfile.dll,-1".
  678.         ''' </summary>
  679.         ''' ----------------------------------------------------------------------------------------------------
  680.         ''' <value>
  681.         ''' A command string associated with a Shell verb.
  682.         ''' </value>
  683.         ''' ----------------------------------------------------------------------------------------------------
  684.         Public Property DefaultIcon As String
  685.  
  686.         ''' ----------------------------------------------------------------------------------------------------
  687.         ''' <summary>
  688.         ''' For an object that has a Shell extension associated with it, you can use this to retrieve the CLSID of that Shell extension object.
  689.         ''' </summary>
  690.         ''' ----------------------------------------------------------------------------------------------------
  691.         ''' <value>
  692.         ''' The CLSID of the associated Shell extension object.
  693.         ''' </value>
  694.         ''' ----------------------------------------------------------------------------------------------------
  695.         Public Property ShellExtension As String
  696.  
  697.         ''' ----------------------------------------------------------------------------------------------------
  698.         ''' <summary>
  699.         ''' For a verb invoked through COM and the IDropTarget interface, you can use this flag to retrieve the IDropTarget object's CLSID.
  700.         ''' This CLSID is registered in the DropTarget subkey. The verb is specified in the pwszExtra parameter in the call to IQueryAssociations::GetString.
  701.         ''' </summary>
  702.         ''' ----------------------------------------------------------------------------------------------------
  703.         ''' <value>
  704.         ''' The CLSID of the associated IDropTarget object.
  705.         ''' </value>
  706.         ''' ----------------------------------------------------------------------------------------------------
  707.         Public Property DropTarget As String
  708.  
  709.         ''' ----------------------------------------------------------------------------------------------------
  710.         ''' <summary>
  711.         ''' For a verb invoked through COM and the IExecuteCommand interface, you can use this flag to retrieve the IExecuteCommand object's CLSID.
  712.         ''' This CLSID is registered in the verb's command subkey as the DelegateExecute entry.
  713.         ''' The verb is specified in the pwszExtra parameter in the call to IQueryAssociations::GetString.
  714.         ''' </summary>
  715.         ''' ----------------------------------------------------------------------------------------------------
  716.         ''' <value>
  717.         ''' The CLSID of the associated IExecuteCommand object.
  718.         ''' </value>
  719.         ''' ----------------------------------------------------------------------------------------------------
  720.         Public Property DelegateExecute As String
  721.  
  722.         ''' ----------------------------------------------------------------------------------------------------
  723.         ''' <summary>
  724.         ''' (Introduced in Windows 8)
  725.         ''' There is no official documentation for this member.
  726.         ''' </summary>
  727.         ''' ----------------------------------------------------------------------------------------------------
  728.         Public Property SupportedUriProtocols As String
  729.  
  730.         ''' ----------------------------------------------------------------------------------------------------
  731.         ''' <summary>
  732.         ''' The maximum defined <see cref="FileAssocUtil.NativeMethods.AssocStr"/> value, used for validation purposes.
  733.         ''' </summary>
  734.         ''' ----------------------------------------------------------------------------------------------------
  735.         <EditorBrowsable(EditorBrowsableState.Never)>
  736.         Public Property Max As String
  737.  
  738. #End Region
  739.  
  740. #Region " Constructors "
  741.  
  742.         ''' ----------------------------------------------------------------------------------------------------
  743.         ''' <summary>
  744.         ''' Prevents a default instance of the <see cref="FileExtensionInfo"/> class from being created.
  745.         ''' </summary>
  746.         ''' ----------------------------------------------------------------------------------------------------
  747.         Private Sub New()
  748.         End Sub
  749.  
  750.         ''' ----------------------------------------------------------------------------------------------------
  751.         ''' <summary>
  752.         ''' Initializes a new instance of the <see cref="FileExtensionInfo"/> class.
  753.         ''' </summary>
  754.         ''' ----------------------------------------------------------------------------------------------------
  755.         ''' <param name="extensionName">
  756.         ''' The name of the file extension.
  757.         ''' </param>
  758.         ''' ----------------------------------------------------------------------------------------------------
  759.         Public Sub New(ByVal extensionName As String)
  760.  
  761.             Me.nameB = extensionName.TrimStart({"."c}).ToLower ' Remove extension dot and fix letter casing.
  762.  
  763.         End Sub
  764.  
  765. #End Region
  766.  
  767.     End Class
  768.  
  769. #End Region
  770.  
  771. #Region " Enumerations "
  772.  
  773.     ''' <summary>
  774.     ''' Specified a registry user (root key).
  775.     ''' </summary>
  776.     Public Enum RegistryUser As Integer
  777.  
  778.         ''' <summary>
  779.         ''' This reffers to the commonly known "HKLM" or "HKEY_LOCAL_MACHINE" registry root key.
  780.         ''' Changes made on this registry root key will affect all users.
  781.         ''' </summary>
  782.         Machine = 0
  783.  
  784.         ''' <summary>
  785.         ''' Current User, this reffers to the commonly known "HKCU" or "HKEY_CURRENT_USER" registry root key.
  786.         ''' Changes made on this registry root key will affect the current user.
  787.         ''' </summary>
  788.         CurrentUser = 1
  789.  
  790.     End Enum
  791.  
  792. #End Region
  793.  
  794. #Region " Constructors "
  795.  
  796.     ''' ----------------------------------------------------------------------------------------------------
  797.     ''' <summary>
  798.     ''' Prevents a default instance of the <see cref="FileAssocUtil"/> class from being created.
  799.     ''' </summary>
  800.     ''' ----------------------------------------------------------------------------------------------------
  801.     Private Sub New()
  802.     End Sub
  803.  
  804. #End Region
  805.  
  806. #Region " Public Methods "
  807.  
  808.     ''' ----------------------------------------------------------------------------------------------------
  809.     ''' <remarks>
  810.     ''' Title : Get file extension info.
  811.     ''' Author: Elektro
  812.     ''' Date  : 21-June-2015
  813.     ''' </remarks>
  814.     ''' ----------------------------------------------------------------------------------------------------
  815.     ''' <example>
  816.     ''' Dim feInfo As FileAssocUtil.FileExtensionInfo = FileAssocUtil.GetFileExtensionInfo(".wav")
  817.     '''
  818.     ''' Dim sb As New StringBuilder
  819.     ''' With sb
  820.     '''     .AppendLine(String.Format("Extension Name: {0}", feInfo.Name))
  821.     '''     .AppendLine(String.Format("Friendly Doc Name: {0}", feInfo.FriendlyDocName))
  822.     '''     .AppendLine(String.Format("Content Type: {0}", feInfo.ContentType))
  823.     '''     .AppendLine(String.Format("Default Icon: {0}", feInfo.DefaultIcon))
  824.     '''     .AppendLine("-----------------------------------------------------------")
  825.     '''     .AppendLine(String.Format("Friendly App Name: {0}", feInfo.FriendlyAppName))
  826.     '''     .AppendLine(String.Format("Executable: {0}", feInfo.Executable))
  827.     '''     .AppendLine(String.Format("Command: {0}", feInfo.Command))
  828.     '''     .AppendLine("-----------------------------------------------------------")
  829.     '''     .AppendLine(String.Format("Drop Target: {0}", feInfo.DropTarget))
  830.     '''     .AppendLine(String.Format("Info Tip: {0}", feInfo.InfoTip))
  831.     '''     .AppendLine(String.Format("No Open: {0}", feInfo.NoOpen))
  832.     '''     .AppendLine(String.Format("Shell Extension: {0}", feInfo.ShellExtension))
  833.     '''     .AppendLine(String.Format("Shell New Value: {0}", feInfo.ShellNewValue))
  834.     '''     .AppendLine("-----------------------------------------------------------")
  835.     '''     .AppendLine(String.Format("Supported URI Protocols: {0}", feInfo.SupportedUriProtocols))
  836.     '''     .AppendLine(String.Format("DDE Application: {0}", feInfo.DdeApplication))
  837.     '''     .AppendLine(String.Format("DDE Command: {0}", feInfo.DdeCommand))
  838.     '''     .AppendLine(String.Format("DDE If Exec: {0}", feInfo.DdeIfExec))
  839.     '''     .AppendLine(String.Format("DDE Topic: {0}", feInfo.DdeTopic))
  840.     ''' End With
  841.     '''
  842.     ''' MessageBox.Show(sb.ToString, "", MessageBoxButtons.OK, MessageBoxIcon.Information)
  843.     ''' </example>
  844.     ''' ----------------------------------------------------------------------------------------------------
  845.     ''' <summary>
  846.     ''' Gets the system information of the specified file extension.
  847.     ''' </summary>
  848.     ''' ----------------------------------------------------------------------------------------------------
  849.     ''' <param name="extensionName">
  850.     ''' The extension name (eg: .txt).
  851.     ''' </param>
  852.     ''' ----------------------------------------------------------------------------------------------------
  853.     ''' <returns>
  854.     ''' A <see cref="FileAssocUtil.FileExtensionInfo"/> object that contains the file extension info.
  855.     ''' </returns>
  856.     ''' ----------------------------------------------------------------------------------------------------
  857.     <DebuggerStepThrough>
  858.     Public Shared Function GetFileExtensionInfo(ByVal extensionName As String) As FileExtensionInfo
  859.  
  860.         ' Fix extension dot.
  861.         extensionName = extensionName.TrimStart({"."c}).Insert(0, "."c)
  862.  
  863.         Dim feInfo As New FileExtensionInfo(extensionName)
  864.         Dim sb As New StringBuilder
  865.         Dim pcchout As UInteger
  866.  
  867.         pcchout = 0UI
  868.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.Command, extensionName, Nothing, Nothing, pcchout)
  869.         sb.Capacity = CInt(pcchout)
  870.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.Command, extensionName, Nothing, sb, pcchout)
  871.         feInfo.Command = sb.ToString()
  872.         sb.Clear()
  873.  
  874.         pcchout = 0UI
  875.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.ContentType, extensionName, Nothing, Nothing, pcchout)
  876.         sb.Capacity = CInt(pcchout)
  877.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.ContentType, extensionName, Nothing, sb, pcchout)
  878.         feInfo.ContentType = sb.ToString()
  879.         sb.Clear()
  880.  
  881.         pcchout = 0UI
  882.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DdeApplication, extensionName, Nothing, Nothing, pcchout)
  883.         sb.Capacity = CInt(pcchout)
  884.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DdeApplication, extensionName, Nothing, sb, pcchout)
  885.         feInfo.DdeApplication = sb.ToString()
  886.         sb.Clear()
  887.  
  888.         pcchout = 0UI
  889.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DdeCommand, extensionName, Nothing, Nothing, pcchout)
  890.         sb.Capacity = CInt(pcchout)
  891.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DdeCommand, extensionName, Nothing, sb, pcchout)
  892.         feInfo.DdeCommand = sb.ToString()
  893.         sb.Clear()
  894.  
  895.         pcchout = 0UI
  896.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DdeIfExec, extensionName, Nothing, Nothing, pcchout)
  897.         sb.Capacity = CInt(pcchout)
  898.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DdeIfExec, extensionName, Nothing, sb, pcchout)
  899.         feInfo.DdeIfExec = sb.ToString()
  900.         sb.Clear()
  901.  
  902.         pcchout = 0UI
  903.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DdeTopic, extensionName, Nothing, Nothing, pcchout)
  904.         sb.Capacity = CInt(pcchout)
  905.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DdeTopic, extensionName, Nothing, sb, pcchout)
  906.         feInfo.DdeTopic = sb.ToString()
  907.         sb.Clear()
  908.  
  909.         pcchout = 0UI
  910.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DefaultIcon, extensionName, Nothing, Nothing, pcchout)
  911.         sb.Capacity = CInt(pcchout)
  912.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DefaultIcon, extensionName, Nothing, sb, pcchout)
  913.         feInfo.DefaultIcon = sb.ToString()
  914.         sb.Clear()
  915.  
  916.         pcchout = 0UI
  917.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DelegateExecute, extensionName, Nothing, Nothing, pcchout)
  918.         sb.Capacity = CInt(pcchout)
  919.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DelegateExecute, extensionName, Nothing, sb, pcchout)
  920.         feInfo.DelegateExecute = sb.ToString()
  921.         sb.Clear()
  922.  
  923.         pcchout = 0UI
  924.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DropTarget, extensionName, Nothing, Nothing, pcchout)
  925.         sb.Capacity = CInt(pcchout)
  926.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DropTarget, extensionName, Nothing, sb, pcchout)
  927.         feInfo.DropTarget = sb.ToString()
  928.         sb.Clear()
  929.  
  930.         pcchout = 0UI
  931.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.Executable, extensionName, Nothing, Nothing, pcchout)
  932.         sb.Capacity = CInt(pcchout)
  933.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.Executable, extensionName, Nothing, sb, pcchout)
  934.         feInfo.Executable = sb.ToString()
  935.         sb.Clear()
  936.  
  937.         pcchout = 0UI
  938.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.FriendlyAppName, extensionName, Nothing, Nothing, pcchout)
  939.         sb.Capacity = CInt(pcchout)
  940.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.FriendlyAppName, extensionName, Nothing, sb, pcchout)
  941.         feInfo.FriendlyAppName = sb.ToString()
  942.         sb.Clear()
  943.  
  944.         pcchout = 0UI
  945.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.FriendlyDocName, extensionName, Nothing, Nothing, pcchout)
  946.         sb.Capacity = CInt(pcchout)
  947.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.FriendlyDocName, extensionName, Nothing, sb, pcchout)
  948.         feInfo.FriendlyDocName = sb.ToString()
  949.         sb.Clear()
  950.  
  951.         pcchout = 0UI
  952.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.InfoTip, extensionName, Nothing, Nothing, pcchout)
  953.         sb.Capacity = CInt(pcchout)
  954.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.InfoTip, extensionName, Nothing, sb, pcchout)
  955.         feInfo.InfoTip = sb.ToString()
  956.         sb.Clear()
  957.  
  958.         pcchout = 0UI
  959.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.Max, extensionName, Nothing, Nothing, pcchout)
  960.         sb.Capacity = CInt(pcchout)
  961.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.Max, extensionName, Nothing, sb, pcchout)
  962.         feInfo.Max = sb.ToString()
  963.         sb.Clear()
  964.  
  965.         pcchout = 0UI
  966.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.NoOpen, extensionName, Nothing, Nothing, pcchout)
  967.         sb.Capacity = CInt(pcchout)
  968.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.NoOpen, extensionName, Nothing, sb, pcchout)
  969.         feInfo.NoOpen = sb.ToString()
  970.         sb.Clear()
  971.  
  972.         pcchout = 0UI
  973.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.QuickTip, extensionName, Nothing, Nothing, pcchout)
  974.         sb.Capacity = CInt(pcchout)
  975.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.QuickTip, extensionName, Nothing, sb, pcchout)
  976.         feInfo.QuickTip = sb.ToString()
  977.         sb.Clear()
  978.  
  979.         pcchout = 0UI
  980.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.ShellExtension, extensionName, Nothing, Nothing, pcchout)
  981.         sb.Capacity = CInt(pcchout)
  982.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.ShellExtension, extensionName, Nothing, sb, pcchout)
  983.         feInfo.ShellExtension = sb.ToString()
  984.         sb.Clear()
  985.  
  986.         pcchout = 0UI
  987.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.ShellNewValue, extensionName, Nothing, Nothing, pcchout)
  988.         sb.Capacity = CInt(pcchout)
  989.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.ShellNewValue, extensionName, Nothing, sb, pcchout)
  990.         feInfo.ShellNewValue = sb.ToString()
  991.         sb.Clear()
  992.  
  993.         pcchout = 0UI
  994.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.SupportedUriProtocols, extensionName, Nothing, Nothing, pcchout)
  995.         sb.Capacity = CInt(pcchout)
  996.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.SupportedUriProtocols, extensionName, Nothing, sb, pcchout)
  997.         feInfo.SupportedUriProtocols = sb.ToString()
  998.         sb.Clear()
  999.  
  1000.         pcchout = 0UI
  1001.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.TileInfo, extensionName, Nothing, Nothing, pcchout)
  1002.         sb.Capacity = CInt(pcchout)
  1003.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.TileInfo, extensionName, Nothing, sb, pcchout)
  1004.         feInfo.TileInfo = sb.ToString()
  1005.         sb.Clear()
  1006.  
  1007.         Return feInfo
  1008.  
  1009.     End Function
  1010.  
  1011.     ''' ----------------------------------------------------------------------------------------------------
  1012.     ''' <remarks>
  1013.     ''' Title : File extension is registered?.
  1014.     ''' Author: Elektro
  1015.     ''' Date  : 21-June-2015
  1016.     ''' </remarks>
  1017.     ''' ----------------------------------------------------------------------------------------------------
  1018.     ''' <example>
  1019.     ''' Dim isRegistered As Boolean = FileAssocUtil.IsRegistered(".ext")
  1020.     ''' </example>
  1021.     ''' ----------------------------------------------------------------------------------------------------
  1022.     ''' <summary>
  1023.     ''' Determines whether the specified file extension is registered in the current system.
  1024.     ''' </summary>
  1025.     ''' ----------------------------------------------------------------------------------------------------
  1026.     ''' <param name="extensionName">
  1027.     ''' The extension name (eg: .txt).
  1028.     ''' </param>
  1029.     ''' ----------------------------------------------------------------------------------------------------
  1030.     ''' <returns>
  1031.     ''' <c>True</c> if the file extension is registered, otherwise, <c>False</c>.
  1032.     ''' </returns>
  1033.     ''' ----------------------------------------------------------------------------------------------------
  1034.     <DebuggerStepThrough>
  1035.     Public Shared Function IsRegistered(ByVal extensionName As String) As Boolean
  1036.  
  1037.         ' Fix extension dot.
  1038.         extensionName = extensionName.TrimStart({"."c}).Insert(0, "."c)
  1039.  
  1040.         Dim sb As New StringBuilder
  1041.         Dim pcchout As UInteger = 0UI
  1042.  
  1043.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DdeApplication, extensionName, Nothing, Nothing, pcchout)
  1044.         sb.Capacity = CInt(pcchout)
  1045.         NativeMethods.AssocQueryString(NativeMethods.AssocF.Verify, NativeMethods.AssocStr.DdeApplication, extensionName, Nothing, sb, pcchout)
  1046.         Return Not sb.ToString().Equals("OpenWith", StringComparison.OrdinalIgnoreCase)
  1047.  
  1048.     End Function
  1049.  
  1050.     ''' ----------------------------------------------------------------------------------------------------
  1051.     ''' <remarks>
  1052.     ''' Title : Register file extension.
  1053.     ''' Author: Elektro
  1054.     ''' Date  : 22-June-2015
  1055.     ''' </remarks>
  1056.     ''' ----------------------------------------------------------------------------------------------------
  1057.     ''' <example>
  1058.     ''' FileAssocUtil.Register(regUser:=FileAssocUtil.RegistryUser.CurrentUser,
  1059.     '''                        extensionName:=".elek",
  1060.     '''                        keyReferenceName:="ElektroFile",
  1061.     '''                        friendlyName:="Elektro File",
  1062.     '''                        defaultIcon:="%WinDir%\System32\Shell32.ico",
  1063.     '''                        iconIndex:=0,
  1064.     '''                        executable:="%WinDir%\notepad.exe",
  1065.     '''                        arguments:="""%1""")
  1066.     ''' </example>
  1067.     ''' ----------------------------------------------------------------------------------------------------
  1068.     ''' <summary>
  1069.     ''' Registers or modifies a file extension in the current system.
  1070.     ''' </summary>
  1071.     ''' ----------------------------------------------------------------------------------------------------
  1072.     ''' <param name="regUser">
  1073.     ''' The registry user that will owns the file association.
  1074.     ''' </param>
  1075.     '''
  1076.     ''' <param name="extensionName">
  1077.     ''' The extension name (eg: .txt).
  1078.     ''' </param>
  1079.     '''
  1080.     ''' <param name="keyReferenceName">
  1081.     ''' The name of the registry key to reference.
  1082.     ''' </param>
  1083.     '''
  1084.     ''' <param name="friendlyName">
  1085.     ''' The friendly name for this file extension (visible in Windows Esplorer).
  1086.     ''' </param>
  1087.     '''
  1088.     ''' <param name="defaultIcon">
  1089.     ''' The icon filepath.
  1090.     ''' </param>
  1091.     '''
  1092.     ''' <param name="iconIndex">
  1093.     ''' The index image of the icon resource.
  1094.     ''' </param>
  1095.     '''
  1096.     ''' <param name="executable">
  1097.     ''' The executable path that will open the file.
  1098.     ''' </param>
  1099.     '''
  1100.     ''' <param name="arguments">
  1101.     ''' The executable arguments,
  1102.     ''' normally this value is set as '"%1"' to take the filepath as the only one argument,
  1103.     ''' or '"%1" %*' to take the filepath as first argument and additional arguments.
  1104.     ''' </param>
  1105.     ''' ----------------------------------------------------------------------------------------------------
  1106.     ''' <exception cref="ArgumentException">
  1107.     ''' Invalid enumeration value.;regUser
  1108.     ''' </exception>
  1109.     ''' ----------------------------------------------------------------------------------------------------
  1110.     <DebuggerStepThrough>
  1111.     Public Shared Sub Register(ByVal regUser As FileAssocUtil.RegistryUser,
  1112.                                ByVal extensionName As String,
  1113.                                ByVal keyReferenceName As String,
  1114.                                Optional ByVal friendlyName As String = "",
  1115.                                Optional ByVal defaultIcon As String = "%WinDir%\System32\shell32.dll",
  1116.                                Optional ByVal iconIndex As Integer = 0,
  1117.                                Optional ByVal executable As String = "%WinDir%\System32\OpenWith.exe",
  1118.                                Optional ByVal arguments As String = """%1""")
  1119.  
  1120.         Dim regKey As RegistryKey
  1121.  
  1122.         Select Case regUser
  1123.  
  1124.             Case RegistryUser.Machine
  1125.                 regKey = Registry.LocalMachine
  1126.  
  1127.             Case RegistryUser.CurrentUser
  1128.                 regKey = Registry.CurrentUser
  1129.  
  1130.             Case Else
  1131.                 Throw New ArgumentException(message:="Invalid enumeration value.", paramName:="regUser")
  1132.  
  1133.         End Select
  1134.  
  1135.         ' Fix extension dot.
  1136.         extensionName = extensionName.TrimStart({"."c}).Insert(0, "."c)
  1137.  
  1138.         Using regKey
  1139.  
  1140.             ' Create sub-key 'HKxx\Software\Classes'
  1141.             regKey.CreateSubKey("Software\Classes")
  1142.  
  1143.             ' Create sub-key 'HKxx\Software\Classes\{.ext}'
  1144.             regKey.OpenSubKey("Software\Classes", writable:=True).
  1145.                    CreateSubKey(extensionName)
  1146.  
  1147.             ' Set value data 'HKxx\Software\Classes\{.ext}\@Default={keyReferenceName}'
  1148.             regKey.OpenSubKey(String.Format("Software\Classes\{0}", extensionName), writable:=True).
  1149.                    SetValue("", keyReferenceName, RegistryValueKind.String)
  1150.  
  1151.             ' Create sub-key 'HKxx\Software\Classes\{KeyRefrenceName}'.
  1152.             regKey.OpenSubKey("Software\Classes", writable:=True).
  1153.                    CreateSubKey(keyReferenceName)
  1154.  
  1155.             ' Set value data 'HKxx\Software\Classes\{KeyRefrenceName}\@Default={friendlyName}'
  1156.             regKey.OpenSubKey(String.Format("Software\Classes\{0}", keyReferenceName), writable:=True).
  1157.                    SetValue("", friendlyName, RegistryValueKind.String)
  1158.  
  1159.             ' Create sub-key 'HKxx\Software\Classes\{KeyRefrenceName}\DefaultIcon'.
  1160.             regKey.OpenSubKey(String.Format("Software\Classes\{0}", keyReferenceName), writable:=True).
  1161.                    CreateSubKey("DefaultIcon")
  1162.  
  1163.             ' Set value data 'HKxx\Software\Classes\{KeyRefrenceName}\DefaultIcon\@Default={defaultIcon},{iconIndex}'.
  1164.             regKey.OpenSubKey(String.Format("Software\Classes\{0}\DefaultIcon", keyReferenceName), writable:=True).
  1165.                    SetValue("", Environment.ExpandEnvironmentVariables(String.Format("""{0}"",{1}", defaultIcon, CStr(iconIndex))), RegistryValueKind.String)
  1166.  
  1167.             ' Create sub-key 'HKxx\Software\Classes\{KeyRefrenceName}\Shell\Open\Command'.
  1168.             regKey.OpenSubKey(String.Format("Software\Classes\{0}", keyReferenceName), writable:=True).
  1169.                    CreateSubKey("Shell\Open\Command")
  1170.  
  1171.             ' Set value data 'HKxx\Software\Classes\{KeyRefrenceName}\Shell\Open\Command\@Default={executable} {arguments}'.
  1172.             regKey.OpenSubKey(String.Format("Software\Classes\{0}\Shell\Open\Command", keyReferenceName), writable:=True).
  1173.                    SetValue("", Environment.ExpandEnvironmentVariables(String.Format("""{0}"" {1}", executable, arguments)), RegistryValueKind.String)
  1174.  
  1175.             ' Delete the system 'OpenWith' override.
  1176.             regKey.DeleteSubKeyTree(String.Format("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\{0}\OpenWithProgIds", extensionName), throwOnMissingSubKey:=False)
  1177.             regKey.DeleteSubKeyTree(String.Format("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\{0}\UserChoice", extensionName), throwOnMissingSubKey:=False)
  1178.  
  1179.             ' Set the ProgId.
  1180.             regKey.CreateSubKey(String.Format("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\{0}\UserChoice", extensionName)).
  1181.                    SetValue("ProgId", keyReferenceName, RegistryValueKind.String)
  1182.  
  1183.             regKey.CreateSubKey(String.Format("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\{0}\OpenWithProgids", extensionName)).
  1184.                    SetValue(keyReferenceName, New Byte() {}, RegistryValueKind.None)
  1185.  
  1186.             regKey.CreateSubKey(String.Format("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\{0}\OpenWithList", extensionName)).
  1187.                    SetValue("MRUList", "a", RegistryValueKind.String)
  1188.  
  1189.             regKey.CreateSubKey(String.Format("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\{0}\OpenWithList", extensionName)).
  1190.                    SetValue("a", Path.GetFileName(executable), RegistryValueKind.String)
  1191.  
  1192.             ' Notify the system that a file association has been added/changed to update the changes (on Windows Explorer).
  1193.             NativeMethods.SHChangeNotify(FileAssocUtil.NativeMethods.HChangeNotifyEventID.AssocChanged,
  1194.                                          FileAssocUtil.NativeMethods.HChangeNotifyFlags.IdList,
  1195.                                          dwItem1:=IntPtr.Zero, dwItem2:=IntPtr.Zero)
  1196.  
  1197.         End Using
  1198.  
  1199.     End Sub
  1200.  
  1201. #End Region
  1202.  
  1203. #Region " Private Methods "
  1204.  
  1205.     ' THIS MEMBER IS COMMENTED OUT BBECAUSE IS NOT NEEDED TO USE IT, BY THE MOMENT.
  1206.  
  1207.     ' ''' ----------------------------------------------------------------------------------------------------
  1208.     ' ''' <remarks>
  1209.     ' ''' Title : SafePInvoke
  1210.     ' ''' Author: Elektro
  1211.     ' ''' Date  : 17-June-2015
  1212.     ' ''' </remarks>
  1213.     ' ''' ----------------------------------------------------------------------------------------------------
  1214.     ' ''' <summary>
  1215.     ' ''' Invokes the specified encapsulated function, trying to provide a higher safety level for error-handling.
  1216.     ' ''' If the function that was called using platform invoke has the <see cref="DllImportAttribute.SetLastError"/>,
  1217.     ' ''' then it checks the exit code returned by the function, and, if is not a success code, throws a <see cref="Win32Exception"/>.
  1218.     ' '''
  1219.     ' ''' Note that each function that sets the last-error code notes the conditions under which the function sets the last-error code,
  1220.     ' ''' this means that some functions set the last-error code to '0' on success and others do not.
  1221.     ' ''' </summary>
  1222.     ' ''' ----------------------------------------------------------------------------------------------------
  1223.     ' ''' <typeparam name="T"></typeparam>
  1224.     ' '''
  1225.     ' ''' <param name="expr">
  1226.     ' ''' The encapsulated function.
  1227.     ' ''' </param>
  1228.     ' ''' ----------------------------------------------------------------------------------------------------
  1229.     ' ''' <returns>
  1230.     ' ''' The type of the return value depends on the function definition.
  1231.     ' ''' </returns>
  1232.     ' ''' ----------------------------------------------------------------------------------------------------
  1233.     ' ''' <exception cref="Win32Exception">
  1234.     ' ''' </exception>
  1235.     ' ''' ----------------------------------------------------------------------------------------------------
  1236.     '<DebuggerStepThrough>
  1237.     'Private Shared Function SafePInvoke(Of T)(ByVal expr As Expression(Of Func(Of T)),
  1238.     '                                          Optional ByVal successCode As Integer = 0) As T
  1239.     '
  1240.     '    Dim result As T = expr.Compile.Invoke()
  1241.     '
  1242.     '    Dim method As MethodInfo =
  1243.     '        CType(expr.Body, MethodCallExpression).Method
  1244.     '
  1245.     '    Dim isSetLastError As Boolean =
  1246.     '        method.GetCustomAttributes(inherit:=False).
  1247.     '               OfType(Of DllImportAttribute)().FirstOrDefault.SetLastError
  1248.     '
  1249.     '    If isSetLastError Then
  1250.     '
  1251.     '        Dim exitCode As Integer = Marshal.GetLastWin32Error
  1252.     '
  1253.     '        If (exitCode <> successCode) Then
  1254.     '            Throw New Win32Exception([error]:=exitCode)
  1255.     '        End If
  1256.     '
  1257.     '    End If
  1258.     '
  1259.     '    Return result
  1260.     '
  1261.     'End Function
  1262.  
  1263. #End Region
  1264.  
  1265. End Class
  1266.  
  1267. #End Region
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement