Advertisement
Guest User

FileAssocUti.vb - By Elektro

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