Exercise 1: Developing the SLUtil

The Shell Library Utility (SLUtil) is a command line tool that enables you to manage libraries under the default library directory.

The SLUtil commands are:

SLUtil Create LibraryName
SLUtil Delete LibraryName
SLUtil Rename OldName NewName
SLUtil AddFolder LibraryName FolderPath
SLUtil RemoveFolder LibraryName FolderPath
SLUtil ShowInfo [LibraryName]
SLUtil FolderType LibraryName [Documents|Pictures|Music|Videos]
SLUtil SaveFolder LibraryName [FolderPath]
SLUtil NavPanePinnedState LibraryName [TRUE|FALSE]
SLUtil Icon LibraryName [Icon]
SLUtil ManageUI Videos
SLUtil ? [CommandName]

Task 1 – Creating the SLUtil Project

  1. Start Visual Studio 2008 and select the Console Application project template, choosing the language of your preference (Visual C# or Visual Basic). Enter SLUtil as the name of the new project.
  2. Add a reference to the Microsoft.WindowsApiCodePack.dll and Microsoft.WindowsApiCodePack.shell.dll. You can find those assemblies under the Asset folder of this lab.
  3. (For C# users only) Also add references to the following assemblies:
    • PresentationCore
    • PresentationFramework
    • WindowsBase
    • System.Windows.Forms
  4. Add the CommandLineInterpreter.cs (C#) or CommandLineInterpreter.vb (Visual Basic) file. You can find it under Asset\SLUtil folder, choosing the language of your preference.

    Note:
    The Command Line Interpreter is a utility class that knows how to interpret command line arguments and execute static methods that include the CommandAttribute attribute.

  5. To activate the Command Line Interpreter, change the Main method to this code:

    (Code Snippet – Shell Libraries – Main CSharp)

    class Program
    {
    static int Main(string[] args)
    {
    CommandLineInterpreter cli = new CommandLineInterpreter(args);
    return cli.Execute();
    }
    }

    (Code Snippet – Shell Libraries – Main VB)

    Module Module1

    Function Main() As Integer
    Dim cli As New CommandLineInterpreter(My.Application.CommandLineArgs.ToArray())
    Return cli.Execute()
    End Function

    End Module

  6. Compile the solution.
  7. To test the current state of the application, add a command line argument in the Debug pane of the project properties.

    Figure 2

    Adding a command line argument

  8. Execute the application by pressing CTRL+F5. You should get the following output:SLUtil ? [CommandName]
    Press any key to continue . . .

Task 2 – Adding the Create Command

The Windows API Pack ShellLibrary managed wrapper has several constructors that let you create new libraries:

// Summary:
// Creates a shell library in the Libraries Known Folder,
// using the given IKnownFolder
//
// Parameters:
// kf: KnownFolder from which to create the new Shell Library
// isReadOnly:
public ShellLibrary(IKnownFolder kf, bool isReadOnly);

//
// Summary:
// Creates a shell library in the Libraries Known Folder,
// using the given shell library name.
//
// Parameters:
// libraryName: The name of this library
// overwrite: Override an existing library with the same name
public ShellLibrary(string libraryName, bool overwrite);

// Summary:
// Creates a shell library in a given Known Folder, using the given shell
// library name.
// Parameters:
// libraryName: The name of this library
// kf: The known folder
// overwrite: Override an existing library with the same name
public ShellLibrary(string libraryName, IKnownFolder kf, bool overwrite);

// Summary:
// Creates a shell library in a given local folder, using the given shell
// library name.
// Parameters:
// libraryName: The name of this library
// folderPath: The path to the local folder
// overwrite: Override an existing library with the same name
public ShellLibrary(string libraryName, string folderPath, bool overwrite);' Summary:
' Creates a shell library in the Libraries Known Folder,
' using the given IKnownFolder
'
' Parameters:
' kf: KnownFolder from which to create the new Shell Library
' isReadOnly:
Public Sub New(ByVal kf As Microsoft.WindowsAPICodePack.Shell.IKnownFolder, ByVal isReadOnly As Boolean)

' Summary:
' Creates a shell library in the Libraries Known Folder,
' using the given shell library name.
'
' Parameters:
' libraryName: The name of this library
' overwrite: Override an existing library with the same name
Public Sub New(ByVal libraryName As String, ByVal overwrite As Boolean)

' Summary:
' Creates a shell library in a given Known Folder, using the given shell
' library name.
' Parameters:
' libraryName: The name of this library
' kf: The known folder
' overwrite: Override an existing library with the same name
Public Sub New(ByVal libraryName As String, ByVal kf As Microsoft.WindowsAPICodePack.Shell.IKnownFolder, ByVal overwrite As Boolean)

' Summary:
' Creates a shell library in a given local folder, using the given shell
' library name.
' Parameters:
' libraryName: The name of this library
' folderPath: The path to the local folder
' overwrite: Override an existing library with the same name
Public Sub New(ByVal libraryName As String, ByVal folderPath As String, ByVal overwrite As Boolean)

The ShellLibrary implements the IDispose interface. It is important to call the Dispose() function to free the underlying Shell Library COM object. Utilization of the using statement facilitates that Dispose call.

The pattern to use a library object is:

using (ShellLibrary library = new ShellLibray("Library Name", true))
{
//Use the library instance here
}Using library As New ShellLibray("Library Name", True)
'Use the lib instance here
End Using

  1. Create a Static class (C#) or a module (Visual Basic) named ShellCommands.
  2. Add the following namespace directive:using Microsoft.WindowsAPICodePack.Shell;Imports Microsoft.WindowsAPICodePack.Shell

  3. Create a new Command named Create. To do this, add the following code to ShellCommands:

    (Code Snippet – Shell Libraries – CreateCommand CSharp)

    [Command(
    Name = "Create",
    Usage = "SLUtil Create LibraryName",
    Info = "Create a new library",
    Example = "SLUtil Create MyLib")]
    public static void CreateLibrary(string name)
    {
    using (ShellLibrary library = new ShellLibrary(name, true))
    {
    }
    }

    (Code Snippet – Shell Libraries – CreateCommand VB)

    <Command(Name:="Create", Usage:="SLUtil Create LibraryName", Info:="Create a new library", Example:="SLUtil Create MyLib")> _
    Public Sub CreateLibrary(ByVal name As String)
    Using library As New ShellLibrary(name, True)
    End Using
    End Sub

  4. Compile the solution.
  5. Change the command line argument to: Create MyLib

    Figure 3

    Modifying the command line arguments

  6. Run the application by pressing CTRL+F5. Then open Windows Explorer to verify that you created a new library.

    Figure 4

    Creating my first library via Shell API

Task 3 – Adding the AddFolder and RemoveFolder Commands

  1. To use an existing library, we need to create a ShellLibrary instance by loading that library. The ShellLibrary provides two load methods:
    // Summary:
    // Load the library using a number of options
    // Parameters:
    // sourceKnownFolder: the Knowfolder
    // isReadOnly:
    // Returns: A ShellLibrary Object
    public static ShellLibrary Load(IKnownFolder sourceKnownFolder, bool isReadOnly);

    // Summary:
    // Load the library using a number of options
    // Returns: A ShellLibrary Object
    public static ShellLibrary Load(string libraryName, bool isReadOnly);

    // Summary:
    // Load the library using a number of options
    // Returns: A ShellLibrary Object
    public static ShellLibrary Load(string libraryName, string folderPath,
    bool isReadOnly);' Summary:
    ' Load the library using a number of options
    ' Parameters:
    ' sourceKnownFolder: the Knowfolder
    ' isReadOnly:
    ' Returns: A ShellLibrary Object
    Public Shared Function Load(ByVal sourceKnownFolder As Microsoft.WindowsAPICodePack.Shell.IKnownFolder, ByVal isReadOnly As Boolean) As Microsoft.WindowsAPICodePack.Shell.ShellLibrary

    ' Summary:
    ' Load the library using a number of options
    ' Returns: A ShellLibrary Object
    Public Shared Function Load(ByVal libraryName As String, ByVal isReadOnly As Boolean) As Microsoft.WindowsAPICodePack.Shell.ShellLibrary

    ' Summary:
    ' Load the library using a number of options
    ' Returns: A ShellLibrary Object
    Public Shared Function Load(ByVal libraryName As String, ByVal folderPath As String, ByVal isReadOnly As Boolean) As Microsoft.WindowsAPICodePack.Shell.ShellLibrary

  2. To add or remove a folder, you need to use two of these methods:// Summary:
    // Add a new FileSystemFolder or SearchConnector
    public void Add(FileSystemFolder item);
    //
    // Summary:
    // Add an existing folder to this library
    public void Add(string folderPath);

    // Summary:
    // Remove a folder or search connector
    public bool Remove(FileSystemFolder item);
    //
    // Summary:
    // Remove a folder or search connector
    public bool Remove(string folderPath);' Summary:
    ' Add a new FileSystemFolder or SearchConnector
    Public Sub Add(ByVal item As FileSystemFolder)
    '
    ' Summary:
    ' Add an existing folder to this library
    Public Sub Add(ByVal folderPath As String)
    ' Summary:
    ' Remove a folder or search connector
    Public Function Remove(ByVal item As FileSystemFolder) As Boolean
    '
    ' Summary:
    ' Remove a folder or search connector
    Public Function Remove(ByVal folderPath As String) As Boolean

  3. Now that we know how to open (load) an existing library, and how to add and remove folders, we can implement the AddFolder and RemoveFolder commands in our SLUtil application. Add the following code to ShellCommands:

    (Code Snippet – Shell Libraries – AddAndRemoveFolderCommands CSharp)

    [Command(
    Name = "AddFolder",
    Usage = "SLUtil AddFolder LibraryName FolderPath",
    Info = "Add a folder to a library",
    Example = @"SLUtil AddFolder Documents C:\Docs")]
    public static void AddFolder(string name, string folderPath)
    {
    using (ShellLibrary library = ShellLibrary.Load(name, false))
    {
    library.Add(folderPath);
    }
    }

    [Command(
    Name = "RemoveFolder",
    Usage = "SLUtil RemoveFolder LibraryName FolderPath",
    Info = "Remove a folder from a library",
    Example = @"SLUtil RemoveFolder Documents C:\Docs")]
    public static void RemoveFolder(string name, string folderPath)
    {
    using (ShellLibrary library = ShellLibrary.Load(name, false))
    {
    library.Remove(folderPath);
    }
    }

    (Code Snippet – Shell Libraries – AddAndRemoveFolderCommands VB)

    <Command(Name:="AddFolder", Usage:="SLUtil AddFolder LibraryName FolderPath", Info:="Add a folder to a library", Example:="SLUtil AddFolder Documents C:\Docs")> _
    Public Sub AddFolder(ByVal name As String, ByVal folderPath As String)
    Using library = ShellLibrary.Load(name, False)
    library.Add(folderPath)
    End Using
    End Sub

    <Command(Name:="RemoveFolder", Usage:="SLUtil RemoveFolder LibraryName FolderPath", Info:="Remove a folder from a library", Example:="SLUtil RemoveFolder Documents C:\Docs")> _
    Public Sub RemoveFolder(ByVal name As String, ByVal folderPath As String)
    Using library = ShellLibrary.Load(name, False)
    library.Remove(folderPath)
    End Using
    End Sub

  4. Build the solution (CTRL+SHIFT+B), and follow these steps to verify the result:
    1. Clear the command line arguments from the Debug pane of the project properties pages.
    2. Open a Command Prompt window and change the directory (cd) to the location of the SLUtil.exe (…\bin\debug\SLUtil.exe).
    3. Open the Libraries Shell Folder next to the Command Prompt Window, so you will be able to see the changes you make with the SLUtil tool.

      Figure 5

      Setting the environment to execute SLUtil.exe

    4. Execute the SLUtil from command line:SLUtil ?
      SLUtil Create NewLibrary
      SLUtil AddFolder NewLibrary C:\Users
      SLUtil RemoveFolder NewLibrary C:\Users

      Note:
      Since the interpreter finds the best match command, you can use “SLUtil Cr Lib” to create a library and “SLUtil Add Lib C:\” to add a folder. Try it.

Task 4 – Adding the Delete and Rename Commands

Deleting a library is not an operation of the IShellLibrary; it is a regular file system operation. However, for the purpose of completeness we will implement it. Renaming can be achieved by copying the library to a new library and deleting the old one. The ShellLibrary wrapper provides these methods:

// Summary:
// Creates a copy of a ShellLibrary, using a new name and known folder
public static ShellLibrary Copy(ShellLibrary library, string name,
IKnownFolder destinationKnownFolder, bool overrideExisting);

// Summary:
// Creates a copy of a ShellLibrary, using a new name and path
public static ShellLibrary Copy(ShellLibrary library, string name,
string path, bool overrideExisting);' Summary:
' Creates a copy of a ShellLibrary, using a new name and known folder
Public Shared Function Copy(ByVal library As ShellLibrary, ByVal name As String, ByVal destinationKnownFolder As IKnownFolder, ByVal overrideExisting As Boolean) As ShellLibrary

' Summary:
' Creates a copy of a ShellLibrary, using a new name and path
Public Shared Function Copy(ByVal library As ShellLibrary, ByVal name As String, ByVal path As String, ByVal overrideExisting As Boolean) As ShellLibrary

  1. Add the following namespace directive to ShellCommands.cs (C#) or ShellCommands.vb (Visual Basic).using System.IO;Imports System.IO

  2. Add the following code to ShellCommands:

    (Code Snippet –Shell Libraries – DeleteAndRenameLibraryCommands CSharp)

    [Command(
    Name = "Delete",
    Usage = "SLUtil Delete LibraryName",
    Info = "Delete a library",
    Example = "SLUtil Delete MyLib")]
    public static void DeleteLibrary(string name)
    {
    string librariesPath = Path.Combine(
    Environment.GetFolderPath(
    Environment.SpecialFolder.ApplicationData),
    ShellLibrary.LibrariesKnownFolder.RelativePath);

    string libraryPath = Path.Combine(librariesPath, name);
    string libraryFullPath = Path.ChangeExtension(libraryPath, "library-ms");

    File.Delete(libraryFullPath);
    }

    [Command(
    Name = "Rename",
    Usage = "SLUtil Rename OldName NewName",
    Info = "Rename a library",
    Example = "SLUtil Rename MyLib MyLibNewName")]
    public static void RenameLibrary(string oldName, string newName)
    {
    using (ShellLibrary library = ShellLibrary.Load(oldName, true))
    {
    ShellLibrary.Copy(library, newName, ShellLibrary.LibrariesKnownFolder, false);
    }
    DeleteLibrary(oldName);
    }

    (Code Snippet – Shell Libraries – DeleteAndRenameLibraryCommands VB)

    <Command(Name:="Delete", Usage:="SLUtil Delete LibraryName", Info:="Delete a library", Example:="SLUtil Delete MyLib")> _
    Public Sub DeleteLibrary(ByVal name As String)
    Dim librariesPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), ShellLibrary.LibrariesKnownFolder.RelativePath)

    Dim libraryPath = Path.Combine(librariesPath, name)
    Dim libraryFullPath = Path.ChangeExtension(libraryPath, "library-ms")

    File.Delete(libraryFullPath)
    End Sub

    <Command(Name:="Rename", Usage:="SLUtil Rename OldName NewName", Info:="Rename a library", Example:="SLUtil Rename MyLib MyLibNewName")> _
    Public Sub RenameLibrary(ByVal oldName As String, ByVal newName As String)
    Using library = ShellLibrary.Load(oldName, True)
    ShellLibrary.Copy(library, newName, ShellLibrary.LibrariesKnownFolder, False)
    End Using
    DeleteLibrary(oldName)
    End Sub

  3. Build the solution (CTRL+SHIFT+B), and follow these steps to verify the result:
    1. Open a Command Prompt window and change the directory (cd) to the location of the SLUtil.exe (…\bin\debug\SLUtil.exe).
    2. Open the Libraries Shell Folder next to the Command Prompt Window, so you will be able to see the changes you make with the SLUtil tool.
    3. Test the SLUtil from command line:SLUtil.exe Rename MyLib MyLib2

Task 5 – Adding SaveFolder, NavPanePinnedState, Icon, and FolderType Commands

These four commands share common behaviors. First, the user can use these commands to query the state of the library by supplying just the Library name. Second, to implement these commands, the Windows API exposes them in the ShellLibrary as properties.

// Summary:
// By default, this folder is the first location added to the library.
// The default save folder is both the default folder where files can be
// saved, and also where the library XML file will be saved, if no other
// path is specified
public string DefaultSaveFolder { get; set; }

public IconReference IconResourceId { get; set; }

// Summary:
// Whether the library will be pinned to the Explorer Navigation Pane
public bool IsPinnedToNavigationPane { get; set; }

// Summary:
// One of predefined Library types
//
// Exceptions:
// System.Runtime.InteropServices.COMException:
// Will throw if no Library Type is set
public LibraryFolderType LibraryType { get; set; }' Summary:
' By default, this folder is the first location added to the library.
' The default save folder is both the default folder where files can be
' saved, and also where the library XML file will be saved, if no other
' path is specified
Public Property DefaultSaveFolder() As String

Public Property IconResourceId() As IconReference

' Summary:
' Whether the library will be pinned to the Explorer Navigation Pane
Public Property IsPinnedToNavigationPane() As Boolean

' Summary:
' One of predefined Library types
'
' Exceptions:
' System.Runtime.InteropServices.COMException:
' Will throw if no Library Type is set
Public Property LibraryType() As LibraryFolderType

  1. Add the following code to ShellCommands:

    1. SaveFolder -- Lets you query and set the current default save folder. Bear in mind that this value may be empty if the folder list of the library is empty.
    2. NavPanePinnedState -- Lets you query and set whether the library name will appear in the Explorer navigation pane.
    3. Icon -- Lets you query or set the icon resource name; this property may be empty.
    4. FolderType -- Lets you query and set the Library shell folder template. This template tells the Shell how to display the library window.

    (Code Snippet – Shell Libraries – LibraryPropertiesCommands CSharp)

    [Command(
    Name = "SaveFolder",
    Usage = "SLUtil SaveFolder LibraryName [FolderPath]",
    Info = "Set or get the library's save folder path",
    Example = @"SLUtil SaveFolder Documents C:\Docs")]
    public static void SaveFolder(string name, string folderPath)
    {
    bool isReadOperation = string.IsNullOrEmpty(folderPath);

    using (ShellLibrary library = ShellLibrary.Load(name, isReadOperation))
    {
    if (isReadOperation)
    {
    Console.WriteLine("Save folder: {0}", library.DefaultSaveFolder);
    }
    else
    {
    library.DefaultSaveFolder = folderPath;
    }
    }
    }

    [Command(
    Name = "NavPanePinnedState",
    Usage = "SLUtil NavPanePinnedState LibraryName [TRUE|FALSE]",
    Info = "Set or get the library's Pinned to navigation pane state",
    Example = @"SLUtil NavPanePinnedState MyLib TRUE")]
    public static void NavPanePinnedState(string name, string stateText)
    {
    bool isReadOperation = string.IsNullOrEmpty(stateText);

    using (ShellLibrary library = ShellLibrary.Load(name, isReadOperation))
    {
    if (isReadOperation)
    {
    Console.WriteLine("The library {0} is{1}pinned to the" +
    "navigation pane.",
    name, library.IsPinnedToNavigationPane ? " " : " not ");
    }
    else
    {
    bool state = bool.Parse(stateText);
    library.IsPinnedToNavigationPane = state;
    }
    }
    }

    [Command(
    Name = "Icon",
    Usage = "SLUtil Icon LibraryName [Icon]",
    Info = "Set or get the library's icon",
    Example = @"SLUtil Icon MyLib imageres.dll,-1005")]
    public static void Icon(string name, string icon)
    {
    bool isReadOperation = string.IsNullOrEmpty(icon);

    using (ShellLibrary library = ShellLibrary.Load(name, isReadOperation))
    {
    if (isReadOperation)
    {
    Console.WriteLine("Icon: {0}", library.IconResourceId.ReferencePath);
    }
    else
    {
    library.IconResourceId = new IconReference(icon);
    }
    }
    }

    [Command(
    Name = "FolderType",
    Usage = "SLUtil FolderType LibraryName " +
    "[Generic|Documents|Pictures|Music|Videos]",
    Info = "Set or get the library's folder template",
    Example = @"SLUtil FolderType MyLib Documents")]
    public static void FolderType(string name, string folderType)
    {
    bool isReadOperation = string.IsNullOrEmpty(folderType);

    using (ShellLibrary library = ShellLibrary.Load(name, isReadOperation))
    {
    if (isReadOperation)
    {
    Console.WriteLine("Folder type: {0}", library.LibraryType);
    }
    else
    {
    library.LibraryType = (LibraryFolderType)Enum.Parse(typeof(LibraryFolderType), folderType);
    }
    }
    }

    (Code Snippet – Shell Libraries – LibraryPropertiesCommands VB)

    <Command(Name:="SaveFolder", Usage:="SLUtil SaveFolder LibraryName [FolderPath]", Info:="Set or get the library's save folder path", Example:="SLUtil SaveFolder Documents C:\Docs")> _
    Public Sub SaveFolder(ByVal name As String, ByVal folderPath As String)
    Dim isReadOperation = String.IsNullOrEmpty(folderPath)

    Using library = ShellLibrary.Load(name, isReadOperation)
    If isReadOperation Then
    Console.WriteLine("Save folder: {0}", library.DefaultSaveFolder)
    Else
    library.DefaultSaveFolder = folderPath
    End If
    End Using
    End Sub

    <Command(Name:="NavPanePinnedState", Usage:="SLUtil NavPanePinnedState LibraryName [TRUE|FALSE]", Info:="Set or get the library's Pinned to navigation pane state", Example:="SLUtil NavPanePinnedState MyLib TRUE")> _
    Public Sub NavPanePinnedState(ByVal name As String, ByVal stateText As String)
    Dim isReadOperation = String.IsNullOrEmpty(icon)

    Using library = ShellLibrary.Load(name, isReadOperation)
    If isReadOperation Then
    Console.WriteLine("The library {0} is{1}pinned to the navigation pane.", _
    name, If(library.IsPinnedToNavigationPane, " ", " not "))
    Else
    Dim state = CBool(stateText)
    library.IsPinnedToNavigationPane = state
    End If
    End Using
    End Sub

    <Command(Name:="Icon", Usage:="SLUtil Icon LibraryName [Icon]", Info:="Set or get the library's icon", Example:="SLUtil Icon MyLib imageres.dll,-1005")> _
    Public Sub Icon(ByVal name As String, ByVal icon As String)
    Dim isReadOperation As Boolean = String.IsNullOrEmpty(icon)

    Using library = ShellLibrary.Load(name, isReadOperation)
    If isReadOperation Then
    Console.WriteLine("Icon: {0}", library.IconResourceId.ReferencePath)
    Else
    library.IconResourceId = New IconReference(icon)
    End If
    End Using
    End Sub

    <Command(Name:="FolderType", Usage:="SLUtil FolderType LibraryName " & "[Generic|Documents|Pictures|Music|Videos]", Info:="Set or get the library's folder template", Example:="SLUtil FolderType MyLib Documents")> _
    Public Sub FolderType(ByVal name As String, ByVal folderType As String)
    Dim isReadOperation = String.IsNullOrEmpty(folderType)

    Using library = ShellLibrary.Load(name, isReadOperation)
    If isReadOperation Then
    Console.WriteLine("Folder type: {0}", library.LibraryType)
    Else
    library.LibraryType = CType(System.Enum.Parse(GetType(LibraryFolderType), folderType), LibraryFolderType)
    End If
    End Using
    End Sub

  2. Build the solution (CTRL+SHIFT+B), and follow these steps to verify the result:

    1. Open a Command Prompt window and change the directory (cd) to the location of the SLUtil.exe (…\bin\debug\SLUtil.exe).
    2. Open the Libraries Shell Folder next to the Command Prompt Window, so you will be able to see the changes you make with the SLUtil tool.
    3. Test the SLUtil from the command line:SLUtil.exe SaveFolder Documents
      SLUtil.exe NavPanePinnedState NewLibrary TRUE
      SLUtil.exe Icon NewLibrary imageres.dll,-1005
      SLUtil.exe FolderType NewLibrary Documents

    Figure 6

    New Library settings changed

Task 6 – Adding the ShowInfo Command

The ShowInfo command displays everything about a Library. If ShowInfo receives no input parameters, it shows the information of all the libraries under the “main” library folder. In the previous task, you learned how to use ShellLibrary properties to get information about the library's state. With the ShowInfo command, we also need to know how to get the library’s folder list. The Windows API Pack ShellLibrary is a ShellContainer, hence implementing the IList<FileSystemFolder> (C#) or IList(Of FileSystemFolder) (Visual Basic). You can iterate through all the folders in the library using regular iterator.

  1. Add the following code to ShellCommands:

    (Code Snippet – Shell Libraries – ShowInfoCommand CSharp)

    [Command(
    Name = "ShowInfo",
    Usage = "SLUtil ShowInfo [LibraryName]",
    Info = "Show Library information. If the LibraryName parameter is" +
    "missing, show information of all libraries under the Libraries folder",
    Example = @"SLUtil ShowInfo Documents")]
    public static void ShowInfo(string name)
    {
    if (string.IsNullOrEmpty(name))
    {
    foreach (ShellObject shellObject in ShellLibrary.LibrariesKnownFolder)
    {
    ShellLibrary shellLibrary = shellObject as ShellLibrary;

    if (shellLibrary == null)
    continue;

    try //try to get the maximum information
    {
    ShowInformation(shellLibrary);
    }
    catch (Exception ex)
    {
    System.Diagnostics.Trace.WriteLine("Error: " + ex.Message);
    }
    shellLibrary.Dispose();
    }
    }
    else
    {
    using (ShellLibrary library = ShellLibrary.Load(name, true))
    {
    ShowInformation(library);
    }
    }
    }

    private static void ShowInformation(ShellLibrary library)
    {
    string defaultSaveFolder = string.Empty;

    Console.WriteLine("\nShowing information of {0} library", library.Name);
    Console.WriteLine("\tIs pinned to navigation pane: {0}",
    library.IsPinnedToNavigationPane);
    try
    {
    defaultSaveFolder = library.DefaultSaveFolder;
    }
    catch
    {
    }

    Console.WriteLine("\tSave folder: {0}", defaultSaveFolder);
    try
    {
    Console.WriteLine("\tIcon: {0}", library.IconResourceId.ReferencePath);
    }
    catch
    {
    }

    try
    {
    Console.WriteLine("\tFolder type: {0}", library.LibraryType);
    }
    catch
    {
    }

    Console.WriteLine("\tFolder list:");
    foreach (ShellFolder folder in library)
    {
    Console.WriteLine("\t\t{0} {1}", folder.Name, defaultSaveFolder ==
    folder.Name ? "*" : "");
    }
    }

    (Code Snippet – Shell Libraries – ShowInfoCommand VB)

    <Command(Name:="ShowInfo", Usage:="SLUtil ShowInfo [LibraryName]", Info:="Show Library information. If the LibraryName parameter is" & "missing, show information of all libraries under the Libraries folder", Example:="SLUtil ShowInfo Documents")> _
    Public Sub ShowInfo(ByVal name As String)
    If String.IsNullOrEmpty(name) Then
    For Each shellObject In shellLibrary.LibrariesKnownFolder
    Dim shellLibrary = TryCast(shellObject, ShellLibrary)

    If shellLibrary Is Nothing Then Continue For

    Try 'try to get the maximum information
    ShowInformation(shellLibrary)
    Catch ex As Exception
    System.Diagnostics.Trace.WriteLine("Error: " & ex.Message)
    End Try
    shellLibrary.Dispose()
    Next shellObject
    Else
    Using library = ShellLibrary.Load(name, True)
    ShowInformation(library)
    End Using
    End If
    End Sub

    Private Sub ShowInformation(ByVal library As ShellLibrary)
    Dim defaultSaveFolder = String.Empty

    Console.WriteLine(Constants.vbLf & "Showing information of {0} library", library.Name)
    Console.WriteLine(Constants.vbTab & "Is pinned to navigation pane: {0}", library.IsPinnedToNavigationPane)
    Try
    defaultSaveFolder = library.DefaultSaveFolder
    Catch
    End Try

    Console.WriteLine(Constants.vbTab & "Save folder: {0}", defaultSaveFolder)
    Try
    Console.WriteLine(Constants.vbTab & "Icon: {0}", library.IconResourceId.ReferencePath)
    Catch
    End Try

    Try
    Console.WriteLine(Constants.vbTab & "Folder type: {0}", library.LibraryType)
    Catch
    End Try

    Console.WriteLine(Constants.vbTab & "Folder list:")
    For Each folder In library
    Console.WriteLine(Constants.vbTab & Constants.vbTab & "{0} {1}", folder.Name, If(defaultSaveFolder = folder.Name, "*", ""))
    Next folder
    End Sub

  2. Build the solution (CTRL+SHIFT+B), and follow these steps to verify the result:

    1. Open a Command Prompt window to change the directory (cd) to the location of the SLUtil.exe (…\bin\debug\SLUtil.exe).
    2. Open the Libraries Shell Folder next to the Command Prompt Window, so you will be able to see the changes you make with the SLUtil tool.
    3. Test the SLUtil from the command line:SLUtil.exe ShowInfo

    Figure 7

    Using the ShowInfo command

Task 7 – Adding the ManageUI Command

The final command that complete the SLUtil, is the ManageUI command. This command shows the library’s shell management window:

Figure 8

Library's shell management window

// Summary:
// Shows the library management dialog which enables users to mange
// the library folders and default save location.
//
// Parameters:
// windowHandle:
// The parent window,or IntPtr.Zero for no parent
//
// title:
// A title for the library management dialog, or null to use the library
// name as the title
//
// instruction:
// An optional help string to display for the library management dialog
//
// allowAllLocations:
// If true, do not show warning dialogs about locations that cannot be
// indexed
//
// Returns:
// true if the user cliked O.K, false if the user clicked Cancel
public bool ShowManageLibraryUI(IntPtr windowHandle, string title,
string instruction, bool allowAllLocations);
//
// Summary:
// Shows the library management dialog which enables users to mange the
// library folders and default save location.
//
// Parameters:
// form:
// A windows form (WinForm)
//
// title:
// A title for the library management dialog, or null to use the library
// name as the title
//
// instruction:
// An optional help string to display for the library management dialog
//
// allowAllLocations:
// If true, do not show warning dialogs about locations that cannot be
// indexed
//
// Returns:
// true if the user cliked O.K, false if the user clicked Cancel
public bool ShowManageLibraryUI(System.Windows.Forms.Form form, string title,
string instruction, bool allowAllLocations);
//
// Summary:
// Shows the library management dialog which enables users to mange the
// library folders and default save location.
//
// Parameters:
// mainWindow:
// The parent window for a WPF app
//
// title:
// A title for the library management dialog, or null to use the library
// name as the title
//
// instruction:
// An optional help string to display for the library management dialog
//
// allowAllLocations:
// If true, do not show warning dialogs about locations that cannot be
// indexed
//
// Returns:
// true if the user cliked O.K, false if the user clicked Cancel
public bool ShowManageLibraryUI(System.Windows.Window mainWindow,
string title, string instruction, bool allowAllLocations);' Summary:
' Shows the library management dialog which enables users to mange
' the library folders and default save location.
'
' Parameters:
' windowHandle:
' The parent window,or IntPtr.Zero for no parent
'
' title:
' A title for the library management dialog, or null to use the library
' name as the title
'
' instruction:
' An optional help string to display for the library management dialog
'
' allowAllLocations:
' If true, do not show warning dialogs about locations that cannot be
' indexed
'
' Returns:
' true if the user cliked O.K, false if the user clicked Cancel
Public Function ShowManageLibraryUI(ByVal windowHandle As System.IntPtr, ByVal title As String, ByVal instruction As String, ByVal allowAllLocations As Boolean) As Boolean
'
' Summary:
' Shows the library management dialog which enables users to mange the
' library folders and default save location.
'
' Parameters:
' form:
' A windows form (WinForm)
'
' title:
' A title for the library management dialog, or null to use the library
' name as the title
'
' instruction:
' An optional help string to display for the library management dialog
'
' allowAllLocations:
' If true, do not show warning dialogs about locations that cannot be
' indexed
'
' Returns:
' true if the user cliked O.K, false if the user clicked Cancel
Public Function ShowManageLibraryUI(ByVal form As Form, ByVal title As String, ByVal instruction As String, ByVal allowAllLocations As Boolean) As Boolean
'
' Summary:
' Shows the library management dialog which enables users to mange the
' library folders and default save location.
'
' Parameters:
' mainWindow:
' The parent window for a WPF app
'
' title:
' A title for the library management dialog, or null to use the library
' name as the title
'
' instruction:
' An optional help string to display for the library management dialog
'
' allowAllLocations:
' If true, do not show warning dialogs about locations that cannot be
' indexed
'
' Returns:
' true if the user cliked O.K, false if the user clicked Cancel
Public Function ShowManageLibraryUI(ByVal mainWindow As Window, ByVal title As String, ByVal instruction As String, ByVal allowAllLocations As Boolean) As Boolean

  1. Add the following code to ShellCommands:

    (Code Snippet – Shell Libraries – ManageUICommand CSharp)

    [Command(
    Name = "ManageUI",
    Usage = "SLUtil ManageUI LibraryName",
    Info = "Show the Shell Library management UI",
    Example = @"SLUtil ManageUI Documents")]
    public static void ManageUI(string name)
    {
    using (ShellLibrary library = ShellLibrary.Load(name, false))
    {
    library.ShowManageLibraryUI(IntPtr.Zero, "SLUtil", "Manage Library", true);
    }
    }

    (Code Snippet – Shell Libraries – ManageUICommand VB)

    <Command(Name:="ManageUI", Usage:="SLUtil ManageUI LibraryName", Info:="Show the Shell Library management UI", Example:="SLUtil ManageUI Documents")> _
    Public Sub ManageUI(ByVal name As String)
    Using library = ShellLibrary.Load(name, False)
    library.ShowManageLibraryUI(IntPtr.Zero, "SLUtil", "Manage Library", True)
    End Using
    End Sub

  2. Build the solution (CTRL+SHIFT+B), and follow these steps to verify the result:
    1. Open a Command Prompt window to change the directory (cd) to the location of the SLUtil.exe (…\bin\debug\SLUtil.exe).
    2. Test the SLUtil from the command line:SLUtil.exe ManageUI Documents