diff --git a/SharpShell/Samples/ContextMenu/AdvancedContextMenuExtension/AdvancedContextMenuExtension.csproj b/SharpShell/Samples/ContextMenu/AdvancedContextMenuExtension/AdvancedContextMenuExtension.csproj
index 4e636a3b..4964a388 100644
--- a/SharpShell/Samples/ContextMenu/AdvancedContextMenuExtension/AdvancedContextMenuExtension.csproj
+++ b/SharpShell/Samples/ContextMenu/AdvancedContextMenuExtension/AdvancedContextMenuExtension.csproj
@@ -28,6 +28,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -36,6 +37,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/ContextMenu/CopyDirectoryLocationHandler/CopyDirectoryLocationHandler.csproj b/SharpShell/Samples/ContextMenu/CopyDirectoryLocationHandler/CopyDirectoryLocationHandler.csproj
index b9c7d6e7..b1872d15 100644
--- a/SharpShell/Samples/ContextMenu/CopyDirectoryLocationHandler/CopyDirectoryLocationHandler.csproj
+++ b/SharpShell/Samples/ContextMenu/CopyDirectoryLocationHandler/CopyDirectoryLocationHandler.csproj
@@ -28,6 +28,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -36,6 +37,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/ContextMenu/CountLinesExtension/CountLinesExtension.csproj b/SharpShell/Samples/ContextMenu/CountLinesExtension/CountLinesExtension.csproj
index 987b69df..ef4ec696 100644
--- a/SharpShell/Samples/ContextMenu/CountLinesExtension/CountLinesExtension.csproj
+++ b/SharpShell/Samples/ContextMenu/CountLinesExtension/CountLinesExtension.csproj
@@ -29,6 +29,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -37,6 +38,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/ContextMenu/DynamicSubMenu/DynamicSubMenus.csproj b/SharpShell/Samples/ContextMenu/DynamicSubMenu/DynamicSubMenus.csproj
index b909991e..f8de19b2 100644
--- a/SharpShell/Samples/ContextMenu/DynamicSubMenu/DynamicSubMenus.csproj
+++ b/SharpShell/Samples/ContextMenu/DynamicSubMenu/DynamicSubMenus.csproj
@@ -20,6 +20,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -28,6 +29,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/DataHandler/CopyPathDataHandler/CopyPathDataHandler.csproj b/SharpShell/Samples/DataHandler/CopyPathDataHandler/CopyPathDataHandler.csproj
index 49d1a28a..0969756b 100644
--- a/SharpShell/Samples/DataHandler/CopyPathDataHandler/CopyPathDataHandler.csproj
+++ b/SharpShell/Samples/DataHandler/CopyPathDataHandler/CopyPathDataHandler.csproj
@@ -29,6 +29,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -37,6 +38,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/DeskBand/WebSearchDeskBand/WebSearchDeskBand.csproj b/SharpShell/Samples/DeskBand/WebSearchDeskBand/WebSearchDeskBand.csproj
index a26d4cc1..b0f145c9 100644
--- a/SharpShell/Samples/DeskBand/WebSearchDeskBand/WebSearchDeskBand.csproj
+++ b/SharpShell/Samples/DeskBand/WebSearchDeskBand/WebSearchDeskBand.csproj
@@ -20,6 +20,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -30,6 +31,7 @@
4
false
AnyCPU
+ 7.3
true
diff --git a/SharpShell/Samples/DropHandler/XsdDropHandler/XsdDropHandler.csproj b/SharpShell/Samples/DropHandler/XsdDropHandler/XsdDropHandler.csproj
index 00bdb76a..610b06ac 100644
--- a/SharpShell/Samples/DropHandler/XsdDropHandler/XsdDropHandler.csproj
+++ b/SharpShell/Samples/DropHandler/XsdDropHandler/XsdDropHandler.csproj
@@ -29,6 +29,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -37,6 +38,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/IconHandler/DllIconHandler/DllIconHandler.csproj b/SharpShell/Samples/IconHandler/DllIconHandler/DllIconHandler.csproj
index 51ceae43..31906394 100644
--- a/SharpShell/Samples/IconHandler/DllIconHandler/DllIconHandler.csproj
+++ b/SharpShell/Samples/IconHandler/DllIconHandler/DllIconHandler.csproj
@@ -29,6 +29,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -37,6 +38,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/IconOverlayHandler/LockedFileIconOverlayHandler/LockedFileIconOverlayHandler.csproj b/SharpShell/Samples/IconOverlayHandler/LockedFileIconOverlayHandler/LockedFileIconOverlayHandler.csproj
index e7819f6c..6cd61810 100644
--- a/SharpShell/Samples/IconOverlayHandler/LockedFileIconOverlayHandler/LockedFileIconOverlayHandler.csproj
+++ b/SharpShell/Samples/IconOverlayHandler/LockedFileIconOverlayHandler/LockedFileIconOverlayHandler.csproj
@@ -29,6 +29,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -37,6 +38,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/IconOverlayHandler/ReadOnlyFileIconOverlayHandler/ReadOnlyFileIconOverlayHandler.csproj b/SharpShell/Samples/IconOverlayHandler/ReadOnlyFileIconOverlayHandler/ReadOnlyFileIconOverlayHandler.csproj
index 425e5ffd..07a640f3 100644
--- a/SharpShell/Samples/IconOverlayHandler/ReadOnlyFileIconOverlayHandler/ReadOnlyFileIconOverlayHandler.csproj
+++ b/SharpShell/Samples/IconOverlayHandler/ReadOnlyFileIconOverlayHandler/ReadOnlyFileIconOverlayHandler.csproj
@@ -29,6 +29,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -37,6 +38,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/InfoTipHandler/FolderInfoTipHandler/FolderInfoTipHandler.csproj b/SharpShell/Samples/InfoTipHandler/FolderInfoTipHandler/FolderInfoTipHandler.csproj
index 7f3fa2f0..da95b2d3 100644
--- a/SharpShell/Samples/InfoTipHandler/FolderInfoTipHandler/FolderInfoTipHandler.csproj
+++ b/SharpShell/Samples/InfoTipHandler/FolderInfoTipHandler/FolderInfoTipHandler.csproj
@@ -29,6 +29,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -37,6 +38,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/NamespaceExtension/EnvironmentVariablesNamespaceExtension/EnvironmentVariablesNamespaceExtension.csproj b/SharpShell/Samples/NamespaceExtension/EnvironmentVariablesNamespaceExtension/EnvironmentVariablesNamespaceExtension.csproj
index 1d2401f1..44ebfb97 100644
--- a/SharpShell/Samples/NamespaceExtension/EnvironmentVariablesNamespaceExtension/EnvironmentVariablesNamespaceExtension.csproj
+++ b/SharpShell/Samples/NamespaceExtension/EnvironmentVariablesNamespaceExtension/EnvironmentVariablesNamespaceExtension.csproj
@@ -20,6 +20,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -28,6 +29,7 @@
TRACE
prompt
4
+ 7.3
diff --git a/SharpShell/Samples/NamespaceExtension/GitHubNamespaceExtension/GitHubNamespaceExtension.csproj b/SharpShell/Samples/NamespaceExtension/GitHubNamespaceExtension/GitHubNamespaceExtension.csproj
index 2c38cb16..03deab01 100644
--- a/SharpShell/Samples/NamespaceExtension/GitHubNamespaceExtension/GitHubNamespaceExtension.csproj
+++ b/SharpShell/Samples/NamespaceExtension/GitHubNamespaceExtension/GitHubNamespaceExtension.csproj
@@ -22,6 +22,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -30,6 +31,7 @@
TRACE
prompt
4
+ 7.3
diff --git a/SharpShell/Samples/NamespaceExtension/RegistryNamespaceExtension/RegistryNamespaceExtension.csproj b/SharpShell/Samples/NamespaceExtension/RegistryNamespaceExtension/RegistryNamespaceExtension.csproj
index c614393f..21406552 100644
--- a/SharpShell/Samples/NamespaceExtension/RegistryNamespaceExtension/RegistryNamespaceExtension.csproj
+++ b/SharpShell/Samples/NamespaceExtension/RegistryNamespaceExtension/RegistryNamespaceExtension.csproj
@@ -20,6 +20,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -28,6 +29,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/PreviewHandler/AbcPreviewHandler/AbcPreviewHandler.csproj b/SharpShell/Samples/PreviewHandler/AbcPreviewHandler/AbcPreviewHandler.csproj
index cfb18e4f..e2390499 100644
--- a/SharpShell/Samples/PreviewHandler/AbcPreviewHandler/AbcPreviewHandler.csproj
+++ b/SharpShell/Samples/PreviewHandler/AbcPreviewHandler/AbcPreviewHandler.csproj
@@ -20,6 +20,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -28,6 +29,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/PreviewHandler/IconPreviewHandler/IconPreviewHandler.csproj b/SharpShell/Samples/PreviewHandler/IconPreviewHandler/IconPreviewHandler.csproj
index f162de99..b48873b9 100644
--- a/SharpShell/Samples/PreviewHandler/IconPreviewHandler/IconPreviewHandler.csproj
+++ b/SharpShell/Samples/PreviewHandler/IconPreviewHandler/IconPreviewHandler.csproj
@@ -29,6 +29,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -37,6 +38,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/PropertySheet/FileTimesPropertySheet/FileTimesPropertySheet.csproj b/SharpShell/Samples/PropertySheet/FileTimesPropertySheet/FileTimesPropertySheet.csproj
index ff71f2bd..fdc71ceb 100644
--- a/SharpShell/Samples/PropertySheet/FileTimesPropertySheet/FileTimesPropertySheet.csproj
+++ b/SharpShell/Samples/PropertySheet/FileTimesPropertySheet/FileTimesPropertySheet.csproj
@@ -28,6 +28,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -36,6 +37,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/PropertySheet/ResourcesPropertySheet.Tests/ResourcesPropertySheet.Tests.csproj b/SharpShell/Samples/PropertySheet/ResourcesPropertySheet.Tests/ResourcesPropertySheet.Tests.csproj
index 868bb366..7f103670 100644
--- a/SharpShell/Samples/PropertySheet/ResourcesPropertySheet.Tests/ResourcesPropertySheet.Tests.csproj
+++ b/SharpShell/Samples/PropertySheet/ResourcesPropertySheet.Tests/ResourcesPropertySheet.Tests.csproj
@@ -24,6 +24,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -32,6 +33,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/PropertySheet/ResourcesPropertySheet/ResourcesPropertySheet.csproj b/SharpShell/Samples/PropertySheet/ResourcesPropertySheet/ResourcesPropertySheet.csproj
index c0585847..a1ce0bfa 100644
--- a/SharpShell/Samples/PropertySheet/ResourcesPropertySheet/ResourcesPropertySheet.csproj
+++ b/SharpShell/Samples/PropertySheet/ResourcesPropertySheet/ResourcesPropertySheet.csproj
@@ -21,6 +21,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -29,6 +30,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Samples/ThumbnailHandler/TxtThumbnailHandler/TxtThumbnailHandler.csproj b/SharpShell/Samples/ThumbnailHandler/TxtThumbnailHandler/TxtThumbnailHandler.csproj
index 25d421fa..50e468f5 100644
--- a/SharpShell/Samples/ThumbnailHandler/TxtThumbnailHandler/TxtThumbnailHandler.csproj
+++ b/SharpShell/Samples/ThumbnailHandler/TxtThumbnailHandler/TxtThumbnailHandler.csproj
@@ -29,6 +29,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -37,6 +38,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/SharpShell.Tests/ServerRegistration/ServerRegistrationManagerTests.cs b/SharpShell/SharpShell.Tests/ServerRegistration/ServerRegistrationManagerTests.cs
index b68b438e..f4374f83 100644
--- a/SharpShell/SharpShell.Tests/ServerRegistration/ServerRegistrationManagerTests.cs
+++ b/SharpShell/SharpShell.Tests/ServerRegistration/ServerRegistrationManagerTests.cs
@@ -1,12 +1,7 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.AccessControl;
using Microsoft.Win32;
using NUnit.Framework;
-using NUnit.Framework.Internal.Execution;
using SharpShell.Attributes;
-using SharpShell.Extensions;
using SharpShell.Registry;
using SharpShell.ServerRegistration;
@@ -49,11 +44,18 @@ public void Register_Server_Associations_Uses_Appropriate_Class_Id_For_Class_Of_
// Register a context menu with an *.exe association.
var clsid = new Guid("00000000-1111-2222-3333-444444444444");
- var serverType = ServerType.ShellContextMenu;
+ var extensionType = ShellExtensionType.ShellContextMenu;
var serverName = "TestContextMenu";
- var associations = new[] { new COMServerAssociationAttribute(AssociationType.ClassOfExtension, ".exe") };
- var registrationType = RegistrationType.OS64Bit;
- ServerRegistrationManager.RegisterServerAssociations(clsid, serverType, serverName, associations, registrationType);
+ var registrationType = RegistrationScope.OS64Bit;
+ var associationClassNames =
+ new COMServerAssociationAttribute(AssociationType.ClassOfExtension, ".exe").GetAssociationClassNames(
+ registrationType);
+
+ foreach (var associationClassName in associationClassNames)
+ {
+ ServerRegistrationManager.RegisterShellExtensionAssociation(clsid, extensionType, serverName, associationClassName, registrationType);
+ }
+
// Assert we have the new extention.
var print = _registry.Print(RegistryView.Registry64);
@@ -83,11 +85,17 @@ public void Register_Server_Associations_Creates_Class_Ids_For_Extension_Of_Clas
// Register a file association. Given that this registry is empty, it a new program id and then set an association.
var clsid = new Guid("00000000-1111-2222-3333-444444444444");
- var serverType = ServerType.ShellContextMenu;
+ var extensionType = ShellExtensionType.ShellContextMenu;
var serverName = "TestContextMenu";
- var associations = new[] { new COMServerAssociationAttribute(AssociationType.ClassOfExtension, ".myfile") };
- var registrationType = RegistrationType.OS64Bit;
- ServerRegistrationManager.RegisterServerAssociations(clsid, serverType, serverName, associations, registrationType);
+ var registrationType = RegistrationScope.OS64Bit;
+ var associationClassNames =
+ new COMServerAssociationAttribute(AssociationType.ClassOfExtension, ".myfile").GetAssociationClassNames(
+ registrationType);
+
+ foreach (var associationClassName in associationClassNames)
+ {
+ ServerRegistrationManager.RegisterShellExtensionAssociation(clsid, extensionType, serverName, associationClassName, registrationType);
+ }
// Assert we have the new extention.
var print = _registry.Print(RegistryView.Registry64);
@@ -127,11 +135,18 @@ public void Register_Server_Associations_Fails_If_Class_Ids_For_Extension_Of_Cla
{
// Register a server.
var clsid = new Guid("00000000-1111-2222-3333-444444444444");
- var serverType = ServerType.ShellContextMenu;
+ var extensionType = ShellExtensionType.ShellContextMenu;
var serverName = "TestContextMenu";
- var associations = new[] { new COMServerAssociationAttribute(AssociationType.ClassOfExtension, ".myfile") };
- var registrationType = RegistrationType.OS64Bit;
- ServerRegistrationManager.RegisterServerAssociations(clsid, serverType, serverName, associations, registrationType);
+ var registrationType = RegistrationScope.OS64Bit;
+ var associationClassNames =
+ new COMServerAssociationAttribute(AssociationType.ClassOfExtension, ".myfile").GetAssociationClassNames(
+ registrationType);
+
+ foreach (var associationClassName in associationClassNames)
+ {
+ ServerRegistrationManager.RegisterShellExtensionAssociation(clsid, extensionType, serverName, associationClassName, registrationType);
+ }
+
Assert.Fail(@"Server registration should fail");
}
catch (Exception exception)
@@ -150,11 +165,17 @@ public void Register_Server_Associations_Creates_File_Id_And_Class_Ids_For_Exten
{
// Register a file association. Given that this registry is empty, it a new program id and then set an association.
var clsid = new Guid("00000000-1111-2222-3333-444444444444");
- var serverType = ServerType.ShellContextMenu;
+ var extensionType = ShellExtensionType.ShellContextMenu;
var serverName = "TestContextMenu";
- var associations = new[] {new COMServerAssociationAttribute(AssociationType.ClassOfExtension, ".myfile")};
- var registrationType = RegistrationType.OS64Bit;
- ServerRegistrationManager.RegisterServerAssociations(clsid, serverType, serverName, associations, registrationType);
+ var registrationType = RegistrationScope.OS64Bit;
+ var associationClassNames =
+ new COMServerAssociationAttribute(AssociationType.ClassOfExtension, ".myfile").GetAssociationClassNames(
+ registrationType);
+
+ foreach (var associationClassName in associationClassNames)
+ {
+ ServerRegistrationManager.RegisterShellExtensionAssociation(clsid, extensionType, serverName, associationClassName, registrationType);
+ }
// Assert we have the new extention.
var print = _registry.Print(RegistryView.Registry64);
diff --git a/SharpShell/SharpShell.Tests/SharpShell.Tests.csproj b/SharpShell/SharpShell.Tests/SharpShell.Tests.csproj
index 31f2bdb8..b0748e02 100644
--- a/SharpShell/SharpShell.Tests/SharpShell.Tests.csproj
+++ b/SharpShell/SharpShell.Tests/SharpShell.Tests.csproj
@@ -26,6 +26,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
pdbonly
@@ -34,6 +35,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/SharpShell.sln.DotSettings b/SharpShell/SharpShell.sln.DotSettings
new file mode 100644
index 00000000..eaa28aa9
--- /dev/null
+++ b/SharpShell/SharpShell.sln.DotSettings
@@ -0,0 +1,4 @@
+
+ CD
+ DVD
+ PIDL
\ No newline at end of file
diff --git a/SharpShell/SharpShell/Attributes/AssociationType.cs b/SharpShell/SharpShell/Attributes/AssociationType.cs
index 90f63719..822ac75f 100644
--- a/SharpShell/SharpShell/Attributes/AssociationType.cs
+++ b/SharpShell/SharpShell/Attributes/AssociationType.cs
@@ -15,7 +15,7 @@ public enum AssociationType
///
/// No server association.
///
- None,
+ None = 0,
///
/// Create an association to a specific file extension.
@@ -23,64 +23,64 @@ public enum AssociationType
/// but on the class of the extension.
///
[Obsolete("FileExtension is deprecated. Use 'ClassOfExtension' instead.")]
- FileExtension,
+ FileExtension = 1,
///
/// Create an association to the class of a specific file extension.
///
- ClassOfExtension,
+ ClassOfExtension = 2,
///
/// Create an association to a class.
///
- Class,
+ Class = 3,
///
/// Create an association to the 'all files' class.
///
[PredefinedShellObject(@"*")]
- AllFiles,
+ AllFiles = 4,
///
/// Create an association to the 'all files and folders' class.
///
[PredefinedShellObject(@"AllFileSystemObjects")]
- AllFilesAndFolders,
+ AllFilesAndFolders = 5,
///
/// Create an association to the 'directory' class, i.e. file-system folders.
///
[PredefinedShellObject(@"Directory")]
- Directory,
+ Directory = 6,
///
/// Create an association to the background of folders and the desktop
///
[PredefinedShellObject(@"Directory\Background")]
- DirectoryBackground,
+ DirectoryBackground = 7,
///
/// Create an association to the background of the desktop (Windows 7 and higher)
///
[PredefinedShellObject(@"DesktopBackground")]
- DesktopBackground,
+ DesktopBackground = 8,
///
/// Create an association to the drive class.
///
[PredefinedShellObject(@"Drive")]
- Drive,
+ Drive = 9,
///
/// Create an association to the 'folder' class, i.e. all containers.
///
[PredefinedShellObject(@"Folder")]
- Folder,
+ Folder = 10,
///
/// Create an association to the unknown files class.
///
[PredefinedShellObject(@"Unknown")]
- UnknownFiles
+ UnknownFiles = 11
}
}
diff --git a/SharpShell/SharpShell/Attributes/COMServerAssociationAttribute.cs b/SharpShell/SharpShell/Attributes/COMServerAssociationAttribute.cs
index d179f50b..4ec398b6 100644
--- a/SharpShell/SharpShell/Attributes/COMServerAssociationAttribute.cs
+++ b/SharpShell/SharpShell/Attributes/COMServerAssociationAttribute.cs
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Collections.Generic;
+using SharpShell.ServerRegistration;
namespace SharpShell.Attributes
{
@@ -8,6 +9,7 @@ namespace SharpShell.Attributes
/// Attribute to associate a SharpShell server with a file extension.
///
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
+ [Serializable]
public class COMServerAssociationAttribute : Attribute
{
///
@@ -17,23 +19,21 @@ public class COMServerAssociationAttribute : Attribute
/// The associations.
public COMServerAssociationAttribute(AssociationType associationType, params string[] associations)
{
- // Set the assocation type.
- this.associationType = associationType;
+ // Set the association type.
+ AssociationType = associationType;
// Set the associations.
- this.associations = associations;
+ Associations = associations;
}
///
/// Gets the file extension associations for a specified type.
///
/// The type.
- /// The set of file extension assocations.
+ /// The set of file extension associations.
public static IEnumerable GetAssociations(Type type)
{
- var attribute = type.GetCustomAttributes(typeof(COMServerAssociationAttribute), true)
- .OfType().FirstOrDefault();
- return attribute != null ? attribute.Associations : new string[] {};
+ return GetAssociationAttributes(type).SelectMany(attribute => attribute.Associations ?? new string[0]);
}
///
@@ -41,22 +41,50 @@ public static IEnumerable GetAssociations(Type type)
///
/// The type.
///
- public static AssociationType GetAssociationType(Type type)
+ public static IEnumerable GetAssociationTypes(Type type)
{
- var attribute = type.GetCustomAttributes(typeof(COMServerAssociationAttribute), true)
- .OfType().FirstOrDefault();
- return attribute != null ? attribute.AssociationType : AssociationType.None;
+ return GetAssociationAttributes(type)?
+ .Select(attribute => attribute?.AssociationType ?? AssociationType.None)
+ .Where(associationType => associationType != AssociationType.None);
}
///
- /// The association type.
+ /// Gets all COMServerAssociationAttribute attributes of this class
///
- private readonly AssociationType associationType;
+ /// The type.
+ ///
+ public static IEnumerable GetAssociationAttributes(Type type)
+ {
+ var attributes = ServerSandBox.GetAttributesSafe(type, nameof(COMServerAssociationAttribute), true);
- ///
- /// The extensions.
- ///
- private readonly string[] associations;
+ if (attributes == null)
+ {
+ yield break;
+ }
+
+ foreach (var attribute in attributes)
+ {
+ var associationType = ServerSandBox.GetByValPropertySafe(
+ attribute,
+ nameof(AssociationType)
+ );
+
+ var associations = ServerSandBox.GetByRefPropertySafe>(
+ attribute,
+ nameof(Associations)
+ );
+
+ if (associationType != null && associations != null)
+ {
+ yield return new COMServerAssociationAttribute(associationType.Value, associations.ToArray());
+ }
+ }
+ }
+
+ public IEnumerable GetAssociationClassNames(RegistrationScope registrationScope)
+ {
+ return ServerRegistrationManager.GetAssociationClassNames(AssociationType, Associations, registrationScope);
+ }
///
/// Gets the type of the association.
@@ -64,11 +92,11 @@ public static AssociationType GetAssociationType(Type type)
///
/// The type of the association.
///
- public AssociationType AssociationType { get { return associationType; } }
+ public AssociationType AssociationType { get; }
///
/// Gets the associations.
///
- public IEnumerable Associations { get { return associations; } }
+ public IEnumerable Associations { get; }
}
}
diff --git a/SharpShell/SharpShell/Attributes/CustomRegisterFunctionAttribute.cs b/SharpShell/SharpShell/Attributes/CustomRegisterFunctionAttribute.cs
index 4be0a875..1f2cd88e 100644
--- a/SharpShell/SharpShell/Attributes/CustomRegisterFunctionAttribute.cs
+++ b/SharpShell/SharpShell/Attributes/CustomRegisterFunctionAttribute.cs
@@ -12,19 +12,21 @@ namespace SharpShell.Attributes
public class CustomRegisterFunctionAttribute : Attribute
{
///
- /// Executes the CustomRegisterFunction if it exists for a type.
+ /// Gets the name of CustomRegisterFunction if it exists for a type.
///
/// The type.
- /// Type of the registration.
- public static void ExecuteIfExists(Type type, RegistrationType registrationType)
+ public static string GetMethodName(Type type)
{
// Does the type have the attribute?
- var methodWithAttribute = type.GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy)
- .FirstOrDefault(m => m.GetCustomAttributes(typeof(CustomRegisterFunctionAttribute), false).Any());
-
- // Do we have a method? If so, invoke it.
- if (methodWithAttribute != null)
- methodWithAttribute.Invoke(null, new object[] {type, registrationType});
+ return type
+ .GetMethods(
+ BindingFlags.Static |
+ BindingFlags.NonPublic |
+ BindingFlags.Public |
+ BindingFlags.FlattenHierarchy
+ ).FirstOrDefault(m =>
+ ServerSandBox.GetAttributesSafe(m, nameof(CustomRegisterFunctionAttribute), false).Any()
+ )?.Name;
}
}
}
diff --git a/SharpShell/SharpShell/Attributes/CustomUnregisterFunctionAttribute.cs b/SharpShell/SharpShell/Attributes/CustomUnregisterFunctionAttribute.cs
index 216a8037..69f4e549 100644
--- a/SharpShell/SharpShell/Attributes/CustomUnregisterFunctionAttribute.cs
+++ b/SharpShell/SharpShell/Attributes/CustomUnregisterFunctionAttribute.cs
@@ -12,19 +12,21 @@ namespace SharpShell.Attributes
public class CustomUnregisterFunctionAttribute : Attribute
{
///
- /// Executes the CustomUnregisterFunction if it exists for a type.
+ /// Gets the name of CustomUnregisterFunction if it exists for a type.
///
/// The type.
- /// Type of the registration.
- public static void ExecuteIfExists(Type type, RegistrationType registrationType)
+ public static string GetMethodName(Type type)
{
// Does the type have the attribute?
- var methodWithAttribute = type.GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy)
- .FirstOrDefault(m => m.GetCustomAttributes(typeof (CustomUnregisterFunctionAttribute), false).Any());
-
- // Do we have a method? If so, invoke it.
- if (methodWithAttribute != null)
- methodWithAttribute.Invoke(null, new object[] { type, registrationType });
+ return type
+ .GetMethods(
+ BindingFlags.Static |
+ BindingFlags.NonPublic |
+ BindingFlags.Public |
+ BindingFlags.FlattenHierarchy
+ ).FirstOrDefault(m =>
+ ServerSandBox.GetAttributesSafe(m, nameof(CustomUnregisterFunctionAttribute), false).Any()
+ )?.Name;
}
}
}
diff --git a/SharpShell/SharpShell/Attributes/DisplayNameAttribute.cs b/SharpShell/SharpShell/Attributes/DisplayNameAttribute.cs
index 6dcca3df..62af9949 100644
--- a/SharpShell/SharpShell/Attributes/DisplayNameAttribute.cs
+++ b/SharpShell/SharpShell/Attributes/DisplayNameAttribute.cs
@@ -1,7 +1,6 @@
using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
+using SharpShell.ServerRegistration;
namespace SharpShell.Attributes
{
@@ -9,6 +8,7 @@ namespace SharpShell.Attributes
/// The name attribute can be used to give a class display name.
///
[AttributeUsage(AttributeTargets.Class)]
+ [Serializable]
public class DisplayNameAttribute : Attribute
{
///
@@ -28,9 +28,7 @@ public DisplayNameAttribute(string displayName)
/// The display name of the type, if defined.
public static string GetDisplayName(Type type)
{
- var attribute = type.GetCustomAttributes(typeof (DisplayNameAttribute), true)
- .OfType().FirstOrDefault();
- return attribute != null ? attribute.DisplayName : null;
+ return GetDisplayNameAttribute(type)?.DisplayName;
}
///
@@ -43,12 +41,32 @@ public static string GetDisplayNameOrTypeName(Type type)
{
// Return the display name if it is set, otherwise the type name.
var displayName = GetDisplayName(type);
+
return string.IsNullOrEmpty(displayName) ? type.Name : displayName;
}
+ public static DisplayNameAttribute GetDisplayNameAttribute(Type type)
+ {
+ var attribute = ServerSandBox.GetAttributesSafe(type, nameof(DisplayNameAttribute), true).FirstOrDefault();
+
+ if (attribute == null)
+ {
+ return null;
+ }
+
+ var displayName = ServerSandBox.GetStringPropertySafe(attribute, nameof(DisplayName));
+
+ if (displayName != null)
+ {
+ return new DisplayNameAttribute(displayName);
+ }
+
+ return null;
+ }
+
///
/// Gets the display name.
///
- public string DisplayName { get; private set; }
+ public string DisplayName { get; }
}
}
diff --git a/SharpShell/SharpShell/Attributes/HandlerSubkeyAttribute.cs b/SharpShell/SharpShell/Attributes/HandlerSubkeyAttribute.cs
index 7851c214..1dd38346 100644
--- a/SharpShell/SharpShell/Attributes/HandlerSubkeyAttribute.cs
+++ b/SharpShell/SharpShell/Attributes/HandlerSubkeyAttribute.cs
@@ -1,27 +1,30 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using SharpShell.Extensions;
namespace SharpShell.Attributes
{
///
- /// Attribute to describe handler subkey config.
+ /// Attribute to describe handler sub-key config.
///
[AttributeUsage(AttributeTargets.Field)]
- public class HandlerSubkeyAttribute : Attribute
+ internal class HandlerSubKeyAttribute : Attribute
{
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
+ /// The handler sub-key name.
/// if set to true [allow multiple entries].
- /// The handler subkey.
- public HandlerSubkeyAttribute(bool allowMultipleEntries, string handlerSubkey)
+ public HandlerSubKeyAttribute(string handlerSubKey, bool allowMultipleEntries)
{
AllowMultipleEntries = allowMultipleEntries;
- HandlerSubkey = handlerSubkey;
+ HandlerSubKey = handlerSubKey;
}
+ public static HandlerSubKeyAttribute GetHandlerSubKeyAttribute(T value) where T : Enum
+ {
+ return value.GetAttribute();
+ }
///
/// Gets a value indicating whether multiple entries are allowed.
@@ -29,14 +32,14 @@ public HandlerSubkeyAttribute(bool allowMultipleEntries, string handlerSubkey)
///
/// true if multiple entries are allowed; otherwise, false.
///
- public bool AllowMultipleEntries { get; private set; }
+ public bool AllowMultipleEntries { get; }
///
- /// Gets the handler subkey.
+ /// Gets the handler sub-key.
///
///
- /// The handler subkey.
+ /// The handler sub-key.
///
- public string HandlerSubkey { get; private set; }
+ public string HandlerSubKey { get; }
}
}
diff --git a/SharpShell/SharpShell/Attributes/PredefinedShellObjectAttribute.cs b/SharpShell/SharpShell/Attributes/PredefinedShellObjectAttribute.cs
index 8768da12..37ae8871 100644
--- a/SharpShell/SharpShell/Attributes/PredefinedShellObjectAttribute.cs
+++ b/SharpShell/SharpShell/Attributes/PredefinedShellObjectAttribute.cs
@@ -9,26 +9,31 @@ namespace SharpShell.Attributes
[AttributeUsage(AttributeTargets.Field)]
internal class PredefinedShellObjectAttribute : Attribute
{
- ///
- /// Initializes a new instance of the class.
- ///
- /// Name of the class in the registry for this object.
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Name of the class in the registry for this object.
public PredefinedShellObjectAttribute(string className)
{
ClassName = className;
}
- ///
- /// Gets the class name for a type with a set, or null if none is set.
- ///
- /// The value.
- ///
- public static string GetClassName(Enum value)
+ ///
+ /// Gets the attribute for a enum type field with a set, or null if none is set.
+ ///
+ /// The value.
+ ///
+ public static PredefinedShellObjectAttribute GetPredefinedShellObjectAttribute(Enum value)
{
var enumType = value.GetType();
var enumValueInfo = enumType.GetField(Enum.GetName(enumType, value));
- var predefinedShellObject = enumValueInfo.GetCustomAttributes(false).OfType().FirstOrDefault();
- return predefinedShellObject?.ClassName;
+
+ var predefinedShellObject = enumValueInfo
+ .GetCustomAttributes(false)
+ .OfType()
+ .FirstOrDefault();
+
+ return predefinedShellObject;
}
///
diff --git a/SharpShell/SharpShell/Attributes/RegistrationNameAttribute.cs b/SharpShell/SharpShell/Attributes/RegistrationNameAttribute.cs
index 998faa63..3e560376 100644
--- a/SharpShell/SharpShell/Attributes/RegistrationNameAttribute.cs
+++ b/SharpShell/SharpShell/Attributes/RegistrationNameAttribute.cs
@@ -1,51 +1,67 @@
using System;
+using System.Linq;
+using SharpShell.ServerRegistration;
namespace SharpShell.Attributes
{
///
- /// Specify the registry key name under which a SharpShell server should be registered.
- /// By default (without this attribute) a server is registered under the classname.
- /// Since each server needs its own registry key name, this attribute does not inherit.
+ /// Specify the registry key name under which a SharpShell server should be registered.
+ /// By default (without this attribute) a server is registered under the classname.
+ /// Since each server needs its own registry key name, this attribute does not inherit.
///
[AttributeUsage(AttributeTargets.Class)]
+ [Serializable]
public class RegistrationNameAttribute : Attribute
{
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
- /// The registry key name under which the SharpShell server should be registered. Cannot be null or whitespace.
+ ///
+ /// The registry key name under which the SharpShell server should be registered. Cannot be
+ /// null or whitespace.
+ ///
public RegistrationNameAttribute(string registrationName)
{
if (string.IsNullOrWhiteSpace(registrationName))
- throw new ArgumentException("registrationName");
+ {
+ throw new ArgumentException(nameof(registrationName));
+ }
+
RegistrationName = registrationName;
}
///
- /// Gets the registry key name under which to register the SharpShell server.
+ /// Gets the registry key name under which to register the SharpShell server.
///
- public string RegistrationName { get; private set; }
+ public string RegistrationName { get; }
///
- /// Gets the registration name for a type if defined.
+ /// Gets the registration name attribute for a type if defined, otherwise returns null.
///
/// The type.
- /// The registration name of the type if defined, or null otherwise.
- public static string GetRegistrationName(Type type)
+ /// The registration name of the type if defined, or
+ /// null
+ /// otherwise.
+ ///
+ public static RegistrationNameAttribute GetRegistrationNameAttribute(Type type)
{
- foreach (RegistrationNameAttribute attribute in type.GetCustomAttributes(typeof(RegistrationNameAttribute), false))
- return attribute.RegistrationName;
- return null;
- }
+ var attribute = ServerSandBox
+ .GetAttributesSafe(type, nameof(RegistrationNameAttribute), false)
+ .FirstOrDefault();
- ///
- /// Gets the registration name for a type.
- ///
- /// The type.
- /// The registration name of the type if defined, or type.Name otherwise.
- public static string GetRegistrationNameOrTypeName(Type type)
- {
- return GetRegistrationName(type) ?? type.Name;
+ if (attribute == null)
+ {
+ return null;
+ }
+
+ var registrationName = ServerSandBox.GetStringPropertySafe(attribute, nameof(RegistrationName));
+
+ if (registrationName != null)
+ {
+ return new RegistrationNameAttribute(registrationName);
+ }
+
+ return null;
}
}
-}
+}
\ No newline at end of file
diff --git a/SharpShell/SharpShell/Attributes/ServerTypeAttribute.cs b/SharpShell/SharpShell/Attributes/ServerTypeAttribute.cs
index cc9362aa..d00f4b9d 100644
--- a/SharpShell/SharpShell/Attributes/ServerTypeAttribute.cs
+++ b/SharpShell/SharpShell/Attributes/ServerTypeAttribute.cs
@@ -1,5 +1,6 @@
using System;
using System.Linq;
+using SharpShell.ServerRegistration;
namespace SharpShell.Attributes
{
@@ -9,7 +10,8 @@ namespace SharpShell.Attributes
/// classes derived from the decorated class will be able to use
/// the COMServerAssociationAttribute without any extra configuration.
///
- internal class ServerTypeAttribute : Attribute
+ [Serializable]
+ public class ServerTypeAttribute : Attribute
{
///
/// Initializes a new instance of the class.
@@ -22,15 +24,70 @@ public ServerTypeAttribute(ServerType serverType)
}
///
- /// Gets the server type of a type of the association.
+ /// Gets the server type attribute of a type of the association.
///
/// The type.
- /// The ServerType of the type, or None if not set.
- public static ServerType GetServerType(Type type)
+ /// The ServerTypeAttribute of the type, or null if not set.
+ public static ServerTypeAttribute GetServerTypeAttribute(Type type)
{
- var attribute = type.GetCustomAttributes(typeof(ServerTypeAttribute), true)
- .OfType().FirstOrDefault();
- return attribute != null ? attribute.ServerType : ServerType.None;
+ var attribute = ServerSandBox
+ .GetAttributesSafe(type, nameof(ServerTypeAttribute), true)
+ .FirstOrDefault();
+
+ if (attribute == null)
+ {
+ return null;
+ }
+
+ var serverType = ServerSandBox.GetByValPropertySafe(attribute, nameof(ServerType));
+
+ if (serverType != null)
+ {
+ return new ServerTypeAttribute(serverType.Value);
+ }
+
+ return null;
+ }
+
+ public ShellExtensionType ShellExtensionType
+ {
+ get
+ {
+ switch (ServerType)
+ {
+ case ServerType.ShellContextMenu:
+
+ return ShellExtensionType.ShellContextMenu;
+ case ServerType.ShellPropertySheet:
+
+ return ShellExtensionType.ShellPropertySheet;
+ case ServerType.ShellIconHandler:
+
+ return ShellExtensionType.ShellIconHandler;
+ case ServerType.ShellInfoTipHandler:
+
+ return ShellExtensionType.ShellInfoTipHandler;
+ case ServerType.ShellDropHandler:
+
+ return ShellExtensionType.ShellDropHandler;
+ case ServerType.ShellPreviewHandler:
+
+ return ShellExtensionType.ShellPreviewHandler;
+ case ServerType.ShellDataHandler:
+
+ return ShellExtensionType.ShellDataHandler;
+ case ServerType.ShellThumbnailHandler:
+
+ return ShellExtensionType.ShellThumbnailHandler;
+ case ServerType.None:
+ case ServerType.ShellIconOverlayHandler:
+ case ServerType.ShellNamespaceExtension:
+ case ServerType.ShellDeskBand:
+ default:
+
+ return ShellExtensionType.None;
+ }
+ }
}
///
@@ -39,6 +96,6 @@ public static ServerType GetServerType(Type type)
///
/// The type of the server.
///
- public ServerType ServerType { get; private set; }
+ public ServerType ServerType { get; }
}
}
diff --git a/SharpShell/SharpShell/Attributes/SpecialClassKeyAttribute.cs b/SharpShell/SharpShell/Attributes/SpecialClassKeyAttribute.cs
index 8f8bb641..1d1406c1 100644
--- a/SharpShell/SharpShell/Attributes/SpecialClassKeyAttribute.cs
+++ b/SharpShell/SharpShell/Attributes/SpecialClassKeyAttribute.cs
@@ -1,7 +1,5 @@
using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
namespace SharpShell.Attributes
{
@@ -9,7 +7,7 @@ namespace SharpShell.Attributes
/// Allows the special class key to be defined.
///
[AttributeUsage(AttributeTargets.Field)]
- public class SpecialClassKeyAttribute : Attribute
+ internal class SpecialClassKeyAttribute : Attribute
{
///
/// Initializes a new instance of the class.
@@ -20,12 +18,30 @@ public SpecialClassKeyAttribute(string key)
SpecialClassKey = key;
}
+ ///
+ /// Gets the attribute for a enum type field with a set, or null if none is set.
+ ///
+ /// The value.
+ ///
+ public static SpecialClassKeyAttribute GetPredefinedShellObjectAttribute(Enum value)
+ {
+ var enumType = value.GetType();
+ var enumValueInfo = enumType.GetField(Enum.GetName(enumType, value));
+
+ var specialClassKeyAttribute = enumValueInfo
+ .GetCustomAttributes(false)
+ .OfType()
+ .FirstOrDefault();
+
+ return specialClassKeyAttribute;
+ }
+
///
/// Gets the special class key.
///
///
/// The special class key.
///
- public string SpecialClassKey { get; private set; }
+ public string SpecialClassKey { get; }
}
}
diff --git a/SharpShell/SharpShell/Diagnostics/ExplorerConfigurationManager.cs b/SharpShell/SharpShell/Diagnostics/ExplorerConfigurationManager.cs
index 8a0a0f53..f656395f 100644
--- a/SharpShell/SharpShell/Diagnostics/ExplorerConfigurationManager.cs
+++ b/SharpShell/SharpShell/Diagnostics/ExplorerConfigurationManager.cs
@@ -28,9 +28,9 @@ private static bool CheckAlwaysUnloadDll()
var registry = ServiceRegistry.ServiceRegistry.GetService();
using (var localMachine = registry.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default))
- using (var alwaysUnloadDLLKey = localMachine.OpenSubKey(KeyName_AlwaysUnloadDll))
+ using (var alwaysUnloadDllKey = localMachine.OpenSubKey(KeyName_AlwaysUnloadDll))
{
- return alwaysUnloadDLLKey != null;
+ return alwaysUnloadDllKey != null;
}
}
diff --git a/SharpShell/SharpShell/Extensions/EnumExtensions.cs b/SharpShell/SharpShell/Extensions/EnumExtensions.cs
index aa6fe2fc..181b50a4 100644
--- a/SharpShell/SharpShell/Extensions/EnumExtensions.cs
+++ b/SharpShell/SharpShell/Extensions/EnumExtensions.cs
@@ -1,31 +1,28 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-
-namespace SharpShell.Extensions
+using System;
+using System.Linq;
+
+namespace SharpShell.Extensions
{
///
/// Extension methods for enumerations.
///
- public static class EnumExtensions
- {
+ public static class EnumExtensions
+ {
///
/// Gets the first value of an attribute of the given type, or null.
///
/// The attribute type.
/// The enum value.
/// The first value of the given type, or null.
- public static T GetAttribute(this Enum enumValue) where T : Attribute
- {
- var memberInfo = enumValue.GetType().GetMember(enumValue.ToString())
- .FirstOrDefault();
-
- if (memberInfo == null) return null;
-
- var attribute = (T)memberInfo.GetCustomAttributes(typeof(T), false).FirstOrDefault();
- return attribute;
- }
- }
-}
+ public static T GetAttribute(this Enum enumValue) where T : Attribute
+ {
+ var memberInfo = enumValue.GetType().GetMember(enumValue.ToString())
+ .FirstOrDefault();
+
+ if (memberInfo == null) return null;
+
+ var attribute = (T)memberInfo.GetCustomAttributes(typeof(T), false).FirstOrDefault();
+ return attribute;
+ }
+ }
+}
diff --git a/SharpShell/SharpShell/ISharpShellServer.cs b/SharpShell/SharpShell/ISharpShellServer.cs
index 91ee82e4..40c95cc6 100644
--- a/SharpShell/SharpShell/ISharpShellServer.cs
+++ b/SharpShell/SharpShell/ISharpShellServer.cs
@@ -18,7 +18,7 @@ public interface ISharpShellServer
///
/// Gets the server CLSID.
///
- Guid ServerClsid { get; }
+ Guid ServerClassId { get; }
///
/// Gets the display name.
diff --git a/SharpShell/SharpShell/ServerRegistration/ClassRegistration.cs b/SharpShell/SharpShell/ServerRegistration/ClassRegistration.cs
index 6af417e0..f7752b79 100644
--- a/SharpShell/SharpShell/ServerRegistration/ClassRegistration.cs
+++ b/SharpShell/SharpShell/ServerRegistration/ClassRegistration.cs
@@ -1,48 +1,22 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using SharpShell.Attributes;
-using SharpShell.Extensions;
-
-namespace SharpShell.ServerRegistration
+namespace SharpShell.ServerRegistration
{
- ///
- /// Helper class to determine the registration info of specific class.
- ///
+ ///
+ /// Helper class to determine the registration info of specific class.
+ ///
public class ClassRegistration
{
- ///
- /// Initializes a new instance of the class.
- ///
- /// Name of the class.
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Name of the class.
public ClassRegistration(string className)
- {
+ {
ClassName = className;
- lazySpecialRegistryClass = new Lazy(DetermineSpecialRegistryClass);
}
- ///
- /// Determines the special registry class.
- ///
- /// The special registry class, if any.
- private SpecialRegistryClass DetermineSpecialRegistryClass()
- {
- // Create a dictionary of special class key names to special classes.
- Dictionary dic = new Dictionary();
- foreach (SpecialRegistryClass enumValue in Enum.GetValues(typeof(SpecialRegistryClass)))
- {
- var att = enumValue.GetAttribute();
- if (att != null)
- dic[att.SpecialClassKey] = enumValue;
- }
-
- var specialClass = SpecialRegistryClass.None;
- dic.TryGetValue(ClassName, out specialClass);
- return specialClass;
- }
- private readonly Lazy lazySpecialRegistryClass;
+ public SpecialRegistryClass SpecialRegistryClass { get; }
///
/// Gets or sets the name of the class.
diff --git a/SharpShell/SharpShell/ServerRegistration/ManagedAssemblyInfo.cs b/SharpShell/SharpShell/ServerRegistration/ManagedAssemblyInfo.cs
new file mode 100644
index 00000000..6e6776be
--- /dev/null
+++ b/SharpShell/SharpShell/ServerRegistration/ManagedAssemblyInfo.cs
@@ -0,0 +1,156 @@
+using System;
+using System.IO;
+using System.Reflection;
+
+namespace SharpShell.ServerRegistration
+{
+ [Serializable]
+ public sealed class ManagedAssemblyInfo
+ {
+ private readonly string _assemblyPath;
+
+ public ManagedAssemblyInfo(Assembly assembly)
+ {
+ FullName = assembly.FullName;
+ Version = assembly.GetName().Version.ToString();
+ RuntimeVersion = assembly.ImageRuntimeVersion;
+ CodeBase = assembly.CodeBase;
+ IsSigned = assembly.GetName().GetPublicKey()?.Length > 0;
+ }
+
+ public ManagedAssemblyInfo(Type type) : this(type.Assembly)
+ {
+ }
+
+ internal ManagedAssemblyInfo(string fullName, string version, string runtimeVersion, string codeBase)
+ {
+ FullName = fullName;
+ Version = version;
+ RuntimeVersion = runtimeVersion;
+ CodeBase = codeBase;
+
+ try
+ {
+ if (!string.IsNullOrEmpty(AssemblyPath) && File.Exists(AssemblyPath))
+ {
+ var assemblyName = AssemblyName.GetAssemblyName(AssemblyPath);
+ IsSigned = assemblyName.GetPublicKey().Length > 0;
+ }
+ }
+ catch
+ {
+ // ignored
+ }
+ }
+
+ internal ManagedAssemblyInfo(
+ string fullName,
+ string version,
+ string runtimeVersion,
+ string codeBase,
+ bool isSigned)
+ {
+ FullName = fullName;
+ Version = version;
+ RuntimeVersion = runtimeVersion;
+ CodeBase = codeBase;
+ IsSigned = isSigned;
+ }
+
+ internal ManagedAssemblyInfo(
+ string fullName,
+ string version,
+ string runtimeVersion,
+ string codeBase,
+ string assemblyPath)
+ {
+ FullName = fullName;
+ Version = version;
+ RuntimeVersion = runtimeVersion;
+ CodeBase = codeBase;
+ _assemblyPath = assemblyPath;
+
+ try
+ {
+ if (!string.IsNullOrEmpty(AssemblyPath) && File.Exists(AssemblyPath))
+ {
+ var assemblyName = AssemblyName.GetAssemblyName(AssemblyPath);
+ IsSigned = assemblyName.GetPublicKey().Length > 0;
+ }
+ }
+ catch
+ {
+ // ignored
+ }
+ }
+
+ internal ManagedAssemblyInfo(
+ string fullName,
+ string version,
+ string runtimeVersion,
+ string codeBase,
+ bool isSigned,
+ string assemblyPath) : this(fullName, version, runtimeVersion, codeBase, isSigned)
+ {
+ _assemblyPath = assemblyPath;
+ }
+
+ internal ManagedAssemblyInfo(string assemblyPath)
+ {
+ _assemblyPath = assemblyPath;
+
+ try
+ {
+ if (!string.IsNullOrEmpty(AssemblyPath) && File.Exists(AssemblyPath))
+ {
+ var assemblyName = AssemblyName.GetAssemblyName(AssemblyPath);
+ FullName = assemblyName.FullName;
+ Version = assemblyName.Version.ToString();
+ CodeBase = assemblyName.CodeBase;
+ IsSigned = assemblyName.GetPublicKey().Length > 0;
+ RuntimeVersion = "";
+ }
+ }
+ catch
+ {
+ // ignored
+ }
+ }
+
+ internal ManagedAssemblyInfo(Type type, string assemblyPath) : this(type)
+ {
+ _assemblyPath = assemblyPath;
+ }
+
+ public string AssemblyPath
+ {
+ get
+ {
+ if (!string.IsNullOrEmpty(_assemblyPath))
+ {
+ return _assemblyPath;
+ }
+
+ if (!string.IsNullOrEmpty(CodeBase))
+ {
+ try
+ {
+ return new Uri(CodeBase).LocalPath;
+ }
+ catch
+ {
+ // ignored
+ }
+ }
+
+ return null;
+ }
+ }
+
+ public string CodeBase { get; }
+ public string FullName { get; }
+ public bool IsSigned { get; }
+ public string RuntimeVersion { get; }
+ public string Version { get; }
+ }
+}
\ No newline at end of file
diff --git a/SharpShell/SharpShell/ServerRegistration/RegistrationScope.cs b/SharpShell/SharpShell/ServerRegistration/RegistrationScope.cs
new file mode 100644
index 00000000..0a4bfff9
--- /dev/null
+++ b/SharpShell/SharpShell/ServerRegistration/RegistrationScope.cs
@@ -0,0 +1,18 @@
+namespace SharpShell.ServerRegistration
+{
+ ///
+ /// The registration scope.
+ ///
+ public enum RegistrationScope
+ {
+ ///
+ /// 32 Bit operating system registration.
+ ///
+ OS32Bit,
+
+ ///
+ /// 64 Bit operating system registration.
+ ///
+ OS64Bit
+ }
+}
\ No newline at end of file
diff --git a/SharpShell/SharpShell/ServerRegistration/RegistrationType.cs b/SharpShell/SharpShell/ServerRegistration/RegistrationType.cs
deleted file mode 100644
index b6e607e4..00000000
--- a/SharpShell/SharpShell/ServerRegistration/RegistrationType.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace SharpShell.ServerRegistration
-{
- ///
- /// The registation type.
- ///
- public enum RegistrationType
- {
- ///
- /// 32 Bit operating system registration.
- ///
- OS32Bit,
-
- ///
- /// 64 Bit operating system registration.
- ///
- OS64Bit
- }
-}
diff --git a/SharpShell/SharpShell/ServerRegistration/ServerInstallationInfo.cs b/SharpShell/SharpShell/ServerRegistration/ServerInstallationInfo.cs
new file mode 100644
index 00000000..0fa049fb
--- /dev/null
+++ b/SharpShell/SharpShell/ServerRegistration/ServerInstallationInfo.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Linq;
+
+namespace SharpShell.ServerRegistration
+{
+ public class ServerInstallationInfo
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The server class id.
+ internal ServerInstallationInfo(Guid serverClassId)
+ {
+ ServerInstallationType = ServerInstallationType.PartiallyInstalled;
+ ServerClassId = serverClassId;
+ }
+
+ internal ServerInstallationInfo(
+ Guid serverClassId,
+ string serverPath,
+ string threadingModel) : this(serverClassId)
+ {
+ ServerInstallationType = ServerInstallationType.NativeInProcess32;
+ ServerPath = serverPath;
+ ThreadingModel = threadingModel;
+ }
+
+ internal ServerInstallationInfo(
+ Guid serverClassId,
+ string serverPath,
+ string threadingModel,
+ ManagedAssemblyInfo assembly,
+ string managedClassName) : this(serverClassId, serverPath, threadingModel)
+ {
+ ServerInstallationType = ServerInstallationType.ManagedInProcess32;
+ ManagedAssembly = assembly;
+ ManagedClassName = managedClassName;
+ }
+
+ public ManagedAssemblyInfo ManagedAssembly { get; set; }
+
+ ///
+ /// Gets the managed assembly class.
+ ///
+ public string ManagedClassName { get; }
+
+ ///
+ /// Gets the server class id.
+ ///
+ public Guid ServerClassId { get; }
+
+ ///
+ /// Gets the type of the server registration.
+ ///
+ ///
+ /// The type of the server registration.
+ ///
+ public ServerInstallationType ServerInstallationType { get; }
+
+ ///
+ /// Gets the server path.
+ ///
+ public string ServerPath { get; }
+
+ ///
+ /// Gets the threading model.
+ ///
+ public string ThreadingModel { get; }
+
+ public SharpShellServerInfo GetSharpShellServerInformation()
+ {
+ if (ServerInstallationType != ServerInstallationType.ManagedInProcess32 || ManagedAssembly == null)
+ {
+ throw new InvalidOperationException(
+ "This operation can not be completed on a native or partially registered extension."
+ );
+ }
+
+ return SharpShellServerInfo.FromAssembly(ManagedAssembly)
+ .FirstOrDefault(info => info.ClassFullName == ManagedClassName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/SharpShell/SharpShell/ServerRegistration/ServerInstallationType.cs b/SharpShell/SharpShell/ServerRegistration/ServerInstallationType.cs
new file mode 100644
index 00000000..69bb713b
--- /dev/null
+++ b/SharpShell/SharpShell/ServerRegistration/ServerInstallationType.cs
@@ -0,0 +1,23 @@
+namespace SharpShell.ServerRegistration
+{
+ ///
+ /// Represents the type of server registration.
+ ///
+ public enum ServerInstallationType
+ {
+ ///
+ /// The server is partially installed only - there's no process models.
+ ///
+ PartiallyInstalled,
+
+ ///
+ /// It's a native InProc32 server.
+ ///
+ NativeInProcess32,
+
+ ///
+ /// It's a managed InProc32 server.
+ ///
+ ManagedInProcess32
+ }
+}
\ No newline at end of file
diff --git a/SharpShell/SharpShell/ServerRegistration/ServerRegistationType.cs b/SharpShell/SharpShell/ServerRegistration/ServerRegistationType.cs
deleted file mode 100644
index 8e382f71..00000000
--- a/SharpShell/SharpShell/ServerRegistration/ServerRegistationType.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace SharpShell.ServerRegistration
-{
- ///
- /// Represents the type of server registration.
- ///
- public enum ServerRegistationType
- {
- ///
- /// The Server is partially registered only - there's no process models.
- ///
- PartiallyRegistered,
-
- ///
- /// It's a native InProc32 server.
- ///
- NativeInProc32,
-
- ///
- /// It's a managed InProc32 server.
- ///
- ManagedInProc32,
- }
-}
\ No newline at end of file
diff --git a/SharpShell/SharpShell/ServerRegistration/ServerRegistrationManager.cs b/SharpShell/SharpShell/ServerRegistration/ServerRegistrationManager.cs
index 4a73b10b..09e89de9 100644
--- a/SharpShell/SharpShell/ServerRegistration/ServerRegistrationManager.cs
+++ b/SharpShell/SharpShell/ServerRegistration/ServerRegistrationManager.cs
@@ -1,90 +1,316 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Security.AccessControl;
using Microsoft.Win32;
using SharpShell.Attributes;
+using SharpShell.Diagnostics;
using SharpShell.Extensions;
+using SharpShell.Interop;
using SharpShell.Registry;
-
namespace SharpShell.ServerRegistration
{
///
- /// THe Server Registration Manager is an object that can be used to
- /// help with Server Registration tasks, such as registering, unregistering
- /// and checking servers. It will work with SharpShell Server objects or
- /// other servers.
+ /// THe Server Registration Manager is an object that can be used to
+ /// help with Server Registration tasks, such as registering, un-registering
+ /// and checking servers. It will work with SharpShell Server objects or
+ /// other servers.
///
public static class ServerRegistrationManager
{
///
- /// Installs a SharpShell COM server.
+ /// Opens the classes root.
+ ///
+ /// Type of the registration.
+ /// The classes root key.
+ private static IRegistryKey OpenClassesRootKey(RegistrationScope registrationScope)
+ {
+ // Get the registry.
+ var registry = ServiceRegistry.ServiceRegistry.GetService();
+
+ // Get the classes base key.
+ var classesBaseKey = registrationScope == RegistrationScope.OS64Bit
+ ? registry.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry64)
+ : registry.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry32);
+
+ // Return the classes key.
+ return classesBaseKey;
+ }
+
+ #region Installation
+
+ ///
+ /// The classes key name.
+ ///
+ private const string RegistryClassesKeyName = @"CLSID";
+
+ ///
+ /// The InProc32 key name.
+ ///
+ private const string RegistryInProcess32KeyName = @"InprocServer32";
+
+ ///
+ /// The value for the net framework servers.
+ ///
+ private const string RegistryNetFrameworkServerKeyValue = @"mscoree.dll";
+
+ ///
+ /// The threading model key name.
+ ///
+ private const string RegistryThreadingModelValueName = @"ThreadingModel";
+
+ ///
+ /// THe assembly key name.
+ ///
+ private const string RegistryAssemblyValueName = @"Assembly";
+
+ ///
+ /// The class key name.
+ ///
+ private const string RegistryClassValueName = @"Class";
+
+ ///
+ /// The runtime version key name.
+ ///
+ private const string RegistryRuntimeVersionValueName = @"RuntimeVersion";
+
+ ///
+ /// The codebase key name.
+ ///
+ private const string RegistryCodeBaseValueName = @"CodeBase";
+
+ ///
+ /// Gets the server registration info.
+ ///
+ /// Type of the registration.
+ ///
+ /// The ServerRegistrationInfo if the server is registered, otherwise false.
+ ///
+ public static ServerInstallationInfo GetExtensionInstallationInfo(RegistrationScope registrationScope)
+ where T : SharpShellServer
+ {
+ // Call the main function.
+ return GetExtensionInstallationInfo(SharpShellServerInfo.GetServerClassId(), registrationScope);
+ }
+
+ ///
+ /// Gets the server registration info.
+ ///
+ /// The managed server information.
+ /// Type of the registration.
+ ///
+ /// The ServerRegistrationInfo if the server is registered, otherwise false.
+ ///
+ public static ServerInstallationInfo GetExtensionInstallationInfo(
+ SharpShellServerInfo serverInfo,
+ RegistrationScope registrationScope)
+ {
+ // Call the main function.
+ return GetExtensionInstallationInfo(serverInfo.ClassId, registrationScope);
+ }
+
+ ///
+ /// Gets the server registration info.
///
- /// The server.
- /// Type of the registration.
+ /// The server class id.
+ /// Type of the registration.
+ ///
+ /// The ServerRegistrationInfo if the server is registered, otherwise false.
+ ///
+ public static ServerInstallationInfo GetExtensionInstallationInfo(
+ Guid serverClassId,
+ RegistrationScope registrationScope)
+ {
+ // Open the classes.
+ using (var classesKey = OpenInstalledClassesRoot(registrationScope, RegistryKeyPermissionCheck.ReadSubTree))
+ {
+ // Do we have a sub-key for the server?
+ using (var serverClassKey = classesKey.OpenSubKey(serverClassId.ToRegistryString()))
+ {
+ // If there's no sub-key, the server isn't registered.
+ if (serverClassKey == null)
+ {
+ return null;
+ }
+
+ // Do we have an InProc32 server?
+ using (var inProcess32ServerKey = serverClassKey.OpenSubKey(RegistryInProcess32KeyName))
+ {
+ // If we do, we can return the server info for an inProcess32 server.
+ if (inProcess32ServerKey != null)
+ {
+ // Get the default value.
+ var inProcessLibraryName = inProcess32ServerKey.GetValue(null).ToString();
+
+ // If we default value is null or empty, we've got a partially registered server.
+ if (string.IsNullOrEmpty(inProcessLibraryName))
+ {
+ return new ServerInstallationInfo(serverClassId);
+ }
+
+ // Get the threading model.
+ var threadingModel = inProcess32ServerKey.GetValue(RegistryThreadingModelValueName)
+ .ToString();
+
+ // Is it a .NET server?
+ if (inProcessLibraryName == RegistryNetFrameworkServerKeyValue)
+ {
+ // We've got a .NET server. We should have one sub-key, with the assembly version.
+ var assemblyVersionSubKeyPath = inProcess32ServerKey.GetSubKeyNames().FirstOrDefault();
+
+ // If we have no sub-key name, we've got a partially registered server.
+ if (assemblyVersionSubKeyPath == null)
+ {
+ return new ServerInstallationInfo(serverClassId);
+ }
+
+ // Open the assembly sub-key.
+ using (var assemblyVersionSubKey =
+ inProcess32ServerKey.OpenSubKey(assemblyVersionSubKeyPath))
+ {
+ // If we can't open the key, we've got a problem.
+ if (assemblyVersionSubKey == null)
+ {
+ throw new InvalidOperationException("Can't open the details of the server.");
+ }
+
+ // Read the managed server details.
+ var assemblyName = assemblyVersionSubKey.GetValue(RegistryAssemblyValueName)
+ .ToString();
+ var runtimeVersion = assemblyVersionSubKey.GetValue(RegistryRuntimeVersionValueName)
+ .ToString();
+ var codeBase = assemblyVersionSubKey.GetValue(RegistryCodeBaseValueName).ToString();
+
+ var assembly = new ManagedAssemblyInfo(
+ assemblyName,
+ assemblyVersionSubKeyPath,
+ runtimeVersion,
+ codeBase
+ );
+
+ var managedClass = assemblyVersionSubKey.GetValue(RegistryClassValueName)
+ .ToString();
+
+ // Return the managed server info.
+ return new ServerInstallationInfo(
+ serverClassId,
+ inProcessLibraryName,
+ threadingModel,
+ assembly,
+ managedClass
+ );
+ }
+ }
+
+ // We've got a native COM server.
+ return new ServerInstallationInfo(
+ serverClassId,
+ inProcessLibraryName,
+ threadingModel
+ );
+ }
+ }
+
+ // If by this point we haven't return server info, we've got a partially registered server.
+ return new ServerInstallationInfo(serverClassId);
+ }
+ }
+ }
+
+ ///
+ /// Installs a SharpShell COM server.
+ ///
+ /// Type of the registration.
/// if set to true use code base registration (i.e full assembly path, not the GAC).
- public static void InstallServer(ISharpShellServer server, RegistrationType registrationType, bool codeBase)
+ public static void InstallServer(RegistrationScope registrationScope, bool codeBase)
+ where T : SharpShellServer
{
- // Get the server registration information.
- var serverRegistrationInformation = GetServerRegistrationInfo(server, registrationType);
+ InstallServer(SharpShellServerInfo.FromServer(), registrationScope, codeBase);
+ }
+
+ ///
+ /// Installs a SharpShell COM server.
+ ///
+ /// The managed server info.
+ /// Type of the registration.
+ /// if set to true use code base registration (i.e full assembly path, not the GAC).
+ public static void InstallServer(
+ SharpShellServerInfo serverInfo,
+ RegistrationScope registrationScope,
+ bool codeBase)
+ {
+ // Get the server installation information.
+ var serverInstallationInfo = GetExtensionInstallationInfo(serverInfo.ClassId, registrationScope);
+
+ // If it is installed, uninstall first.
+ if (serverInstallationInfo != null)
+ {
+ UninstallServer(serverInfo.ClassId, registrationScope);
+ }
- // If it is registered, unregister first.
- if (serverRegistrationInformation != null)
- UninstallServer(server, registrationType);
-
// Open the classes.
- using (var classesKey = OpenClassesKey(registrationType, RegistryKeyPermissionCheck.ReadWriteSubTree))
+ using (var classesKey =
+ OpenInstalledClassesRoot(registrationScope, RegistryKeyPermissionCheck.ReadWriteSubTree))
{
// Create the server key.
- using (var serverKey = classesKey.CreateSubKey(server.ServerClsid.ToRegistryString()))
+ using (var serverKey = classesKey.CreateSubKey(serverInfo.ClassId.ToRegistryString()))
{
- if(serverKey == null)
+ if (serverKey == null)
+ {
throw new InvalidOperationException("Cannot create server key.");
+ }
// We always set the server key default value to the display name if we can.
- if(!string.IsNullOrEmpty(server.DisplayName))
- serverKey.SetValue(null, server.DisplayName, RegistryValueKind.String);
+ if (serverInfo.IsDisplayNameDefined)
+ {
+ serverKey.SetValue(null, serverInfo.DisplayName, RegistryValueKind.String);
+ }
- // Create the inproc key.
- using (var inproc32Key = serverKey.CreateSubKey(KeyName_InProc32))
+ // Create the process key.
+ using (var inProcess32Key = serverKey.CreateSubKey(RegistryInProcess32KeyName))
{
// Check the key.
- if(inproc32Key == null)
+ if (inProcess32Key == null)
+ {
throw new InvalidOperationException("Cannot create InProc32 key.");
+ }
// Set the .NET value.
- inproc32Key.SetValue(null, KeyValue_NetFrameworkServer);
-
- // Create the values.
- var assemblyVersion = server.GetType().Assembly.GetName().Version.ToString();
- var assemblyFullName = server.GetType().Assembly.FullName;
- var className = server.GetType().FullName;
- var runtimeVersion = server.GetType().Assembly.ImageRuntimeVersion;
- var codeBaseValue = server.GetType().Assembly.CodeBase;
- const string threadingModel = "Both";
-
- // Register all details at server level.
- inproc32Key.SetValue(KeyName_Assembly, assemblyFullName);
- inproc32Key.SetValue(KeyName_Class, className);
- inproc32Key.SetValue(KeyName_RuntimeVersion, runtimeVersion);
- inproc32Key.SetValue(KeyName_ThreadingModel, threadingModel);
+ inProcess32Key.SetValue(null, RegistryNetFrameworkServerKeyValue);
+
+ // Install all details at server level.
+ inProcess32Key.SetValue(RegistryClassValueName, serverInfo.ClassFullName);
+ inProcess32Key.SetValue(RegistryAssemblyValueName, serverInfo.AssemblyInfo.FullName);
+ inProcess32Key.SetValue(RegistryRuntimeVersionValueName,
+ serverInfo.AssemblyInfo.RuntimeVersion);
+ inProcess32Key.SetValue(RegistryThreadingModelValueName, "Both");
+
if (codeBase)
- inproc32Key.SetValue(KeyName_CodeBase, codeBaseValue);
+ {
+ inProcess32Key.SetValue(RegistryCodeBaseValueName, serverInfo.AssemblyInfo.CodeBase);
+ }
// Create the version key.
- using (var versionKey = inproc32Key.CreateSubKey(assemblyVersion))
+ using (var versionKey = inProcess32Key.CreateSubKey(serverInfo.AssemblyInfo.Version))
{
// Check the key.
- if(versionKey == null)
+ if (versionKey == null)
+ {
throw new InvalidOperationException("Cannot create assembly version key.");
+ }
// Set the values.
- versionKey.SetValue(KeyName_Assembly, assemblyFullName);
- versionKey.SetValue(KeyName_Class, className);
- versionKey.SetValue(KeyName_RuntimeVersion, runtimeVersion);
+ versionKey.SetValue(RegistryClassValueName, serverInfo.ClassFullName);
+ versionKey.SetValue(RegistryAssemblyValueName, serverInfo.AssemblyInfo.FullName);
+ versionKey.SetValue(RegistryRuntimeVersionValueName,
+ serverInfo.AssemblyInfo.RuntimeVersion);
+
if (codeBase)
- versionKey.SetValue(KeyName_CodeBase, codeBaseValue);
+ {
+ versionKey.SetValue(RegistryCodeBaseValueName, serverInfo.AssemblyInfo.CodeBase);
+ }
}
}
}
@@ -92,464 +318,712 @@ public static void InstallServer(ISharpShellServer server, RegistrationType regi
}
///
- /// Uninstalls the server.
+ /// Uninstalls the server.
+ ///
+ /// Type of the registration.
+ /// True if the server WAS installed and has been uninstalled, false if the server was not found.
+ public static bool UninstallServer(RegistrationScope registrationScope) where T : SharpShellServer
+ {
+ return UninstallServer(SharpShellServerInfo.FromServer(), registrationScope);
+ }
+
+ ///
+ /// Uninstalls the server.
+ ///
+ /// The managed server info.
+ /// Type of the registration.
+ /// True if the server WAS installed and has been uninstalled, false if the server was not found.
+ public static bool UninstallServer(SharpShellServerInfo serverInfo, RegistrationScope registrationScope)
+ {
+ // Check passed type
+ return UninstallServer(serverInfo.ClassId, registrationScope);
+ }
+
+ ///
+ /// Uninstalls the server.
///
- /// The server.
- /// Type of the registration.
+ /// The server's class id.
+ /// Type of the registration.
/// True if the server WAS installed and has been uninstalled, false if the server was not found.
- public static bool UninstallServer(ISharpShellServer server, RegistrationType registrationType)
+ public static bool UninstallServer(Guid serverClassId, RegistrationScope registrationScope)
{
// Open classes.
- using (var classesKey = OpenClassesKey(registrationType, RegistryKeyPermissionCheck.ReadWriteSubTree))
+ using (var classesKey =
+ OpenInstalledClassesRoot(registrationScope, RegistryKeyPermissionCheck.ReadWriteSubTree))
{
- var subKeyTreeName = server.ServerClsid.ToRegistryString();
+ var serverSubKeyPath = serverClassId.ToRegistryString();
+
+ // If the sub-key doesn't exist, we can return false - we're already uninstalled.
+ using (var serverSubKey = classesKey.OpenSubKey(serverSubKeyPath, false))
+ {
+ if (serverSubKey == null)
+ {
+ return false;
+ }
+ }
- // If the subkey doesn't exist, we can return false - we're already uninstalled.
- if (classesKey.GetSubKeyNames().Any(skn => skn.Equals(subKeyTreeName, StringComparison.OrdinalIgnoreCase)) == false)
- return false;
+ // Delete the sub-key tree.
+ classesKey.DeleteSubKeyTree(serverSubKeyPath);
- // Delete the subkey tree.
- classesKey.DeleteSubKeyTree(subKeyTreeName);
return true;
}
}
///
- /// Registers a SharpShell server. This will create the associations defined by the
- /// server's COMServerAssociation attribute.
+ /// Opens the classes key.
+ ///
+ /// Type of the registration.
+ /// The permissions.
+ ///
+ private static IRegistryKey OpenInstalledClassesRoot(
+ RegistrationScope registrationScope,
+ RegistryKeyPermissionCheck permissions)
+ {
+ // Open classes.
+ return OpenClassesRootKey(registrationScope)?
+ .OpenSubKey(
+ RegistryClassesKeyName,
+ permissions,
+ RegistryRights.QueryValues | RegistryRights.ReadPermissions | RegistryRights.EnumerateSubKeys
+ ) ??
+ throw new InvalidOperationException("Cannot open classes.");
+ }
+
+ #endregion
+
+ #region Registration
+
+ ///
+ /// The default icon key name.
+ ///
+ private const string RegistryDefaultIconKeyName = @"DefaultIcon";
+
+ ///
+ /// The default icon backup value name.
+ ///
+ private const string RegistryDefaultIconBackupValueName = @"SharpShell_Backup_DefaultIcon";
+
+ ///
+ /// Registers a SharpShell server. This will create the associations defined by the
+ /// server's COMServerAssociation attribute.
+ ///
+ /// Type of the registration.
+ public static void RegisterAndApproveServer(RegistrationScope registrationScope) where T : SharpShellServer
+ {
+ RegisterAndApproveServer(SharpShellServerInfo.FromServer(), registrationScope);
+ }
+
+ ///
+ /// Registers a SharpShell server. This will create the associations defined by the
+ /// server's COMServerAssociation attribute.
///
- /// The server.
- /// Type of the registration.
- public static void RegisterServer(ISharpShellServer server, RegistrationType registrationType)
+ /// The managed server info.
+ /// Type of the registration.
+ public static void RegisterAndApproveServer(
+ SharpShellServerInfo serverInfo,
+ RegistrationScope registrationScope)
{
// Pass the server type to the SharpShellServer internal registration function and let it
// take over from there.
- SharpShellServer.DoRegister(server.GetType(), registrationType);
+ InternalRegisterServer(serverInfo, registrationScope);
// Approve the extension.
- ApproveExtension(server, registrationType);
+ ApproveExtension(serverInfo, registrationScope);
}
///
- /// Unregisters a SharpShell server. This will remove the associations defined by the
- /// server's COMServerAssociation attribute.
+ /// Actually performs registration. The ComRegisterFunction decorated method will call this function
+ /// internally with the flag appropriate for the operating system processor architecture.
+ /// However, this function can also be called manually if needed.
///
- /// The server.
- /// Type of the registration to undo.
- public static void UnregisterServer(ISharpShellServer server, RegistrationType registrationType)
+ /// The managed server info.
+ /// Type of the registration.
+ private static void InternalRegisterServer(SharpShellServerInfo serverInfo, RegistrationScope registrationScope)
{
- // Unapprove the extension.
- UnapproveExtension(server, registrationType);
+ Logging.Log(
+ $"Preparing to register SharpShell Server {serverInfo.DisplayName} in scope {registrationScope}.");
- // Pass the server type to the SharpShellServer internal unregistration function and let it
+
+ // Register the server associations
+ if (serverInfo.ShellExtensionType != ShellExtensionType.None)
+ {
+ // Get the association data.
+ var associationClassNames =
+ registrationScope == RegistrationScope.OS64Bit
+ ? serverInfo.AssociationClassNamesX64
+ : serverInfo.AssociationClassNamesX32;
+
+ if (associationClassNames?.Any() == true)
+ {
+ foreach (var associationClassName in associationClassNames)
+ {
+ RegisterShellExtensionAssociation(
+ serverInfo.ClassId,
+ serverInfo.ShellExtensionType,
+ serverInfo.RegistrationName,
+ associationClassName,
+ registrationScope
+ );
+ }
+ }
+ }
+
+ // Execute the custom register function, if there is one.
+ try
+ {
+ serverInfo.InvokeCustomRegisterMethodIfExists(registrationScope);
+ }
+ catch (Exception e)
+ {
+ Logging.Error("Custom register function failed.", e);
+ }
+
+ // Notify the shell we've updated associations.
+ Shell32.SHChangeNotify(Shell32.SHCNE_ASSOCCHANGED, 0, IntPtr.Zero, IntPtr.Zero);
+ Logging.Log($"Registration of {serverInfo.DisplayName} completed.");
+ }
+
+ ///
+ /// Un-registers a SharpShell server. This will remove the associations defined by the
+ /// server's COMServerAssociation attribute.
+ ///
+ /// Type of the registration to undo.
+ public static void UnregisterAndUnApproveServer(RegistrationScope registrationScope)
+ where T : SharpShellServer
+ {
+ UnregisterAndUnApproveServer(SharpShellServerInfo.FromServer(), registrationScope);
+ }
+
+ ///
+ /// Un-registers a SharpShell server. This will remove the associations defined by the
+ /// server's COMServerAssociation attribute.
+ ///
+ /// The server type.
+ /// Type of the registration to undo.
+ public static void UnregisterAndUnApproveServer(
+ SharpShellServerInfo serverInfo,
+ RegistrationScope registrationScope)
+ {
+ // Un-approve the extension.
+ UnApproveExtension(serverInfo.ClassId, registrationScope);
+
+ // Pass the server type to the SharpShellServer internal un-registration function and let it
// take over from there.
- SharpShellServer.DoUnregister(server.GetType(), registrationType);
+ InternalUnregisterServer(serverInfo, registrationScope);
+ }
+
+ ///
+ /// Un-registers a SharpShell server. This will remove the associations defined by the
+ /// server's COMServerAssociation attribute.
+ ///
+ /// The server class id.
+ /// Type of the registration to undo.
+ public static void UnregisterAndUnApproveServer(Guid serverClassId, RegistrationScope registrationScope)
+ {
+ // Un-approve the extension.
+ UnApproveExtension(serverClassId, registrationScope);
+
+ var associations = GetExtensionRegistrationInfo(serverClassId, registrationScope);
+
+ if (associations == null)
+ {
+ return;
+ }
+
+ foreach (var association in associations.Associations)
+ {
+ UnregisterShellExtensionAssociation(
+ association.ShellExtensionType,
+ association.RegistrationName,
+ association.AssociationClassName,
+ registrationScope
+ );
+ }
+ }
+
+ ///
+ /// Actually performs un-registration. The ComUnregisterFunction decorated method will call this function
+ /// internally with the flag appropriate for the operating system processor architecture.
+ /// However, this function can also be called manually if needed.
+ ///
+ /// The server type.
+ /// Type of the registration to unregister.
+ private static void InternalUnregisterServer(
+ SharpShellServerInfo serverInfo,
+ RegistrationScope registrationScope)
+ {
+ Logging.Log(
+ $"Preparing to unregister SharpShell Server {serverInfo.DisplayName} in scope {registrationScope}");
+
+ // Unregister the server associations
+ if (serverInfo.ShellExtensionType != ShellExtensionType.None)
+ {
+ // Get the association data.
+ var associationClassNames =
+ registrationScope == RegistrationScope.OS64Bit
+ ? serverInfo.AssociationClassNamesX64
+ : serverInfo.AssociationClassNamesX32;
+
+ if (associationClassNames?.Any() == true)
+ {
+ foreach (var associationClassName in associationClassNames)
+ {
+ UnregisterShellExtensionAssociation(
+ serverInfo.ShellExtensionType,
+ serverInfo.RegistrationName,
+ associationClassName,
+ registrationScope
+ );
+ }
+ }
+ }
+
+ // Execute the custom unregister function, if there is one.
+ try
+ {
+ serverInfo.InvokeCustomUnRegisterMethodIfExists(registrationScope);
+ }
+ catch (Exception e)
+ {
+ Logging.Error("Custom unregister function failed.", e);
+ }
+
+ // Notify the shell we've updated associations.
+ Shell32.SHChangeNotify(Shell32.SHCNE_ASSOCCHANGED, 0, IntPtr.Zero, IntPtr.Zero);
+ Logging.Log($"Un-registration of {serverInfo.DisplayName} completed.");
}
///
- /// Enumerates Shell extensions.
+ /// Enumerates shell extensions registered for a class.
///
- /// Type of the registration.
- /// The shell extension types.
+ /// The class name to return registered shell extensions
+ /// Type of the registration.
///
- public static IEnumerable EnumerateExtensions(RegistrationType registrationType, ShellExtensionType shellExtensionTypes)
+ public static IEnumerable EnumerateRegisteredAssociations(
+ string associationClassName,
+ RegistrationScope registrationScope)
{
- var shellExtensionsGuidMap = new Dictionary();
+ // Go through every shell extension type.
- // Go through all classes.
- using (var classes = OpenClassesRoot(registrationType))
+ return EnumerateRegisteredAssociations(
+ associationClassName,
+ registrationScope,
+ Enum.GetValues(typeof(ShellExtensionType)).OfType()
+ );
+ }
+
+ ///
+ /// Enumerates shell extensions registered for a class.
+ ///
+ /// The class name to return registered shell extensions
+ /// Type of the registration.
+ /// Shell extension types to filter with.
+ ///
+ public static IEnumerable EnumerateRegisteredAssociations(
+ string associationClassName,
+ RegistrationScope registrationScope,
+ IEnumerable extensionTypes)
+ {
+ using (var classesKey = OpenClassesRootKey(registrationScope))
{
- // Read each subkey.
- foreach (var className in classes.GetSubKeyNames().Where(cn => !cn.StartsWith("{")))
+ foreach (var extensionType in extensionTypes)
{
- // Go through every shell extension type.
- foreach (ShellExtensionType shellExtensionType in Enum.GetValues(typeof (ShellExtensionType)))
+ // Get handler attribute
+ var handlerAttribute = HandlerSubKeyAttribute.GetHandlerSubKeyAttribute(extensionType);
+
+ // Ignore invalid or null handlers
+ if (string.IsNullOrEmpty(handlerAttribute?.HandlerSubKey))
{
- // Get the handler subkey.
- var handlerSubkey = shellExtensionType.GetAttribute();
+ continue;
+ }
- if(handlerSubkey == null)
- continue;
+ // Get the handler sub-key.
+ var handlerSubKeyRoot = $"{associationClassName}\\ShellEx\\{handlerAttribute.HandlerSubKey}";
- // Check for the subkey.
- if (handlerSubkey.AllowMultipleEntries)
+ using (var handlerSubKey = classesKey.OpenSubKey(
+ handlerSubKeyRoot,
+ RegistryKeyPermissionCheck.ReadSubTree,
+ RegistryRights.ReadKey | RegistryRights.QueryValues
+ ))
+ {
+ // Skip empty handlers.
+ if (handlerSubKey == null)
{
- // Do we have the single subkey?
- var handlerKeyPath = $"{className}\\ShellEx\\{handlerSubkey.HandlerSubkey}";
- using (var handlerSubKey = classes.OpenSubKey(handlerKeyPath, RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey | RegistryRights.QueryValues))
- {
- // Skip empty handlers.
- if (handlerSubKey == null) continue;
+ yield break;
+ }
- // Read entries.
- foreach (var entry in handlerSubKey.GetSubKeyNames())
+ if (handlerAttribute.AllowMultipleEntries) // We should check for multiple sub-keys
+ {
+ // Read sub-keys.
+ foreach (var entrySubKeyName in handlerSubKey.GetSubKeyNames())
+ {
+ using (var entrySubKey = handlerSubKey.OpenSubKey(
+ entrySubKeyName,
+ RegistryKeyPermissionCheck.ReadSubTree,
+ RegistryRights.QueryValues | RegistryRights.ReadKey
+ ))
{
- using (var entryKey = handlerSubKey.OpenSubKey(entry, RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.QueryValues | RegistryRights.ReadKey))
+ var serverClassIdValue = entrySubKey.GetValue(null, string.Empty).ToString();
+
+ if (Guid.TryParse(serverClassIdValue, out var serverClassId) == false)
{
- var guidVal = entryKey.GetValue(null, string.Empty).ToString();
-
- Guid guid;
- if (Guid.TryParse(guidVal, out guid) == false)
- continue;
- System.Diagnostics.Trace.WriteLine(string.Format("{0} has {3} {1} guid {2}", className,
- shellExtensionType.ToString(), guid, entry));
-
- // If we do not have a shell extension info for this extension, create one.
- if (!shellExtensionsGuidMap.ContainsKey(guid))
- {
- shellExtensionsGuidMap[guid] = new ShellExtensionRegistrationInfo
- {
- DisplayName = entry,
- ShellExtensionType = shellExtensionType,
- ServerCLSID = guid,
- };
- }
-
- // Add the class association.
- shellExtensionsGuidMap[guid].classRegistrations.Add(new ClassRegistration(className));
+ continue;
}
+
+ Trace.WriteLine(string.Format(
+ "Class {0} has {1} with id {2} ({3})",
+ associationClassName,
+ extensionType.ToString(),
+ serverClassId,
+ entrySubKeyName
+ ));
+
+ yield return new ShellExtensionRegisteredAssociationInfo(
+ extensionType, serverClassId, associationClassName, entrySubKeyName
+ );
}
}
}
- else
+ else // We should check the root handler sub-key
{
- // Do we have the single subkey?
- var handlerKeyPath = string.Format("{0}\\ShellEx\\{1}", className, handlerSubkey.HandlerSubkey);
- using (var handlerSubKey = classes.OpenSubKey(handlerKeyPath, RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey | RegistryRights.QueryValues))
+ var serverClassIdValue = handlerSubKey.GetValue(null, string.Empty).ToString();
+
+ if (Guid.TryParse(serverClassIdValue, out var serverClassId) == false)
{
- if (handlerSubKey != null)
- {
- var guidVal = handlerSubKey.GetValue(null, string.Empty).ToString();
+ yield break;
+ }
- Guid guid;
- if (Guid.TryParse(guidVal, out guid) == false)
- continue;
- System.Diagnostics.Trace.WriteLine(string.Format("{0} has {1} guid {2}", className,
- shellExtensionType.ToString(), guid));
-
- // If we do not have a shell extension info for this extension, create one.
- if (!shellExtensionsGuidMap.ContainsKey(guid))
- {
- shellExtensionsGuidMap[guid] = new ShellExtensionRegistrationInfo
- {
- ShellExtensionType = shellExtensionType,
- ServerCLSID = guid,
- };
- }
+ Trace.WriteLine(string.Format(
+ "Class {0} has {1} with id {2}",
+ associationClassName,
+ extensionType.ToString(),
+ serverClassId
+ ));
- // Add the class association.
- shellExtensionsGuidMap[guid].classRegistrations.Add(new ClassRegistration(className));
- }
- }
+ yield return new ShellExtensionRegisteredAssociationInfo(
+ extensionType, serverClassId, associationClassName
+ );
}
}
}
}
+ }
+
+ ///
+ /// Enumerates Shell extensions.
+ ///
+ /// Type of the registration.
+ ///
+ public static IEnumerable EnumerateRegisteredExtensions(
+ RegistrationScope registrationScope)
+ {
+ // Go through all classes.
+ using (var classesKey = OpenClassesRootKey(registrationScope))
+ {
+ return classesKey.GetSubKeyNames()
+ .Where(cn => !cn.StartsWith("{"))
+ .SelectMany(className => EnumerateRegisteredAssociations(className, registrationScope))
+ .GroupBy(info => info.ServerClassId)
+ .Select(group =>
+ {
+ var isApproved = IsExtensionApproved(group.Key, registrationScope);
- return shellExtensionsGuidMap.Values;
+ return new ShellExtensionRegistrationInfo(group.Key, isApproved, group);
+ });
+ }
}
///
- /// Gets the server registration info.
+ /// Get shell extension registration information.
///
- /// The server.
- /// Type of the registration.
- ///
- /// The ServerRegistrationInfo if the server is registered, otherwise false.
- ///
- public static ShellExtensionRegistrationInfo GetServerRegistrationInfo(ISharpShellServer server, RegistrationType registrationType)
+ /// Type of the registration.
+ ///
+ public static ShellExtensionRegistrationInfo GetExtensionRegistrationInfo(
+ RegistrationScope registrationScope) where T : SharpShellServer
{
- // Call the main function.
- return GetServerRegistrationInfo(server.ServerClsid, registrationType);
+ return GetExtensionRegistrationInfo(SharpShellServerInfo.FromServer(), registrationScope);
}
///
- /// Gets the server registration info.
+ /// Get shell extension registration information.
///
- /// The server CLSID.
- /// Type of the registration.
- ///
- /// The ServerRegistrationInfo if the server is registered, otherwise false.
- ///
- public static ShellExtensionRegistrationInfo GetServerRegistrationInfo(Guid serverCLSID, RegistrationType registrationType)
+ /// The managed server info
+ /// Type of the registration.
+ ///
+ public static ShellExtensionRegistrationInfo GetExtensionRegistrationInfo(
+ SharpShellServerInfo serverInfo,
+ RegistrationScope registrationScope)
{
- // We can very quickly check to see if the server is approved.
- bool serverApproved = IsExtensionApproved(serverCLSID, registrationType);
+ IEnumerable associations =
+ new ShellExtensionRegisteredAssociationInfo[0];
- // Open the classes.
- using (var classesKey = OpenClassesKey(registrationType, RegistryKeyPermissionCheck.ReadSubTree))
+ if (serverInfo.ShellExtensionType != ShellExtensionType.None)
{
- // Do we have a subkey for the server?
- using (var serverClassKey = classesKey.OpenSubKey(serverCLSID.ToRegistryString()))
+ // Get the association data.
+ var associationClassNames =
+ registrationScope == RegistrationScope.OS64Bit
+ ? serverInfo.AssociationClassNamesX64
+ : serverInfo.AssociationClassNamesX32;
+
+ if (associationClassNames.Any())
{
- // If there's no subkey, the server isn't registered.
- if (serverClassKey == null)
- return null;
+ associations = associationClassNames.SelectMany(className =>
+ EnumerateRegisteredAssociations(className, registrationScope,
+ new[] {serverInfo.ShellExtensionType})
+ .Where(info => info.ServerClassId == serverInfo.ClassId)
+ );
+ }
+ }
- // Do we have an InProc32 server?
- using(var inproc32ServerKey = serverClassKey.OpenSubKey(KeyName_InProc32))
- {
- // If we do, we can return the server info for an inproc 32 server.
- if (inproc32ServerKey != null)
- {
- // Get the default value.
- var defaultValue = GetValueOrEmpty(inproc32ServerKey, null);
+ var isApproved = IsExtensionApproved(serverInfo.ClassId, registrationScope);
- // If we default value is null or empty, we've got a partially registered server.
- if (string.IsNullOrEmpty(defaultValue))
- return new ShellExtensionRegistrationInfo(ServerRegistationType.PartiallyRegistered, serverCLSID);
+ return new ShellExtensionRegistrationInfo(serverInfo.ClassId, isApproved, associations);
+ }
- // Get the threading model.
- var threadingModel = GetValueOrEmpty(inproc32ServerKey, KeyName_ThreadingModel);
+ ///
+ /// Get shell extension registration information.
+ ///
+ /// The server class id
+ /// Type of the registration.
+ ///
+ public static ShellExtensionRegistrationInfo GetExtensionRegistrationInfo(
+ Guid serverClassId,
+ RegistrationScope registrationScope)
+ {
+ // Go through all classes.
+ using (var classesKey = OpenClassesRootKey(registrationScope))
+ {
+ var associations = classesKey.GetSubKeyNames()
+ .Where(cn => !cn.StartsWith("{"))
+ .SelectMany(className => EnumerateRegisteredAssociations(className, registrationScope))
+ .Where(info => info.ServerClassId == serverClassId);
- // Is it a .NET server?
- if (defaultValue == KeyValue_NetFrameworkServer)
- {
- // We've got a .NET server. We should have one subkey, with the assembly version.
- var subkeyName = inproc32ServerKey.GetSubKeyNames().FirstOrDefault();
+ var isApproved = IsExtensionApproved(serverClassId, registrationScope);
- // If we have no subkey name, we've got a partially registered server.
- if (subkeyName == null)
- return new ShellExtensionRegistrationInfo(ServerRegistationType.PartiallyRegistered, serverCLSID);
+ return new ShellExtensionRegistrationInfo(serverClassId, isApproved, associations);
+ }
+ }
- // Otherwise we now have the assembly version.
- var assemblyVersion = subkeyName;
+ ///
+ /// Registers the server associations.
+ ///
+ /// The server's class id.
+ /// Type of the server.
+ /// Name of the server.
+ /// The association class name.
+ /// Type of the registration.
+ internal static void RegisterShellExtensionAssociation(
+ Guid serverClassId,
+ ShellExtensionType extensionType,
+ string registrationName,
+ string associationClassName,
+ RegistrationScope registrationScope)
+ {
+ using (var classesKey = OpenClassesRootKey(registrationScope))
+ {
+ var attribute = HandlerSubKeyAttribute.GetHandlerSubKeyAttribute(extensionType);
- // Open the assembly subkey.
- using (var assemblySubkey = inproc32ServerKey.OpenSubKey(assemblyVersion))
- {
- // If we can't open the key, we've got a problem.
- if (assemblySubkey == null)
- throw new InvalidOperationException("Can't open the details of the server.");
+ if (attribute == null)
+ {
+ throw new ArgumentException("This server type does not have a handler sub key.",
+ nameof(extensionType));
+ }
- // Read the managed server details.
- var assembly = GetValueOrEmpty(assemblySubkey, KeyName_Assembly);
- var @class = GetValueOrEmpty(assemblySubkey, KeyName_Class);
- var runtimeVersion = GetValueOrEmpty(assemblySubkey, KeyName_RuntimeVersion);
- var codeBase = assemblySubkey.GetValue(KeyName_CodeBase, null);
-
- // Return the server info.
- return new ShellExtensionRegistrationInfo(ServerRegistationType.ManagedInProc32, serverCLSID)
- {
- ThreadingModel = threadingModel,
- Assembly = assembly,
- AssemblyVersion = assemblyVersion,
- Class = @class,
- RuntimeVersion = runtimeVersion,
- CodeBase = codeBase != null ? codeBase.ToString() : null,
- IsApproved = serverApproved
- };
- }
- }
+ var subKeyName = attribute.HandlerSubKey;
- // We've got a native COM server.
+ if (string.IsNullOrEmpty(subKeyName))
+ {
+ return;
+ }
- // Return the server info.
- return new ShellExtensionRegistrationInfo(ServerRegistationType.NativeInProc32, serverCLSID)
- {
- ThreadingModel = threadingModel,
- ServerPath = defaultValue,
- IsApproved = serverApproved
- };
- }
- }
+ var associationKeyPath = $"{associationClassName}\\ShellEx\\{subKeyName}";
- // If by this point we haven't return server info, we've got a partially registered server.
- return new ShellExtensionRegistrationInfo(ServerRegistationType.PartiallyRegistered, serverCLSID);
+ if (attribute.AllowMultipleEntries)
+ {
+ associationKeyPath += $"\\{registrationName}";
}
- }
- }
- ///
- /// Sets the display name of the a COM server.
- ///
- /// The class identifier.
- /// The display name.
- /// Type of the registration.
- ///
- public static void SetServerDisplayName(Guid classId, string displayName, RegistrationType registrationType)
- {
- // Open the classes.
- using (var classesKey = OpenClassesKey(registrationType, RegistryKeyPermissionCheck.ReadWriteSubTree))
- {
// Create the server key.
- using (var serverKey = classesKey.OpenSubKey(classId.ToRegistryString(), RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.SetValue))
+ using (var serverKey = classesKey.CreateSubKey(associationKeyPath))
{
- if (serverKey == null)
- throw new InvalidOperationException($"Cannot open class id key {classId}");
+ // Set the server class id.
+ serverKey?.SetValue(null, serverClassId.ToRegistryString());
+ }
- // Set the display name.
- serverKey.SetValue(null, displayName, RegistryValueKind.String);
+ // If we're a shell icon handler, we must also set the default icon.
+ if (extensionType == ShellExtensionType.ShellIconHandler)
+ {
+ SetIconHandlerDefaultIcon(registrationScope, associationClassName);
}
}
}
///
- /// Registers the server associations.
+ /// Sets the icon handler default icon, enabling an icon handler extension.
///
- /// The server CLSID.
- /// Type of the server.
- /// Name of the server.
- /// The association attributes.
- /// Type of the registration.
- internal static void RegisterServerAssociations(Guid serverClsid, ServerType serverType, string serverName,
- IEnumerable associationAttributes, RegistrationType registrationType)
+ /// Type of the registration.
+ /// Association class name.
+ private static void SetIconHandlerDefaultIcon(RegistrationScope registrationScope, string associationClassName)
{
- // Go through each association.
- foreach (var associationAttribute in associationAttributes)
+ using (var classesKey = OpenClassesRootKey(registrationScope))
{
- // Get the association classes.
- var associationClassNames = CreateClassNamesForAssociations(associationAttribute.AssociationType,
- associationAttribute.Associations, registrationType);
-
- // Open the classes key.
- using (var classesKey = OpenClassesRoot(registrationType))
+ // Open the class.
+ using (var classKey = classesKey.OpenSubKey(associationClassName))
{
- // For each one, create the server type key.
- foreach (var associationClassName in associationClassNames)
+ // Check we have the class.
+ if (classKey == null)
{
- // Create the server key.
- using (var serverKey = classesKey.CreateSubKey(GetKeyForServerType(associationClassName, serverType, serverName)))
+ throw new InvalidOperationException("Cannot open class " + associationClassName);
+ }
+
+ // Open the default icon.
+ using (var defaultIconKey = classKey.OpenSubKey(
+ RegistryDefaultIconKeyName,
+ RegistryKeyPermissionCheck.ReadWriteSubTree,
+ RegistryRights.ReadKey | RegistryRights.WriteKey
+ ))
+ {
+ // Check we have the key.
+ if (defaultIconKey == null)
{
- // Set the server class id.
- if (serverKey != null)
- serverKey.SetValue(null, serverClsid.ToRegistryString());
+ // if not, we create the key.
+ var tempDefaultIconKey = classesKey.CreateSubKey(
+ associationClassName + @"\" + RegistryDefaultIconKeyName,
+ RegistryKeyPermissionCheck.ReadWriteSubTree
+ );
+ tempDefaultIconKey.SetValue(null, "%1");
}
+ else
+ {
+ // Get the default icon.
+ var defaultIcon = defaultIconKey.GetValue(null, string.Empty).ToString();
- // If we're a shell icon handler, we must also set the defaulticon.
- if (serverType == ServerType.ShellIconHandler)
- SetIconHandlerDefaultIcon(classesKey, associationClassName);
+ // Save the default icon.
+ defaultIconKey.SetValue(RegistryDefaultIconBackupValueName, defaultIcon);
+ defaultIconKey.SetValue(null, "%1");
+ }
}
}
}
}
///
- /// Sets the icon handler default icon, enabling an icon handler extension.
+ /// Un-sets the icon handler default icon sharp shell value, restoring the backed up value.
///
- /// The classes key.
- /// Name of the class.
- private static void SetIconHandlerDefaultIcon(IRegistryKey classesKey, string className)
+ /// Type of the registration.
+ /// Name of the class.
+ private static void UnsetIconHandlerDefaultIcon(
+ RegistrationScope registrationScope,
+ string associationClassName)
{
- // Open the class.
- using (var classKey = classesKey.OpenSubKey(className))
+ using (var classesKey = OpenClassesRootKey(registrationScope))
{
- // Check we have the class.
- if(classKey == null)
- throw new InvalidOperationException("Cannot open class " + className);
-
- // Open the default icon.
- using (var defaultIconKey = classKey.OpenSubKey(KeyName_DefaultIcon, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.ReadKey | RegistryRights.WriteKey))
+ // Open the class.
+ using (var classKey = classesKey.OpenSubKey(associationClassName))
{
- // Check we have the key.
- if (defaultIconKey == null)
+ // Check we have the class.
+ if (classKey == null)
{
- // if not, we create the key.
- var tempDefaultIconKey = classesKey.CreateSubKey(className + @"\" + KeyName_DefaultIcon, RegistryKeyPermissionCheck.ReadWriteSubTree);
- tempDefaultIconKey.SetValue(null, "%1");
- }
- else
+ throw new InvalidOperationException("Cannot open class " + associationClassName);
+ }
+
+ // Open the default icon.
+ using (var defaultIconKey = classKey.OpenSubKey(
+ RegistryDefaultIconKeyName,
+ RegistryKeyPermissionCheck.ReadWriteSubTree,
+ RegistryRights.ReadKey | RegistryRights.WriteKey
+ ))
{
- // Get the default icon.
- var defaultIcon = defaultIconKey.GetValue(null, string.Empty).ToString();
+ // Check we have the key.
+ if (defaultIconKey == null)
+ {
+ throw new InvalidOperationException(
+ "Cannot open default icon key for class " + associationClassName);
+ }
- // Save the default icon.
- defaultIconKey.SetValue(ValueName_DefaultIconBackup, defaultIcon);
- defaultIconKey.SetValue(null, "%1");
+ // Get the backup default icon.
+ var backupDefaultIcon = defaultIconKey.GetValue(RegistryDefaultIconBackupValueName)?.ToString();
+
+ if (backupDefaultIcon != null)
+ {
+ // Save the default icon, delete the backup.
+ defaultIconKey.SetValue(null, backupDefaultIcon);
+ defaultIconKey.DeleteValue(RegistryDefaultIconBackupValueName);
+ }
}
}
}
}
///
- /// Unsets the icon handler default icon sharp shell value, restoring the backed up value.
+ /// Un-registers the server associations.
///
- /// The classes key.
- /// Name of the class.
- private static void UnsetIconHandlerDefaultIcon(IRegistryKey classesKey, string className)
+ /// Type of the shell extension type.
+ /// Name of the server.
+ /// The association class name.
+ /// Type of the registration.
+ private static void UnregisterShellExtensionAssociation(
+ ShellExtensionType extensionType,
+ string registrationName,
+ string associationClassName,
+ RegistrationScope registrationScope)
{
- // Open the class.
- using (var classKey = classesKey.OpenSubKey(className))
+ // Open the classes key...
+ using (var classesKey = OpenClassesRootKey(registrationScope))
{
- // Check we have the class.
- if (classKey == null)
- throw new InvalidOperationException("Cannot open class " + className);
+ var attribute = HandlerSubKeyAttribute.GetHandlerSubKeyAttribute(extensionType);
- // Open the default icon.
- using (var defaultIconKey = classKey.OpenSubKey(KeyName_DefaultIcon, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.ReadKey | RegistryRights.WriteKey))
+ if (attribute == null)
{
- // Check we have the key.
- if (defaultIconKey == null)
- throw new InvalidOperationException("Cannot open default icon key for class " + className);
+ throw new ArgumentException("This server type does not have a handler sub key.",
+ nameof(extensionType));
+ }
- // Do we have a backup default icon to restore?
- if (defaultIconKey.GetValueNames().Any(vm => vm == ValueName_DefaultIconBackup))
- {
- // Get the backup default icon.
- var backupDefaultIcon = defaultIconKey.GetValue(ValueName_DefaultIconBackup, string.Empty).ToString();
+ var subKeyName = attribute.HandlerSubKey;
- // Save the default icon, delete the backup.
- defaultIconKey.SetValue(null, backupDefaultIcon);
- defaultIconKey.DeleteValue(ValueName_DefaultIconBackup);
- }
+ if (string.IsNullOrEmpty(subKeyName))
+ {
+ return;
}
- }
- }
- ///
- /// Unregisters the server associations.
- ///
- /// The server CLSID.
- /// Type of the server.
- /// Name of the server.
- /// The association attributes.
- /// Type of the registration.
- internal static void UnregisterServerAssociations(Guid serverClsid, ServerType serverType, string serverName,
- IEnumerable associationAttributes, RegistrationType registrationType)
- {
- // Go through each association attribute.
- foreach (var associationAttribute in associationAttributes)
- {
- // Get the assocation classes.
- var associationClassNames = CreateClassNamesForAssociations(associationAttribute.AssociationType,
- associationAttribute.Associations, registrationType);
+ // Get the key for the association.
+ var associationKeyPath = $"{associationClassName}\\ShellEx\\{subKeyName}";
- // Open the classes key...
- using (var classesKey = OpenClassesRoot(registrationType))
+ if (attribute.AllowMultipleEntries)
{
- // ...then go through each association class.
- foreach (var associationClassName in associationClassNames)
- {
- // Get the key for the association.
- var associationKeyPath = GetKeyForServerType(associationClassName, serverType, serverName);
+ associationKeyPath += $"\\{registrationName}";
+ }
- // Delete it if it exists.
- classesKey.DeleteSubKeyTree(associationKeyPath, false);
- // If we're a shell icon handler, we must also unset the defaulticon.
- if (serverType == ServerType.ShellIconHandler)
- UnsetIconHandlerDefaultIcon(classesKey, associationClassName);
- }
+ // Delete it if it exists.
+ classesKey.DeleteSubKeyTree(associationKeyPath, false);
+
+ // If we're a shell icon handler, we must also unset the default icon.
+ if (extensionType == ShellExtensionType.ShellIconHandler)
+ {
+ UnsetIconHandlerDefaultIcon(registrationScope, associationClassName);
}
}
}
///
- /// Creates the class names for associations.
+ /// Creates the class names for associations.
///
/// Type of the association.
/// The associations.
- /// Type of the registration.
+ /// Type of the registration.
///
- /// The class names for the associations.
+ /// The class names for the associations.
///
- private static IEnumerable CreateClassNamesForAssociations(AssociationType associationType,
- IEnumerable associations, RegistrationType registrationType)
+ internal static IEnumerable GetAssociationClassNames(
+ AssociationType associationType,
+ IEnumerable associations,
+ RegistrationScope registrationScope)
{
// Switch on the association type.
switch (associationType)
{
- // We are handling the obsolete file extension type for backwards compatiblity.
+ // We are handling the obsolete file extension type for backwards compatibility.
#pragma warning disable 618
case AssociationType.FileExtension:
#pragma warning restore 618
@@ -560,9 +1034,11 @@ private static IEnumerable CreateClassNamesForAssociations(AssociationTy
case AssociationType.ClassOfExtension:
// Open the classes sub key and get or create each file extension classes.
- using (var classesKey = OpenClassesRoot(registrationType))
+ using (var classesKey = OpenClassesRootKey(registrationScope))
{
- return associations.Select(extension => FileExtensionClass.Get(classesKey, extension, true)).ToArray();
+ return associations
+ .Select(extension => FileExtensionClass.Get(classesKey, extension, true))
+ .ToArray();
}
case AssociationType.Class:
@@ -573,250 +1049,108 @@ private static IEnumerable CreateClassNamesForAssociations(AssociationTy
default:
// If this is a predefined shell object, return the class for it.
- var className = PredefinedShellObjectAttribute.GetClassName(associationType);
- if (className != null) return new[] {className};
-
- // It's not a type we know how to deal with, so bail.
- throw new InvalidOperationException($@"Unable to determine associations for AssociationType '{associationType}'");
- }
- }
-
- ///
- /// Gets the type of the key for server.
- ///
- /// Name of the class.
- /// Type of the server.
- /// Name of the server.
- ///
- private static string GetKeyForServerType(string className, ServerType serverType, string serverName)
- {
- // Create the server type name.
- switch (serverType)
- {
- case ServerType.ShellContextMenu:
-
- // Create the key name for a context menu.
- return string.Format(@"{0}\ShellEx\ContextMenuHandlers\{1}", className, serverName);
-
- case ServerType.ShellPropertySheet:
-
- // Create the key name for a property sheet.
- return string.Format(@"{0}\ShellEx\PropertySheetHandlers\{1}", className, serverName);
-
- case ServerType.ShellIconHandler:
-
- // Create the key name for an icon handler. This has no server name,
- // as there cannot be multiple icon handlers.
- return string.Format(@"{0}\ShellEx\IconHandler", className);
-
- case ServerType.ShellInfoTipHandler:
-
- // Create the key name for an info tip handler. This has no server name,
- // as there cannot be multiple info tip handlers.
- return string.Format(@"{0}\ShellEx\{{00021500-0000-0000-C000-000000000046}}", className);
-
- case ServerType.ShellDropHandler:
-
- // Create the key name for a drop handler. This has no server name,
- // as there cannot be multiple drop handlers.
- return string.Format(@"{0}\ShellEx\DropHandler", className);
-
- case ServerType.ShellPreviewHander:
-
- // Create the key name for a preview handler. This has no server name,
- // as there cannot be multiple preview handlers.
- return string.Format(@"{0}\ShellEx\{{8895b1c6-b41f-4c1c-a562-0d564250836f}}", className);
-
- case ServerType.ShellDataHandler:
-
- // Create the key name for a data handler. This has no server name,
- // as there cannot be multiple data handlers.
- return string.Format(@"{0}\ShellEx\DataHandler", className);
-
- case ServerType.ShellThumbnailHandler:
-
- // Create the key name for a thumbnail handler. This has no server name,
- // as there cannot be multiple data handlers.
- return string.Format(@"{0}\ShellEx\{{e357fccd-a995-4576-b01f-234630154e96}}", className);
+ var className = PredefinedShellObjectAttribute.GetPredefinedShellObjectAttribute(associationType)
+ ?.ClassName;
- case ServerType.ShellNamespaceExtension:
+ if (className != null)
+ {
+ return new[] {className};
+ }
- // We don't have a key for shell namespace extensions.
- return null;
-
- default:
- throw new ArgumentOutOfRangeException(nameof(serverType));
+ // It's not a type we know how to deal with, so bail.
+ throw new InvalidOperationException(
+ $@"Unable to determine associations for AssociationType '{associationType}'");
}
}
///
- /// Opens the classes key.
+ /// Approves an extension.
///
- /// Type of the registration.
- /// The permissions.
- ///
- private static IRegistryKey OpenClassesKey(RegistrationType registrationType, RegistryKeyPermissionCheck permissions)
- {
- // Get the classes base key.
- var classesBaseKey = OpenClassesRoot(registrationType);
-
- // Open classes.
- var classesKey = classesBaseKey.OpenSubKey(KeyName_Classes, permissions, RegistryRights.QueryValues | RegistryRights.ReadPermissions | RegistryRights.EnumerateSubKeys);
- if (classesKey == null)
- throw new InvalidOperationException("Cannot open classes.");
-
- return classesKey;
- }
-
- ///
- /// Opens the classes root.
- ///
- /// Type of the registration.
- /// The classes root key.
- private static IRegistryKey OpenClassesRoot(RegistrationType registrationType)
- {
- // Get the registry.
- var registry = ServiceRegistry.ServiceRegistry.GetService();
-
- // Get the classes base key.
- var classesBaseKey = registrationType == RegistrationType.OS64Bit
- ? registry.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry64) :
- registry.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry32);
-
- // Return the classes key.
- return classesBaseKey;
- }
-
- ///
- /// Gets the value or empty.
- ///
- /// The key.
- /// Name of the value.
- ///
- private static string GetValueOrEmpty(IRegistryKey key, string valueName)
- {
- object value = key.GetValue(valueName);
- if (value == null)
- return string.Empty;
- return value.ToString();
- }
-
- ///
- /// Approves an extension.
- ///
- /// The server.
- /// Type of the registration.
- /// Failed to open the Approved Extensions key.
- private static void ApproveExtension(ISharpShellServer server, RegistrationType registrationType)
+ /// The server info.
+ /// Type of the registration.
+ /// Failed to open the Approved Extensions key.
+ private static void ApproveExtension(SharpShellServerInfo serverInfo, RegistrationScope registrationScope)
{
// Open the approved extensions key.
- using(var approvedKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
- registrationType == RegistrationType.OS64Bit ? RegistryView.Registry64 : RegistryView.Registry32)
- .OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved", RegistryKeyPermissionCheck.ReadWriteSubTree))
+ using (var approvedKey = RegistryKey.OpenBaseKey(
+ RegistryHive.LocalMachine,
+ registrationScope == RegistrationScope.OS64Bit ? RegistryView.Registry64 : RegistryView.Registry32
+ ).OpenSubKey(
+ @"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved",
+ RegistryKeyPermissionCheck.ReadWriteSubTree
+ ))
{
// If we can't open the key, we're going to have problems.
- if(approvedKey == null)
+ if (approvedKey == null)
+ {
throw new InvalidOperationException("Failed to open the Approved Extensions key.");
+ }
// Create an entry for the server.
- approvedKey.SetValue(server.ServerClsid.ToRegistryString(), server.DisplayName);
+ approvedKey.SetValue(serverInfo.ClassId.ToRegistryString(), serverInfo.DisplayName);
}
}
///
- /// Determines whether an extension is approved.
+ /// Determines whether an extension is approved.
///
- /// The server CLSID.
- /// Type of the registration.
+ /// The server class id.
+ /// Type of the registration.
///
- /// true if the extension is approved; otherwise, false.
+ /// true if the extension is approved; otherwise, false.
///
- /// Failed to open the Approved Extensions key.
- private static bool IsExtensionApproved(Guid serverClsid, RegistrationType registrationType)
+ /// Failed to open the Approved Extensions key.
+ private static bool IsExtensionApproved(Guid serverClassId, RegistrationScope registrationScope)
{
// Open the approved extensions key.
- using (var approvedKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
- registrationType == RegistrationType.OS64Bit ? RegistryView.Registry64 : RegistryView.Registry32)
- .OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved", RegistryKeyPermissionCheck.ReadSubTree))
+ using (var approvedKey = RegistryKey.OpenBaseKey(
+ RegistryHive.LocalMachine,
+ registrationScope == RegistrationScope.OS64Bit ? RegistryView.Registry64 : RegistryView.Registry32
+ ).OpenSubKey(
+ @"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved",
+ RegistryKeyPermissionCheck.ReadSubTree
+ ))
{
// If we can't open the key, we're going to have problems.
if (approvedKey == null)
+ {
throw new InvalidOperationException("Failed to open the Approved Extensions key.");
+ }
- return approvedKey.GetValueNames().Any(vn => vn.Equals(serverClsid.ToRegistryString(), StringComparison.OrdinalIgnoreCase));
+ return approvedKey.GetValueNames().Any(valueName =>
+ valueName.Equals(serverClassId.ToRegistryString(), StringComparison.OrdinalIgnoreCase)
+ );
}
}
///
- /// Unapproves an extension.
+ /// UnApproves an extension.
///
- /// The server.
- /// Type of the registration.
- /// Failed to open the Approved Extensions key.
- private static void UnapproveExtension(ISharpShellServer server, RegistrationType registrationType)
+ /// The server's class id.
+ /// Type of the registration.
+ /// Failed to open the Approved Extensions key.
+ private static void UnApproveExtension(Guid serverClassId, RegistrationScope registrationScope)
{
// Open the approved extensions key.
- using (var approvedKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
- registrationType == RegistrationType.OS64Bit ? RegistryView.Registry64 : RegistryView.Registry32)
- .OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved", RegistryKeyPermissionCheck.ReadWriteSubTree))
+ using (var approvedKey = RegistryKey.OpenBaseKey(
+ RegistryHive.LocalMachine,
+ registrationScope == RegistrationScope.OS64Bit ? RegistryView.Registry64 : RegistryView.Registry32
+ ).OpenSubKey(
+ @"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved",
+ RegistryKeyPermissionCheck.ReadWriteSubTree
+ ))
{
// If we can't open the key, we're going to have problems.
if (approvedKey == null)
+ {
throw new InvalidOperationException("Failed to open the Approved Extensions key.");
+ }
// Delete the value if it's there.
- approvedKey.DeleteValue(server.ServerClsid.ToRegistryString(), false);
+ approvedKey.DeleteValue(serverClassId.ToRegistryString(), false);
}
}
- ///
- /// The classes key name.
- ///
- private const string KeyName_Classes = @"CLSID";
-
- ///
- /// The InProc32 key name.
- ///
- private const string KeyName_InProc32 = @"InprocServer32";
-
- ///
- /// The value for the net framework servers.
- ///
- private const string KeyValue_NetFrameworkServer = @"mscoree.dll";
-
- ///
- /// The threading model key name.
- ///
- private const string KeyName_ThreadingModel = @"ThreadingModel";
-
- ///
- /// THe assembly key name.
- ///
- private const string KeyName_Assembly = @"Assembly";
-
- ///
- /// The class key name.
- ///
- private const string KeyName_Class = @"Class";
-
- ///
- /// The runtime version key name.
- ///
- private const string KeyName_RuntimeVersion = @"RuntimeVersion";
-
- ///
- /// The codebase keyname.
- ///
- private const string KeyName_CodeBase = @"CodeBase";
-
- ///
- /// The default icon keyname.
- ///
- private const string KeyName_DefaultIcon = @"DefaultIcon";
-
- ///
- /// The default icon backup value name.
- ///
- private const string ValueName_DefaultIconBackup = @"SharpShell_Backup_DefaultIcon";
+ #endregion
}
-}
+}
\ No newline at end of file
diff --git a/SharpShell/SharpShell/ServerRegistration/ServerSandBox.cs b/SharpShell/SharpShell/ServerRegistration/ServerSandBox.cs
new file mode 100644
index 00000000..123ecf05
--- /dev/null
+++ b/SharpShell/SharpShell/ServerRegistration/ServerSandBox.cs
@@ -0,0 +1,418 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+namespace SharpShell.ServerRegistration
+{
+ internal class ServerSandBox : MarshalByRefObject
+ {
+ public static SharpShellServerInfo[] FromAssemblyFile(FileInfo assemblyFile)
+ {
+ // Get sandbox type
+ var sandboxType = typeof(ServerSandBox);
+
+ if (string.IsNullOrEmpty(sandboxType.FullName))
+ {
+ return null;
+ }
+
+ // Creating a new temporary domain
+ var domain = AppDomain.CreateDomain("ServerTemporarySandboxedDomain");
+
+ try
+ {
+ // Adding custom resolve function to load local version of SharpShell and other dependencies
+ domain.AssemblyResolve += DomainOnAssemblyResolve;
+
+ // Create and instance of this class inside the newly created domain
+ var sandbox = (ServerSandBox) domain.CreateInstanceAndUnwrap(
+ sandboxType.Assembly.FullName,
+ sandboxType.FullName
+ );
+
+ // Load assembly
+ var assemblyLocation = sandbox.InjectedLoadAssemblyFile(assemblyFile.FullName);
+
+ // Get server information from inside of the newly created domain
+ return sandbox.InjectedGetServersInformation(assemblyLocation);
+ }
+ catch (Exception e)
+ {
+ throw new BadImageFormatException("File is not a valid .Net library or failed to load the library.", e);
+ }
+ finally
+ {
+ // Unload the newly created domain to free up resource and close loaded assembly files
+ AppDomain.Unload(domain);
+ }
+ }
+
+ public static SharpShellServerInfo[] FromGAC(AssemblyName assemblyName)
+ {
+ // Get sandbox type
+ var sandboxType = typeof(ServerSandBox);
+
+ if (string.IsNullOrEmpty(sandboxType.FullName))
+ {
+ return null;
+ }
+
+ // Creating a new temporary domain
+ var domain = AppDomain.CreateDomain("ServerTemporarySandboxedDomain");
+
+ try
+ {
+ // Adding custom resolve function to load local version of SharpShell and other dependencies
+ domain.AssemblyResolve += DomainOnAssemblyResolve;
+
+ // Create and instance of this class inside the newly created domain
+ var sandbox = (ServerSandBox) domain.CreateInstanceAndUnwrap(
+ sandboxType.Assembly.FullName,
+ sandboxType.FullName
+ );
+
+ // Load assembly
+ var assemblyLocation = sandbox.InjectedLoadAssemblyGAC(assemblyName);
+
+ // Get server information from inside of the newly created domain
+ return sandbox.InjectedGetServersInformation(assemblyLocation);
+ }
+ catch (Exception e)
+ {
+ throw new BadImageFormatException("File is not a valid .Net library or failed to load the library.", e);
+ }
+ finally
+ {
+ // Unload the newly created domain to free up resource and close loaded assembly files
+ AppDomain.Unload(domain);
+ }
+ }
+
+ public static IEnumerable
[Description("Not a SharpShell Server")]
- None,
+ None = 0,
///
/// A Shell Context Menu.
///
- [Description("Shell Context Menu")]
- ShellContextMenu,
+ [Description(@"Shell Context Menu")]
+ ShellContextMenu = 1,
///
/// A Shell Property Sheet.
///
- [Description("Shell Property Sheet")]
- ShellPropertySheet,
+ [Description(@"Shell Property Sheet")]
+ ShellPropertySheet = 2,
///
/// A Shell Icon Handler.
///
- [Description("Shell Icon Handler")]
- ShellIconHandler,
+ [Description(@"Shell Icon Handler")]
+ ShellIconHandler = 3,
///
/// A Shell Info Tip Handler.
///
- [Description("Shell Info Tip Handler")]
- ShellInfoTipHandler,
+ [Description(@"Shell Info Tip Handler")]
+ ShellInfoTipHandler = 4,
///
/// A Shell Drop Handler
///
- [Description("Shell Drop Handler")]
- ShellDropHandler,
+ [Description(@"Shell Drop Handler")]
+ ShellDropHandler = 5,
///
/// A Shell Icon Overlay Handler.
///
- [Description("Shell Icon Overlay Handler")]
- ShellIconOverlayHandler,
+ [Description(@"Shell Icon Overlay Handler")]
+ ShellIconOverlayHandler = 6,
///
/// A Shell Preview Handler
///
- [Description("Shell Preview Handler")]
- ShellPreviewHander,
+ [Description(@"Shell Preview Handler")]
+ ShellPreviewHandler = 7,
///
/// A Shell Data Handler
///
- [Description("Shell Data Handler")]
- ShellDataHandler,
+ [Description(@"Shell Data Handler")]
+ ShellDataHandler = 8,
///
/// A Shell Thumbnail Handler
///
- [Description("Shell Thumbnail Handler")]
- ShellThumbnailHandler,
+ [Description(@"Shell Thumbnail Handler")]
+ ShellThumbnailHandler = 9,
///
/// A Shell Namespace Extension
///
- [Description("Shell Namespace Extension")]
- ShellNamespaceExtension,
+ [Description(@"Shell Namespace Extension")]
+ ShellNamespaceExtension = 10,
///
/// A Shell Desk Band Extension
///
- [Description("Shell Desk Band Extension")]
- ShellDeskBand
+ [Description(@"Shell Desk Band Extension")]
+ ShellDeskBand = 11
}
}
\ No newline at end of file
diff --git a/SharpShell/SharpShell/SharpDeskBand/SharpDeskBand.cs b/SharpShell/SharpShell/SharpDeskBand/SharpDeskBand.cs
index 9b73f304..53357aae 100644
--- a/SharpShell/SharpShell/SharpDeskBand/SharpDeskBand.cs
+++ b/SharpShell/SharpShell/SharpDeskBand/SharpDeskBand.cs
@@ -135,7 +135,7 @@ int IPersistStream.GetClassID(out Guid pClassID)
Log("IPersistStream.GetClassID called.");
// Return the server class id.
- pClassID = ServerClsid;
+ pClassID = ServerClassId;
// Return success.
return WinError.S_OK;
@@ -189,7 +189,7 @@ int IPersist.GetClassID(out Guid pClassID)
// The class ID is just a unique identifier for the class, meaning
// that we can use the class GUID as it will be provided for
// all SharpShell servers.
- pClassID = ServerClsid;
+ pClassID = ServerClassId;
// Return success.
return WinError.S_OK;
@@ -478,7 +478,7 @@ int IInputObject.TranslateAcceleratorIO(ref MSG msg)
/// The custom registration function.
///
/// Type of the server.
- /// Type of the registration.
+ /// Type of the registration.
///
/// Unable to register a SharpNamespaceExtension as it is missing it's junction point definition.
/// or
@@ -491,9 +491,9 @@ int IInputObject.TranslateAcceleratorIO(ref MSG msg)
/// An exception occured creating the ShellFolder key.
///
[CustomRegisterFunction]
- internal static void CustomRegisterFunction(Type serverType, RegistrationType registrationType)
+ internal static void CustomRegisterFunction(Type serverType, RegistrationScope registrationScope)
{
- Logging.Log($"DeskBand: Preparing to register {registrationType} COM categories for type {serverType.Name}");
+ Logging.Log($"DeskBand: Preparing to register {registrationScope} COM categories for type {serverType.Name}");
// Use the category manager to register this server as a Desk Band.
try
@@ -502,7 +502,7 @@ internal static void CustomRegisterFunction(Type serverType, RegistrationType re
}
catch (Exception exception)
{
- Logging.Error($"An exception occurred to registering {registrationType} COM categories for type {serverType.Name}", exception);
+ Logging.Error($"An exception occurred to registering {registrationScope} COM categories for type {serverType.Name}", exception);
}
}
@@ -510,11 +510,11 @@ internal static void CustomRegisterFunction(Type serverType, RegistrationType re
/// Customs the unregister function.
///
/// Type of the server.
- /// Type of the registration.
+ /// Type of the registration.
[CustomUnregisterFunction]
- internal static void CustomUnregisterFunction(Type serverType, RegistrationType registrationType)
+ internal static void CustomUnregisterFunction(Type serverType, RegistrationScope registrationScope)
{
- Logging.Log($"DeskBand: Preparing to unregister {registrationType} COM categories for type {serverType.Name}");
+ Logging.Log($"DeskBand: Preparing to unregister {registrationScope} COM categories for type {serverType.Name}");
// Use the category manager to register this server as a Desk Band.
try
@@ -523,7 +523,7 @@ internal static void CustomUnregisterFunction(Type serverType, RegistrationType
}
catch (Exception exception)
{
- Logging.Error($"An exception occurred to registering {registrationType} COM categories for type {serverType.Name}", exception);
+ Logging.Error($"An exception occurred to registering {registrationScope} COM categories for type {serverType.Name}", exception);
}
}
diff --git a/SharpShell/SharpShell/SharpIconOverlayHandler/SharpIconOverlayHandler.cs b/SharpShell/SharpShell/SharpIconOverlayHandler/SharpIconOverlayHandler.cs
index 0db82b57..6df1ea21 100644
--- a/SharpShell/SharpShell/SharpIconOverlayHandler/SharpIconOverlayHandler.cs
+++ b/SharpShell/SharpShell/SharpIconOverlayHandler/SharpIconOverlayHandler.cs
@@ -212,15 +212,15 @@ private string GetIconFilePath()
/// The custom registration function.
///
/// Type of the server.
- /// Type of the registration.
+ /// Type of the registration.
[CustomRegisterFunction]
- internal static void CustomRegisterFunction(Type serverType, RegistrationType registrationType)
+ internal static void CustomRegisterFunction(Type serverType, RegistrationScope registrationScope)
{
- var keyName = RegistrationNameAttribute.GetRegistrationNameOrTypeName(serverType);
- Logging.Log($"IconOverlayHandler: Preparing to register {registrationType} Icon Overlay Handler for type '{serverType.Name}' with key name '{keyName}'");
+ var keyName = RegistrationNameAttribute.GetRegistrationNameAttribute(serverType);
+ Logging.Log($"IconOverlayHandler: Preparing to register {registrationScope} Icon Overlay Handler for type '{serverType.Name}' with key name '{keyName}'");
// Open the local machine.
- using (var localMachineBaseKey = registrationType == RegistrationType.OS64Bit
+ using (var localMachineBaseKey = registrationScope == RegistrationScope.OS64Bit
? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64) :
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
{
@@ -241,7 +241,7 @@ internal static void CustomRegisterFunction(Type serverType, RegistrationType re
"being registered, it will not be used by Windows Explorer.");
// Create the overlay key.
- using (var overlayKey = overlayIdentifiers.CreateSubKey(keyName))
+ using (var overlayKey = overlayIdentifiers.CreateSubKey(keyName.RegistrationName))
{
// If we don't have the overlay key, we've got a problem.
if(overlayKey == null)
@@ -258,15 +258,15 @@ internal static void CustomRegisterFunction(Type serverType, RegistrationType re
/// Customs the unregister function.
///
/// Type of the server.
- /// Type of the registration.
+ /// Type of the registration.
[CustomUnregisterFunction]
- internal static void CustomUnregisterFunction(Type serverType, RegistrationType registrationType)
+ internal static void CustomUnregisterFunction(Type serverType, RegistrationScope registrationScope)
{
- var keyName = RegistrationNameAttribute.GetRegistrationNameOrTypeName(serverType);
- Logging.Log($"IconOverlayHandler: Preparing to unregister {registrationType} Icon Overlay Handler for type '{serverType.Name}' with key name '{keyName}'");
+ var keyName = RegistrationNameAttribute.GetRegistrationNameAttribute(serverType);
+ Logging.Log($"IconOverlayHandler: Preparing to unregister {registrationScope} Icon Overlay Handler for type '{serverType.Name}' with key name '{keyName}'");
// Open the local machine.
- using (var localMachineBaseKey = registrationType == RegistrationType.OS64Bit
+ using (var localMachineBaseKey = registrationScope == RegistrationScope.OS64Bit
? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64) :
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
{
@@ -280,8 +280,8 @@ internal static void CustomUnregisterFunction(Type serverType, RegistrationType
throw new InvalidOperationException("Cannot open the ShellIconOverlayIdentifiers key.");
// Delete the overlay key.
- if (overlayIdentifiers.GetSubKeyNames().Any(skn => skn == keyName))
- overlayIdentifiers.DeleteSubKey(keyName);
+ if (overlayIdentifiers.GetSubKeyNames().Any(skn => skn == keyName.RegistrationName))
+ overlayIdentifiers.DeleteSubKey(keyName.RegistrationName);
}
}
}
diff --git a/SharpShell/SharpShell/SharpNamespaceExtension/SharpNamespaceExtension.cs b/SharpShell/SharpShell/SharpNamespaceExtension/SharpNamespaceExtension.cs
index 4a234a17..96f55466 100644
--- a/SharpShell/SharpShell/SharpNamespaceExtension/SharpNamespaceExtension.cs
+++ b/SharpShell/SharpShell/SharpNamespaceExtension/SharpNamespaceExtension.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
-using System.EnterpriseServices;
using System.Linq;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
@@ -397,7 +396,7 @@ int IPersistIDList.GetIDList([Out] out IntPtr pidl)
/// The custom registration function.
///
/// Type of the server.
- /// Type of the registration.
+ /// Type of the registration.
///
/// Unable to register a SharpNamespaceExtension as it is missing it's junction point definition.
/// or
@@ -410,7 +409,7 @@ int IPersistIDList.GetIDList([Out] out IntPtr pidl)
/// An exception occured creating the ShellFolder key.
///
[CustomRegisterFunction]
- internal static void CustomRegisterFunction(Type serverType, RegistrationType registrationType)
+ internal static void CustomRegisterFunction(Type serverType, RegistrationScope registrationScope)
{
// Get the junction point.
var junctionPoint = NamespaceExtensionJunctionPointAttribute.GetJunctionPoint(serverType);
@@ -437,7 +436,7 @@ Virtual Folder Name
var hive = junctionPoint.Availablity == NamespaceExtensionAvailability.CurrentUser
? RegistryHive.CurrentUser
: RegistryHive.LocalMachine;
- var view = registrationType == RegistrationType.OS64Bit ? RegistryView.Registry64 : RegistryView.Registry32;
+ var view = registrationScope == RegistrationScope.OS64Bit ? RegistryView.Registry64 : RegistryView.Registry32;
// Now open the base key.
using (var baseKey = RegistryKey.OpenBaseKey(hive, view))
@@ -468,7 +467,7 @@ Virtual Folder Name
// adapting it here.
// Open the classes root.
- using (var classesBaseKey = registrationType == RegistrationType.OS64Bit
+ using (var classesBaseKey = registrationScope == RegistrationScope.OS64Bit
? RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry64) :
RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry32))
{
@@ -524,9 +523,9 @@ Virtual Folder Name
/// Customs the unregister function.
///
/// Type of the server.
- /// Type of the registration.
+ /// Type of the registration.
[CustomUnregisterFunction]
- internal static void CustomUnregisterFunction(Type serverType, RegistrationType registrationType)
+ internal static void CustomUnregisterFunction(Type serverType, RegistrationScope registrationScope)
{
// Get the junction point.
var junctionPoint = NamespaceExtensionJunctionPointAttribute.GetJunctionPoint(serverType);
@@ -540,7 +539,7 @@ internal static void CustomUnregisterFunction(Type serverType, RegistrationType
var hive = junctionPoint.Availablity == NamespaceExtensionAvailability.CurrentUser
? RegistryHive.CurrentUser
: RegistryHive.LocalMachine;
- var view = registrationType == RegistrationType.OS64Bit ? RegistryView.Registry64 : RegistryView.Registry32;
+ var view = registrationScope == RegistrationScope.OS64Bit ? RegistryView.Registry64 : RegistryView.Registry32;
// Now open the base key.
using (var baseKey = RegistryKey.OpenBaseKey(hive, view))
diff --git a/SharpShell/SharpShell/SharpNamespaceExtension/ShellFolderImpl.cs b/SharpShell/SharpShell/SharpNamespaceExtension/ShellFolderImpl.cs
index 2e0fdc0a..d6ab2b97 100644
--- a/SharpShell/SharpShell/SharpNamespaceExtension/ShellFolderImpl.cs
+++ b/SharpShell/SharpShell/SharpNamespaceExtension/ShellFolderImpl.cs
@@ -763,7 +763,7 @@ int IShellFolder2.MapColumnToSCID(uint iColumn, out PROPERTYKEY pscid)
int IPersist.GetClassID(out Guid pClassID)
{
// Set the class ID to the server id.
- pClassID = namespaceExtension.ServerClsid;
+ pClassID = namespaceExtension.ServerClassId;
return WinError.S_OK;
}
int IPersistFolder.GetClassID(out Guid pClassID) { return ((IPersist)this).GetClassID(out pClassID); }
diff --git a/SharpShell/SharpShell/SharpPreviewHandler/PreviewHandlerHost.cs b/SharpShell/SharpShell/SharpPreviewHandler/PreviewHandlerHost.cs
index 69bc53db..416c9b9f 100644
--- a/SharpShell/SharpShell/SharpPreviewHandler/PreviewHandlerHost.cs
+++ b/SharpShell/SharpShell/SharpPreviewHandler/PreviewHandlerHost.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
-using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
diff --git a/SharpShell/SharpShell/SharpPreviewHandler/PreviewHandlerRegistrar.cs b/SharpShell/SharpShell/SharpPreviewHandler/PreviewHandlerRegistrar.cs
index 9a4b0b7f..032fa58d 100644
--- a/SharpShell/SharpShell/SharpPreviewHandler/PreviewHandlerRegistrar.cs
+++ b/SharpShell/SharpShell/SharpPreviewHandler/PreviewHandlerRegistrar.cs
@@ -17,7 +17,7 @@ internal static class PreviewHandlerRegistrar
{
private const string PreviewHandlersKey = @"Software\Microsoft\Windows\CurrentVersion\PreviewHandlers";
- public static void Register(Type serverType, RegistrationType registrationType)
+ public static void Register(Type serverType, RegistrationScope registrationScope)
{
// Get the preview handler attribute. If it is missing, throw a registration exception.
var previewHandlerAttribute = PreviewHandlerAttribute.GetPreviewHandlerAttribute(serverType);
@@ -27,10 +27,10 @@ public static void Register(Type serverType, RegistrationType registrationType)
}
// We will use the display name a few times.
- var displayName = DisplayNameAttribute.GetDisplayNameOrTypeName(serverType);
+ var displayName = DisplayNameAttribute.GetDisplayNameAttribute(serverType)?.DisplayName ?? serverType.Name;
// Open the local machine.
- using (var localMachineBaseKey = registrationType == RegistrationType.OS64Bit
+ using (var localMachineBaseKey = registrationScope == RegistrationScope.OS64Bit
? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
RegistryView.Registry64)
: RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
@@ -52,7 +52,7 @@ public static void Register(Type serverType, RegistrationType registrationType)
}
// Open the classes root.
- using (var classesBaseKey = registrationType == RegistrationType.OS64Bit
+ using (var classesBaseKey = registrationScope == RegistrationScope.OS64Bit
? RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry64)
: RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry32))
{
@@ -109,11 +109,11 @@ public static void Register(Type serverType, RegistrationType registrationType)
/// Unregisters the SharpShell Preview Handler with the given type.
///
/// Type of the server.
- /// Type of the registration.
- public static void Unregister(Type serverType, RegistrationType registrationType)
+ /// Type of the registration.
+ public static void Unregister(Type serverType, RegistrationScope registrationScope)
{
// Open the local machine.
- using (var localMachineBaseKey = registrationType == RegistrationType.OS64Bit
+ using (var localMachineBaseKey = registrationScope == RegistrationScope.OS64Bit
? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64) :
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
{
diff --git a/SharpShell/SharpShell/SharpPreviewHandler/SharpPreviewHandler.cs b/SharpShell/SharpShell/SharpPreviewHandler/SharpPreviewHandler.cs
index d0da5d34..729e04fb 100644
--- a/SharpShell/SharpShell/SharpPreviewHandler/SharpPreviewHandler.cs
+++ b/SharpShell/SharpShell/SharpPreviewHandler/SharpPreviewHandler.cs
@@ -25,7 +25,7 @@ namespace SharpShell.SharpPreviewHandler
/// The SharpPreviewHandler is the base class for Shell Preview Handlers
/// implemented with SharpShell.
///
- [ServerType(ServerType.ShellPreviewHander)]
+ [ServerType(ServerType.ShellPreviewHandler)]
public abstract class SharpPreviewHandler : SharpShellServer,
IInitializeWithFile,
/*IInitializeWithStream,*/
@@ -540,24 +540,24 @@ int IPreviewHandlerVisuals.SetTextColor(COLORREF color)
/// The custom registration function.
///
/// Type of the server.
- /// Type of the registration.
+ /// Type of the registration.
[CustomRegisterFunction]
- internal static void CustomRegisterFunction(Type serverType, RegistrationType registrationType)
+ internal static void CustomRegisterFunction(Type serverType, RegistrationScope registrationScope)
{
// Register preview handlers via the registrar.
- PreviewHandlerRegistrar.Register(serverType, registrationType);
+ PreviewHandlerRegistrar.Register(serverType, registrationScope);
}
///
/// Customs the unregister function.
///
/// Type of the server.
- /// Type of the registration.
+ /// Type of the registration.
[CustomUnregisterFunction]
- internal static void CustomUnregisterFunction(Type serverType, RegistrationType registrationType)
+ internal static void CustomUnregisterFunction(Type serverType, RegistrationScope registrationScope)
{
// Open the local machine.
- using (var localMachineBaseKey = registrationType == RegistrationType.OS64Bit
+ using (var localMachineBaseKey = registrationScope == RegistrationScope.OS64Bit
? RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64) :
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
{
diff --git a/SharpShell/SharpShell/SharpShell.csproj b/SharpShell/SharpShell/SharpShell.csproj
index af6d156b..8454ac40 100644
--- a/SharpShell/SharpShell/SharpShell.csproj
+++ b/SharpShell/SharpShell/SharpShell.csproj
@@ -34,6 +34,7 @@
true
+ 7.3
pdbonly
@@ -44,6 +45,7 @@
4
bin\Release\SharpShell.xml
true
+ 7.3
true
@@ -56,13 +58,8 @@
-
-
-
-
-
@@ -206,6 +203,11 @@
+
+
+
+
+
@@ -300,9 +302,9 @@
-
-
-
+
+
+
diff --git a/SharpShell/SharpShell/SharpShellServer.cs b/SharpShell/SharpShell/SharpShellServer.cs
index 7b4de1f3..aab50fb4 100644
--- a/SharpShell/SharpShell/SharpShellServer.cs
+++ b/SharpShell/SharpShell/SharpShellServer.cs
@@ -1,11 +1,9 @@
using System;
using System.ComponentModel.Composition;
-using System.Linq;
using System.Runtime.InteropServices;
using SharpShell.Attributes;
using SharpShell.Diagnostics;
using SharpShell.ServerRegistration;
-using SharpShell.Interop;
namespace SharpShell
{
@@ -32,11 +30,14 @@ public abstract class SharpShellServer : ISharpShellServer
[ComRegisterFunction]
internal static void Register(Type type)
{
- Logging.Log("Registering server for type " + type.Name);
-
- // Register the type, use the operating system architecture to determine
+ Logging.Log("Registering server for type " + type.Name);
+
+ // Register the type, use the operating system architecture to determine
// what registration type to perform.
- DoRegister(type, Environment.Is64BitOperatingSystem ? RegistrationType.OS64Bit : RegistrationType.OS32Bit);
+ ServerRegistrationManager.RegisterAndApproveServer(
+ new SharpShellServerInfo(type),
+ Environment.Is64BitOperatingSystem ? RegistrationScope.OS64Bit : RegistrationScope.OS32Bit
+ );
}
///
@@ -48,86 +49,16 @@ internal static void Register(Type type)
[ComUnregisterFunction]
internal static void Unregister(Type type)
{
- Logging.Log("Unregistering server for type " + type.Name);
+ Logging.Log("Un-registering server for type " + type.Name);
// Unregister the type, use the operating system architecture to determine
// what registration type to unregister.
- DoUnregister(type, Environment.Is64BitOperatingSystem ? RegistrationType.OS64Bit : RegistrationType.OS32Bit);
+ ServerRegistrationManager.UnregisterAndUnApproveServer(
+ new SharpShellServerInfo(type),
+ Environment.Is64BitOperatingSystem ? RegistrationScope.OS64Bit : RegistrationScope.OS32Bit
+ );
}
-
- ///
- /// Actually performs registration. The ComRegisterFunction decorated method will call this function
- /// internally with the flag appropriate for the operating system processor architecture.
- /// However, this function can also be called manually if needed.
- ///
- /// The type of object to register, this must be a SharpShellServer derived class.
- /// Type of the registration.
- internal static void DoRegister(Type type, RegistrationType registrationType)
- {
- Logging.Log($"Preparing to register SharpShell Server {type.Name} as {registrationType}");
-
- // Get the association data.
- var associationAttributes = type.GetCustomAttributes(typeof(COMServerAssociationAttribute), true)
- .OfType().ToList();
-
- // Get the server type and the registration name.
- var serverType = ServerTypeAttribute.GetServerType(type);
- var registrationName = RegistrationNameAttribute.GetRegistrationNameOrTypeName(type);
-
- // Register the server associations, if there are any.
- if (associationAttributes.Any())
- {
- ServerRegistrationManager.RegisterServerAssociations(
- type.GUID, serverType, registrationName, associationAttributes, registrationType);
- }
-
- // If a DisplayName attribute has been set, then set the display name of the COM server.
- var displayName = DisplayNameAttribute.GetDisplayName(type);
- if (!string.IsNullOrEmpty(displayName))
- ServerRegistrationManager.SetServerDisplayName(type.GUID, displayName, registrationType);
-
- // Execute the custom register function, if there is one.
- CustomRegisterFunctionAttribute.ExecuteIfExists(type, registrationType);
-
- // Notify the shell we've updated associations.
- Shell32.SHChangeNotify(Shell32.SHCNE_ASSOCCHANGED, 0, IntPtr.Zero, IntPtr.Zero);
- Logging.Log($"Registration of {type.Name} completed");
- }
-
- ///
- /// Actually performs unregistration. The ComUnregisterFunction decorated method will call this function
- /// internally with the flag appropriate for the operating system processor architecture.
- /// However, this function can also be called manually if needed.
- ///
- /// The type of object to unregister, this must be a SharpShellServer derived class.
- /// Type of the registration to unregister.
- internal static void DoUnregister(Type type, RegistrationType registrationType)
- {
- Logging.Log($"Preparing to unregister SharpShell Server {type.Name} as {registrationType}");
-
- // Get the association data.
- var associationAttributes = type.GetCustomAttributes(typeof(COMServerAssociationAttribute), true)
- .OfType().ToList();
-
- // Get the server type and the registration name.
- var serverType = ServerTypeAttribute.GetServerType(type);
- var registrationName = RegistrationNameAttribute.GetRegistrationNameOrTypeName(type);
-
- // Unregister the server associations, if there are any.
- if (associationAttributes.Any())
- {
- ServerRegistrationManager.UnregisterServerAssociations(
- type.GUID, serverType, registrationName, associationAttributes, registrationType);
- }
-
- // Execute the custom unregister function, if there is one.
- CustomUnregisterFunctionAttribute.ExecuteIfExists(type, registrationType);
-
- // Notify the shell we've updated associations.
- Shell32.SHChangeNotify(Shell32.SHCNE_ASSOCCHANGED, 0, IntPtr.Zero, IntPtr.Zero);
- Logging.Log($"Unregistration of {type.Name} completed");
- }
-
+
///
/// Logs the specified message to the SharpShell log, with the name of the type.
///
@@ -157,7 +88,10 @@ protected virtual void LogError(string message, Exception exception = null)
///
/// The name of the server.
///
- public string DisplayName => DisplayNameAttribute.GetDisplayNameOrTypeName(GetType());
+ public string DisplayName
+ {
+ get => DisplayNameAttribute.GetDisplayNameAttribute(GetType())?.DisplayName ?? GetType().Name;
+ }
///
/// Gets the type of the server.
@@ -165,11 +99,17 @@ protected virtual void LogError(string message, Exception exception = null)
///
/// The type of the server.
///
- public ServerType ServerType => ServerTypeAttribute.GetServerType(GetType());
+ public ServerType ServerType
+ {
+ get => ServerTypeAttribute.GetServerTypeAttribute(GetType())?.ServerType ?? ServerType.None;
+ }
///
- /// Gets the server CLSID.
+ /// Gets the server class id.
///
- public Guid ServerClsid => GetType().GUID;
+ public Guid ServerClassId
+ {
+ get => SharpShellServerInfo.GetServerClassId(GetType());
+ }
}
}
diff --git a/SharpShell/Tools/ServerManager/ObjectExtensions.cs b/SharpShell/Tools/ServerManager/ObjectExtensions.cs
index d25d2c9d..530db10d 100644
--- a/SharpShell/Tools/ServerManager/ObjectExtensions.cs
+++ b/SharpShell/Tools/ServerManager/ObjectExtensions.cs
@@ -1,8 +1,5 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
+using System.ComponentModel;
using System.Linq;
-using System.Text;
namespace ServerManager
{
@@ -10,10 +7,10 @@ public static class ObjectExtensions
{
public static string GetDescription(this object @this)
{
- var attributes = @this.GetType().GetCustomAttributes(typeof (DescriptionAttribute), true);
- if (!attributes.Any())
- return null;
- return attributes.OfType().First().Description;
+ return @this.GetType()
+ .GetCustomAttributes(typeof(DescriptionAttribute), true)
+ .OfType()
+ .FirstOrDefault()?.Description;
}
}
}
diff --git a/SharpShell/Tools/ServerManager/Program.cs b/SharpShell/Tools/ServerManager/Program.cs
index 1bca6a8b..45a6de8c 100644
--- a/SharpShell/Tools/ServerManager/Program.cs
+++ b/SharpShell/Tools/ServerManager/Program.cs
@@ -1,7 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
using System.Windows.Forms;
namespace ServerManager
diff --git a/SharpShell/Tools/ServerManager/Properties/Resources.Designer.cs b/SharpShell/Tools/ServerManager/Properties/Resources.Designer.cs
index 8ce1b9e2..8fe2081b 100644
--- a/SharpShell/Tools/ServerManager/Properties/Resources.Designer.cs
+++ b/SharpShell/Tools/ServerManager/Properties/Resources.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.18051
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -19,7 +19,7 @@ namespace ServerManager.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
diff --git a/SharpShell/Tools/ServerManager/Properties/Settings.Designer.cs b/SharpShell/Tools/ServerManager/Properties/Settings.Designer.cs
index 72bc7379..deb6e675 100644
--- a/SharpShell/Tools/ServerManager/Properties/Settings.Designer.cs
+++ b/SharpShell/Tools/ServerManager/Properties/Settings.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.269
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -12,7 +12,7 @@ namespace ServerManager.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
diff --git a/SharpShell/Tools/ServerManager/ServerDetails/ServerDetailsView.Designer.cs b/SharpShell/Tools/ServerManager/ServerDetails/ServerDetailsView.Designer.cs
deleted file mode 100644
index 4c275e7c..00000000
--- a/SharpShell/Tools/ServerManager/ServerDetails/ServerDetailsView.Designer.cs
+++ /dev/null
@@ -1,347 +0,0 @@
-namespace ServerManager.ServerDetails
-{
- partial class ServerDetailsView
- {
- ///
- /// Required designer variable.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Clean up any resources being used.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Component Designer generated code
-
- ///
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- ///
- private void InitializeComponent()
- {
- this.label5 = new System.Windows.Forms.Label();
- this.textBox32BitServer = new System.Windows.Forms.TextBox();
- this.textBox64BitServer = new System.Windows.Forms.TextBox();
- this.label7 = new System.Windows.Forms.Label();
- this.groupBox1 = new System.Windows.Forms.GroupBox();
- this.textBoxAssociations = new System.Windows.Forms.TextBox();
- this.label8 = new System.Windows.Forms.Label();
- this.textBoxAssemblyPath = new System.Windows.Forms.TextBox();
- this.label6 = new System.Windows.Forms.Label();
- this.textBoxServerSecurity = new System.Windows.Forms.TextBox();
- this.textBoxServerCLSID = new System.Windows.Forms.TextBox();
- this.textBoxServerType = new System.Windows.Forms.TextBox();
- this.textBoxServerName = new System.Windows.Forms.TextBox();
- this.label4 = new System.Windows.Forms.Label();
- this.label3 = new System.Windows.Forms.Label();
- this.label2 = new System.Windows.Forms.Label();
- this.label1 = new System.Windows.Forms.Label();
- this.groupBox2 = new System.Windows.Forms.GroupBox();
- this.groupBoxRegistration = new System.Windows.Forms.GroupBox();
- this.textBox32BitServerRegistration = new System.Windows.Forms.TextBox();
- this.label9 = new System.Windows.Forms.Label();
- this.textBox64BitServerRegistration = new System.Windows.Forms.TextBox();
- this.label10 = new System.Windows.Forms.Label();
- this.groupBox1.SuspendLayout();
- this.groupBox2.SuspendLayout();
- this.groupBoxRegistration.SuspendLayout();
- this.SuspendLayout();
- //
- // label5
- //
- this.label5.AutoSize = true;
- this.label5.Location = new System.Drawing.Point(18, 33);
- this.label5.Name = "label5";
- this.label5.Size = new System.Drawing.Size(68, 13);
- this.label5.TabIndex = 0;
- this.label5.Text = "32 Bit Server";
- //
- // textBox32BitServer
- //
- this.textBox32BitServer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.textBox32BitServer.Location = new System.Drawing.Point(128, 30);
- this.textBox32BitServer.Name = "textBox32BitServer";
- this.textBox32BitServer.ReadOnly = true;
- this.textBox32BitServer.Size = new System.Drawing.Size(230, 20);
- this.textBox32BitServer.TabIndex = 1;
- //
- // textBox64BitServer
- //
- this.textBox64BitServer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.textBox64BitServer.Location = new System.Drawing.Point(127, 56);
- this.textBox64BitServer.Name = "textBox64BitServer";
- this.textBox64BitServer.ReadOnly = true;
- this.textBox64BitServer.Size = new System.Drawing.Size(230, 20);
- this.textBox64BitServer.TabIndex = 3;
- //
- // label7
- //
- this.label7.AutoSize = true;
- this.label7.Location = new System.Drawing.Point(18, 59);
- this.label7.Name = "label7";
- this.label7.Size = new System.Drawing.Size(68, 13);
- this.label7.TabIndex = 2;
- this.label7.Text = "64 Bit Server";
- //
- // groupBox1
- //
- this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.groupBox1.Controls.Add(this.textBoxAssociations);
- this.groupBox1.Controls.Add(this.label8);
- this.groupBox1.Controls.Add(this.textBoxAssemblyPath);
- this.groupBox1.Controls.Add(this.label6);
- this.groupBox1.Controls.Add(this.textBoxServerSecurity);
- this.groupBox1.Controls.Add(this.textBoxServerCLSID);
- this.groupBox1.Controls.Add(this.textBoxServerType);
- this.groupBox1.Controls.Add(this.textBoxServerName);
- this.groupBox1.Controls.Add(this.label4);
- this.groupBox1.Controls.Add(this.label3);
- this.groupBox1.Controls.Add(this.label2);
- this.groupBox1.Controls.Add(this.label1);
- this.groupBox1.Location = new System.Drawing.Point(3, 3);
- this.groupBox1.Name = "groupBox1";
- this.groupBox1.Size = new System.Drawing.Size(376, 198);
- this.groupBox1.TabIndex = 0;
- this.groupBox1.TabStop = false;
- this.groupBox1.Text = "Server";
- //
- // textBoxAssociations
- //
- this.textBoxAssociations.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.textBoxAssociations.Location = new System.Drawing.Point(128, 161);
- this.textBoxAssociations.Name = "textBoxAssociations";
- this.textBoxAssociations.ReadOnly = true;
- this.textBoxAssociations.Size = new System.Drawing.Size(230, 20);
- this.textBoxAssociations.TabIndex = 11;
- //
- // label8
- //
- this.label8.AutoSize = true;
- this.label8.Location = new System.Drawing.Point(18, 164);
- this.label8.Name = "label8";
- this.label8.Size = new System.Drawing.Size(113, 13);
- this.label8.TabIndex = 10;
- this.label8.Text = "Specified Associations";
- //
- // textBoxAssemblyPath
- //
- this.textBoxAssemblyPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.textBoxAssemblyPath.Location = new System.Drawing.Point(128, 135);
- this.textBoxAssemblyPath.Name = "textBoxAssemblyPath";
- this.textBoxAssemblyPath.ReadOnly = true;
- this.textBoxAssemblyPath.Size = new System.Drawing.Size(230, 20);
- this.textBoxAssemblyPath.TabIndex = 9;
- //
- // label6
- //
- this.label6.AutoSize = true;
- this.label6.Location = new System.Drawing.Point(18, 138);
- this.label6.Name = "label6";
- this.label6.Size = new System.Drawing.Size(76, 13);
- this.label6.TabIndex = 8;
- this.label6.Text = "Assembly Path";
- //
- // textBoxServerSecurity
- //
- this.textBoxServerSecurity.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.textBoxServerSecurity.Location = new System.Drawing.Point(128, 109);
- this.textBoxServerSecurity.Name = "textBoxServerSecurity";
- this.textBoxServerSecurity.ReadOnly = true;
- this.textBoxServerSecurity.Size = new System.Drawing.Size(230, 20);
- this.textBoxServerSecurity.TabIndex = 7;
- //
- // textBoxServerCLSID
- //
- this.textBoxServerCLSID.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.textBoxServerCLSID.Location = new System.Drawing.Point(128, 83);
- this.textBoxServerCLSID.Name = "textBoxServerCLSID";
- this.textBoxServerCLSID.ReadOnly = true;
- this.textBoxServerCLSID.Size = new System.Drawing.Size(230, 20);
- this.textBoxServerCLSID.TabIndex = 5;
- //
- // textBoxServerType
- //
- this.textBoxServerType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.textBoxServerType.Location = new System.Drawing.Point(128, 57);
- this.textBoxServerType.Name = "textBoxServerType";
- this.textBoxServerType.ReadOnly = true;
- this.textBoxServerType.Size = new System.Drawing.Size(230, 20);
- this.textBoxServerType.TabIndex = 3;
- //
- // textBoxServerName
- //
- this.textBoxServerName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.textBoxServerName.Location = new System.Drawing.Point(128, 31);
- this.textBoxServerName.Name = "textBoxServerName";
- this.textBoxServerName.ReadOnly = true;
- this.textBoxServerName.Size = new System.Drawing.Size(230, 20);
- this.textBoxServerName.TabIndex = 1;
- //
- // label4
- //
- this.label4.AutoSize = true;
- this.label4.Location = new System.Drawing.Point(18, 112);
- this.label4.Name = "label4";
- this.label4.Size = new System.Drawing.Size(45, 13);
- this.label4.TabIndex = 6;
- this.label4.Text = "Security";
- //
- // label3
- //
- this.label3.AutoSize = true;
- this.label3.Location = new System.Drawing.Point(18, 86);
- this.label3.Name = "label3";
- this.label3.Size = new System.Drawing.Size(72, 13);
- this.label3.TabIndex = 4;
- this.label3.Text = "Server CLSID";
- //
- // label2
- //
- this.label2.AutoSize = true;
- this.label2.Location = new System.Drawing.Point(18, 60);
- this.label2.Name = "label2";
- this.label2.Size = new System.Drawing.Size(65, 13);
- this.label2.TabIndex = 2;
- this.label2.Text = "Server Type";
- //
- // label1
- //
- this.label1.AutoSize = true;
- this.label1.Location = new System.Drawing.Point(18, 34);
- this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(35, 13);
- this.label1.TabIndex = 0;
- this.label1.Text = "Name";
- //
- // groupBox2
- //
- this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.groupBox2.Controls.Add(this.textBox32BitServer);
- this.groupBox2.Controls.Add(this.label5);
- this.groupBox2.Controls.Add(this.textBox64BitServer);
- this.groupBox2.Controls.Add(this.label7);
- this.groupBox2.Location = new System.Drawing.Point(0, 207);
- this.groupBox2.Name = "groupBox2";
- this.groupBox2.Size = new System.Drawing.Size(376, 91);
- this.groupBox2.TabIndex = 1;
- this.groupBox2.TabStop = false;
- this.groupBox2.Text = "Installation";
- //
- // groupBoxRegistration
- //
- this.groupBoxRegistration.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.groupBoxRegistration.Controls.Add(this.textBox32BitServerRegistration);
- this.groupBoxRegistration.Controls.Add(this.label9);
- this.groupBoxRegistration.Controls.Add(this.textBox64BitServerRegistration);
- this.groupBoxRegistration.Controls.Add(this.label10);
- this.groupBoxRegistration.Location = new System.Drawing.Point(0, 304);
- this.groupBoxRegistration.Name = "groupBoxRegistration";
- this.groupBoxRegistration.Size = new System.Drawing.Size(376, 91);
- this.groupBoxRegistration.TabIndex = 2;
- this.groupBoxRegistration.TabStop = false;
- this.groupBoxRegistration.Text = "Registration";
- //
- // textBox32BitServerRegistration
- //
- this.textBox32BitServerRegistration.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.textBox32BitServerRegistration.Location = new System.Drawing.Point(128, 30);
- this.textBox32BitServerRegistration.Name = "textBox32BitServerRegistration";
- this.textBox32BitServerRegistration.ReadOnly = true;
- this.textBox32BitServerRegistration.Size = new System.Drawing.Size(230, 20);
- this.textBox32BitServerRegistration.TabIndex = 1;
- //
- // label9
- //
- this.label9.AutoSize = true;
- this.label9.Location = new System.Drawing.Point(18, 33);
- this.label9.Name = "label9";
- this.label9.Size = new System.Drawing.Size(68, 13);
- this.label9.TabIndex = 0;
- this.label9.Text = "32 Bit Server";
- //
- // textBox64BitServerRegistration
- //
- this.textBox64BitServerRegistration.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.textBox64BitServerRegistration.Location = new System.Drawing.Point(127, 56);
- this.textBox64BitServerRegistration.Name = "textBox64BitServerRegistration";
- this.textBox64BitServerRegistration.ReadOnly = true;
- this.textBox64BitServerRegistration.Size = new System.Drawing.Size(230, 20);
- this.textBox64BitServerRegistration.TabIndex = 3;
- //
- // label10
- //
- this.label10.AutoSize = true;
- this.label10.Location = new System.Drawing.Point(18, 59);
- this.label10.Name = "label10";
- this.label10.Size = new System.Drawing.Size(68, 13);
- this.label10.TabIndex = 2;
- this.label10.Text = "64 Bit Server";
- //
- // ServerDetailsView
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.Controls.Add(this.groupBoxRegistration);
- this.Controls.Add(this.groupBox2);
- this.Controls.Add(this.groupBox1);
- this.Name = "ServerDetailsView";
- this.Size = new System.Drawing.Size(382, 437);
- this.groupBox1.ResumeLayout(false);
- this.groupBox1.PerformLayout();
- this.groupBox2.ResumeLayout(false);
- this.groupBox2.PerformLayout();
- this.groupBoxRegistration.ResumeLayout(false);
- this.groupBoxRegistration.PerformLayout();
- this.ResumeLayout(false);
-
- }
-
- #endregion
-
- private System.Windows.Forms.Label label5;
- private System.Windows.Forms.TextBox textBox32BitServer;
- private System.Windows.Forms.TextBox textBox64BitServer;
- private System.Windows.Forms.Label label7;
- private System.Windows.Forms.GroupBox groupBox1;
- private System.Windows.Forms.TextBox textBoxServerSecurity;
- private System.Windows.Forms.TextBox textBoxServerCLSID;
- private System.Windows.Forms.TextBox textBoxServerType;
- private System.Windows.Forms.TextBox textBoxServerName;
- private System.Windows.Forms.Label label4;
- private System.Windows.Forms.Label label3;
- private System.Windows.Forms.Label label2;
- private System.Windows.Forms.Label label1;
- private System.Windows.Forms.GroupBox groupBox2;
- private System.Windows.Forms.TextBox textBoxAssemblyPath;
- private System.Windows.Forms.Label label6;
- private System.Windows.Forms.TextBox textBoxAssociations;
- private System.Windows.Forms.Label label8;
- private System.Windows.Forms.GroupBox groupBoxRegistration;
- private System.Windows.Forms.TextBox textBox32BitServerRegistration;
- private System.Windows.Forms.Label label9;
- private System.Windows.Forms.TextBox textBox64BitServerRegistration;
- private System.Windows.Forms.Label label10;
- }
-}
diff --git a/SharpShell/Tools/ServerManager/ServerDetails/ServerDetailsView.cs b/SharpShell/Tools/ServerManager/ServerDetails/ServerDetailsView.cs
deleted file mode 100644
index 4aa487e6..00000000
--- a/SharpShell/Tools/ServerManager/ServerDetails/ServerDetailsView.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using System;
-using System.Windows.Forms;
-using SharpShell.Attributes;
-using SharpShell.ServerRegistration;
-
-namespace ServerManager.ServerDetails
-{
- public partial class ServerDetailsView : UserControl
- {
- public ServerDetailsView()
- {
- InitializeComponent();
- }
-
- public void Initialise(ServerEntry serverEntry)
- {
- if (serverEntry != null)
- {
- textBoxServerName.Text = serverEntry.ServerName;
- textBoxServerType.Text = serverEntry.ServerType.ToString();
- textBoxServerCLSID.Text = serverEntry.ClassId.ToString();
- textBoxServerSecurity.Text = serverEntry.GetSecurityStatus();
- textBoxAssemblyPath.Text = serverEntry.ServerPath;
-
- if (serverEntry.IsInvalid)
- {
- // Clear other data for invalid servers.
- textBoxAssociations.Text = string.Empty;
- textBox32BitServer.Text = string.Empty;
- textBox64BitServer.Text = string.Empty;
- }
- else
- {
- // Get the specified associations.
- var associationType = COMServerAssociationAttribute.GetAssociationType(serverEntry.Server.GetType());
- var associations = COMServerAssociationAttribute.GetAssociations(serverEntry.Server.GetType());
- textBoxAssociations.Text = associationType.ToString() + " " + string.Join(", ", associations);
-
- // Now use the server registration manager to get the registration info
- // for the different operating system architectures.
- var info32 = ServerRegistrationManager.GetServerRegistrationInfo(serverEntry.Server.ServerClsid,
- RegistrationType.OS32Bit);
- var info64 = ServerRegistrationManager.GetServerRegistrationInfo(serverEntry.Server.ServerClsid,
- RegistrationType.OS64Bit);
-
- // By default, our installation info is going to be empty.
- textBox32BitServer.Text = "Not Installed";
- textBox64BitServer.Text = "Not Installed";
- textBox32BitServerRegistration.Text = "Not Registered";
- textBox64BitServerRegistration.Text = "Not Registered";
-
- // Do we have 32 bit registration info?
- if (info32 != null)
- {
- // Do we have a codebase?
- if (!string.IsNullOrEmpty(info32.CodeBase))
- textBox32BitServer.Text = info32.CodeBase;
- else if (!string.IsNullOrEmpty(info32.Assembly))
- textBox32BitServer.Text = info32.Assembly + " (GAC)";
-
- // Set the registration info.
- if (info32.IsApproved)
- textBox32BitServerRegistration.Text = "Registered";
- }
-
- // Do we have 32 bit registration info?
- if (info64 != null)
- {
- // Do we have a codebase?
- if (!string.IsNullOrEmpty(info64.CodeBase))
- textBox64BitServer.Text = info64.CodeBase;
- else if (!string.IsNullOrEmpty(info64.Assembly))
- textBox64BitServer.Text = info64.Assembly + " (GAC)";
-
- // Set the registration info.
- if (info64.IsApproved)
- textBox64BitServerRegistration.Text = "Registered";
- }
- }
- }
- }
- }
-}
diff --git a/SharpShell/Tools/ServerManager/ServerEntry.cs b/SharpShell/Tools/ServerManager/ServerEntry.cs
deleted file mode 100644
index 0af53624..00000000
--- a/SharpShell/Tools/ServerManager/ServerEntry.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-using System;
-using System.Reflection;
-using SharpShell;
-
-namespace ServerManager
-{
- ///
- /// A Server Entry in the application. Keeps track of viewmodel style data
- /// for a sharp shell server.
- ///
- public class ServerEntry
- {
- ///
- /// Gets or sets the name of the server.
- ///
- ///
- /// The name of the server.
- ///
- public string ServerName { get; set; }
-
- ///
- /// Gets or sets the server path.
- ///
- ///
- /// The server path.
- ///
- public string ServerPath { get; set; }
-
- ///
- /// Gets or sets the type of the server.
- ///
- ///
- /// The type of the server.
- ///
- public ServerType ServerType { get; set; }
-
- ///
- /// Gets or sets the class id.
- ///
- ///
- /// The class id.
- ///
- public Guid ClassId { get; set; }
-
- ///
- /// Gets or sets the server.
- ///
- ///
- /// The server.
- ///
- public ISharpShellServer Server { get; set; }
-
- ///
- /// Gets or sets a value indicating whether the server is invalid.
- ///
- public bool IsInvalid { get; set; }
-
- ///
- /// Gets the security status.
- ///
- ///
- public string GetSecurityStatus()
- {
- AssemblyName asmName = AssemblyName.GetAssemblyName(ServerPath);
- var key = asmName.GetPublicKey();
- return key != null && key.Length > 0 ? "Signed" : "Not Signed";
- }
- }
-}
diff --git a/SharpShell/Tools/ServerManager/ServerManager.csproj b/SharpShell/Tools/ServerManager/ServerManager.csproj
index 2352c7ff..92c4aaa3 100644
--- a/SharpShell/Tools/ServerManager/ServerManager.csproj
+++ b/SharpShell/Tools/ServerManager/ServerManager.csproj
@@ -1,5 +1,5 @@
-
+
Debug
x86
@@ -10,8 +10,9 @@
Properties
ServerManager
ServerManager
- v4.0
- Client
+ v4.6.2
+
+
512
..\..\
true
@@ -33,6 +34,8 @@
DEBUG;TRACE
prompt
4
+ 7.3
+ false
x86
@@ -42,6 +45,8 @@
TRACE
prompt
4
+ 7.3
+ false
true
@@ -58,6 +63,7 @@
false
;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
true
+ false
bin\x64\Release\
@@ -75,6 +81,7 @@
;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
true
false
+ false
true
@@ -92,6 +99,7 @@
;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
true
false
+ false
bin\Release\
@@ -108,6 +116,7 @@
true
;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
true
+ false
SharpShell.ico
@@ -142,14 +151,12 @@
AboutForm.cs
-
+
UserControl
-
+
ServerDetailsView.cs
-
-
Form
@@ -168,6 +175,7 @@
Component
+
UserControl
@@ -186,6 +194,7 @@
TestShellForm.cs
+
AboutForm.cs
@@ -199,7 +208,7 @@
Resources.resx
True
-
+
ServerDetailsView.cs
@@ -220,6 +229,7 @@
TestShellForm.cs
+
SettingsSingleFileGenerator
diff --git a/SharpShell/Tools/ServerManager/ServerManagerApi.cs b/SharpShell/Tools/ServerManager/ServerManagerApi.cs
deleted file mode 100644
index 5681f395..00000000
--- a/SharpShell/Tools/ServerManager/ServerManagerApi.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition.Hosting;
-using System.IO;
-using System.Linq;
-using System.Windows.Forms;
-using SharpShell;
-using SharpShell.SharpPropertySheet;
-using System.Diagnostics;
-using SharpShell.Diagnostics;
-
-namespace ServerManager
-{
- ///
- /// Helper class for dealing with servers.
- ///
- public static class ServerManagerApi
- {
- ///
- /// Loads all SharpShell servers from an assembly.
- ///
- /// The path to the assembly.
- /// A ServerEntry for each SharpShell server in the assembly.
- public static IEnumerable LoadServers(string path)
- {
- // Storage for the servers.
- var servers = new List();
-
- try
- {
- // Create an assembly catalog for the assembly and a container from it.
- var catalog = new AssemblyCatalog(Path.GetFullPath(path));
- var container = new CompositionContainer(catalog);
-
- // Get all exports of type ISharpShellServer.
- var serverTypes = container.GetExports();
-
- // Go through each servertype (creating the instance from the lazy).
- foreach(var serverType in serverTypes)
- {
- ISharpShellServer server = null;
- try
- {
- server = serverType.Value;
- }
- catch (Exception exception)
- {
- Trace.TraceError($"An exception occurred loading a server: ${exception.ToString()}");
- servers.Add(new ServerEntry
- {
- ServerName = "Invalid",
- ServerPath = path,
- ServerType = ServerType.None,
- ClassId = new Guid(),
- Server = null,
- IsInvalid = true
- });
- continue;
- }
-
- // Yield a server entry for the server type.
- servers.Add(new ServerEntry
- {
- ServerName = server.DisplayName,
- ServerPath = path,
- ServerType = server.ServerType,
- ClassId = server.ServerClsid,
- Server = server
- });
-
- }
- }
- catch (Exception exception)
- {
- // It's almost certainly not a COM server.
- Logging.Error("ServerManager: Failed to load SharpShell server", exception);
- MessageBox.Show("The file '" + Path.GetFileName(path) + "' is not a SharpShell Server.", "Warning");
- }
-
- // Return the servers.
- return servers;
- }
- }
-}
diff --git a/SharpShell/Tools/ServerManager/ServerManagerForm.Designer.cs b/SharpShell/Tools/ServerManager/ServerManagerForm.Designer.cs
index 460121b5..7cbb271a 100644
--- a/SharpShell/Tools/ServerManager/ServerManagerForm.Designer.cs
+++ b/SharpShell/Tools/ServerManager/ServerManagerForm.Designer.cs
@@ -1,5 +1,5 @@
-using ServerManager.ServerDetails;
-
+using ServerManager.Views;
+
namespace ServerManager
{
partial class ServerManagerForm
@@ -33,22 +33,26 @@ private void InitializeComponent()
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ServerManagerForm));
this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer();
- this.statusStrip1 = new System.Windows.Forms.StatusStrip();
+ this.statusStrip = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripStatusLabelOSProcessor = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripStatusLabelProcessProcessor = new System.Windows.Forms.ToolStripStatusLabel();
- this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.splitContainer = new System.Windows.Forms.SplitContainer();
this.listViewServers = new System.Windows.Forms.ListView();
this.columnHeaderServerName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeaderServerType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
- this.menuStrip1 = new System.Windows.Forms.MenuStrip();
+ this.serverDetailsView = new ServerManager.Views.ServerDetailsView();
+ this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.loadServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.serverToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.installToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.uninstallToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
this.installServerx86ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.registerServerx86ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.unregisterServerx86ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -73,28 +77,28 @@ private void InitializeComponent()
this.requestAFeatureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.toolStripMain = new System.Windows.Forms.ToolStrip();
+ this.toolStrip = new System.Windows.Forms.ToolStrip();
this.toolStripButtonOpenTestShell = new System.Windows.Forms.ToolStripButton();
this.toolStripButtonTestServer = new System.Windows.Forms.ToolStripButton();
this.toolStripButtonOpenShellDialog = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripButtonAttachDebugger = new System.Windows.Forms.ToolStripButton();
this.toolStripButtonShellDebugger = new System.Windows.Forms.ToolStripButton();
- this.installToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.uninstallToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.serverDetailsView1 = new ServerManager.ServerDetails.ServerDetailsView();
- this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
+ this.panelPleaseWait = new System.Windows.Forms.Panel();
+ this.label1 = new System.Windows.Forms.Label();
+ this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.toolStripContainer1.BottomToolStripPanel.SuspendLayout();
this.toolStripContainer1.ContentPanel.SuspendLayout();
this.toolStripContainer1.TopToolStripPanel.SuspendLayout();
this.toolStripContainer1.SuspendLayout();
- this.statusStrip1.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
- this.splitContainer1.Panel1.SuspendLayout();
- this.splitContainer1.Panel2.SuspendLayout();
- this.splitContainer1.SuspendLayout();
- this.menuStrip1.SuspendLayout();
- this.toolStripMain.SuspendLayout();
+ this.statusStrip.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+ this.splitContainer.Panel1.SuspendLayout();
+ this.splitContainer.Panel2.SuspendLayout();
+ this.splitContainer.SuspendLayout();
+ this.menuStrip.SuspendLayout();
+ this.toolStrip.SuspendLayout();
+ this.panelPleaseWait.SuspendLayout();
this.SuspendLayout();
//
// toolStripContainer1
@@ -102,43 +106,41 @@ private void InitializeComponent()
//
// toolStripContainer1.BottomToolStripPanel
//
- this.toolStripContainer1.BottomToolStripPanel.Controls.Add(this.statusStrip1);
+ this.toolStripContainer1.BottomToolStripPanel.Controls.Add(this.statusStrip);
//
// toolStripContainer1.ContentPanel
//
- this.toolStripContainer1.ContentPanel.Controls.Add(this.splitContainer1);
- this.toolStripContainer1.ContentPanel.Margin = new System.Windows.Forms.Padding(6);
- this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(1744, 859);
+ this.toolStripContainer1.ContentPanel.Controls.Add(this.splitContainer);
+ this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(1084, 574);
this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.toolStripContainer1.Location = new System.Drawing.Point(0, 0);
- this.toolStripContainer1.Margin = new System.Windows.Forms.Padding(6);
this.toolStripContainer1.Name = "toolStripContainer1";
- this.toolStripContainer1.Size = new System.Drawing.Size(1744, 981);
+ this.toolStripContainer1.Size = new System.Drawing.Size(1084, 661);
this.toolStripContainer1.TabIndex = 0;
this.toolStripContainer1.Text = "toolStripContainer1";
//
// toolStripContainer1.TopToolStripPanel
//
- this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.toolStripMain);
- this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.menuStrip1);
+ this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.menuStrip);
+ this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.toolStrip);
//
- // statusStrip1
+ // statusStrip
//
- this.statusStrip1.Dock = System.Windows.Forms.DockStyle.None;
- this.statusStrip1.ImageScalingSize = new System.Drawing.Size(32, 32);
- this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.statusStrip.Dock = System.Windows.Forms.DockStyle.None;
+ this.statusStrip.ImageScalingSize = new System.Drawing.Size(32, 32);
+ this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripStatusLabel1,
this.toolStripStatusLabelOSProcessor,
this.toolStripStatusLabelProcessProcessor});
- this.statusStrip1.Location = new System.Drawing.Point(0, 0);
- this.statusStrip1.Name = "statusStrip1";
- this.statusStrip1.Size = new System.Drawing.Size(1744, 41);
- this.statusStrip1.TabIndex = 0;
+ this.statusStrip.Location = new System.Drawing.Point(0, 0);
+ this.statusStrip.Name = "statusStrip";
+ this.statusStrip.Size = new System.Drawing.Size(1084, 24);
+ this.statusStrip.TabIndex = 0;
//
// toolStripStatusLabel1
//
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
- this.toolStripStatusLabel1.Size = new System.Drawing.Size(632, 36);
+ this.toolStripStatusLabel1.Size = new System.Drawing.Size(307, 19);
this.toolStripStatusLabel1.Text = "Drop SharpShell Server DLLs onto the list to analyse them";
//
// toolStripStatusLabelOSProcessor
@@ -146,7 +148,7 @@ private void InitializeComponent()
this.toolStripStatusLabelOSProcessor.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Left;
this.toolStripStatusLabelOSProcessor.BorderStyle = System.Windows.Forms.Border3DStyle.Etched;
this.toolStripStatusLabelOSProcessor.Name = "toolStripStatusLabelOSProcessor";
- this.toolStripStatusLabelOSProcessor.Size = new System.Drawing.Size(165, 36);
+ this.toolStripStatusLabelOSProcessor.Size = new System.Drawing.Size(83, 19);
this.toolStripStatusLabelOSProcessor.Text = "Windows: x64";
//
// toolStripStatusLabelProcessProcessor
@@ -154,28 +156,26 @@ private void InitializeComponent()
this.toolStripStatusLabelProcessProcessor.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Left;
this.toolStripStatusLabelProcessProcessor.BorderStyle = System.Windows.Forms.Border3DStyle.Etched;
this.toolStripStatusLabelProcessProcessor.Name = "toolStripStatusLabelProcessProcessor";
- this.toolStripStatusLabelProcessProcessor.Size = new System.Drawing.Size(147, 36);
+ this.toolStripStatusLabelProcessProcessor.Size = new System.Drawing.Size(74, 19);
this.toolStripStatusLabelProcessProcessor.Text = "Process: x86";
//
- // splitContainer1
+ // splitContainer
//
- this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
- this.splitContainer1.Location = new System.Drawing.Point(0, 0);
- this.splitContainer1.Margin = new System.Windows.Forms.Padding(6);
- this.splitContainer1.Name = "splitContainer1";
+ this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
+ this.splitContainer.Location = new System.Drawing.Point(0, 0);
+ this.splitContainer.Name = "splitContainer";
//
- // splitContainer1.Panel1
+ // splitContainer.Panel1
//
- this.splitContainer1.Panel1.Controls.Add(this.listViewServers);
+ this.splitContainer.Panel1.Controls.Add(this.listViewServers);
//
- // splitContainer1.Panel2
+ // splitContainer.Panel2
//
- this.splitContainer1.Panel2.Controls.Add(this.serverDetailsView1);
- this.splitContainer1.Size = new System.Drawing.Size(1744, 859);
- this.splitContainer1.SplitterDistance = 1356;
- this.splitContainer1.SplitterWidth = 8;
- this.splitContainer1.TabIndex = 1;
+ this.splitContainer.Panel2.Controls.Add(this.serverDetailsView);
+ this.splitContainer.Size = new System.Drawing.Size(1084, 574);
+ this.splitContainer.SplitterDistance = 686;
+ this.splitContainer.TabIndex = 1;
//
// listViewServers
//
@@ -187,9 +187,8 @@ private void InitializeComponent()
this.listViewServers.Dock = System.Windows.Forms.DockStyle.Fill;
this.listViewServers.FullRowSelect = true;
this.listViewServers.Location = new System.Drawing.Point(0, 0);
- this.listViewServers.Margin = new System.Windows.Forms.Padding(6);
this.listViewServers.Name = "listViewServers";
- this.listViewServers.Size = new System.Drawing.Size(1356, 859);
+ this.listViewServers.Size = new System.Drawing.Size(686, 574);
this.listViewServers.SmallImageList = this.imageList1;
this.listViewServers.TabIndex = 0;
this.listViewServers.UseCompatibleStateImageBehavior = false;
@@ -202,17 +201,17 @@ private void InitializeComponent()
// columnHeaderServerName
//
this.columnHeaderServerName.Text = "Server Name";
- this.columnHeaderServerName.Width = 200;
+ this.columnHeaderServerName.Width = 230;
//
// columnHeaderServerType
//
this.columnHeaderServerType.Text = "Type";
- this.columnHeaderServerType.Width = 120;
+ this.columnHeaderServerType.Width = 230;
//
// columnHeader
//
this.columnHeader.Text = "CLSID";
- this.columnHeader.Width = 200;
+ this.columnHeader.Width = 230;
//
// imageList1
//
@@ -224,21 +223,32 @@ private void InitializeComponent()
this.imageList1.Images.SetKeyName(3, "InfoTip.png");
this.imageList1.Images.SetKeyName(4, "IconOverlayHandler.png");
//
- // menuStrip1
+ // serverDetailsView
+ //
+ this.serverDetailsView.AutoScroll = true;
+ this.serverDetailsView.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.serverDetailsView.ExtensionEntry = null;
+ this.serverDetailsView.Location = new System.Drawing.Point(0, 0);
+ this.serverDetailsView.Margin = new System.Windows.Forms.Padding(6);
+ this.serverDetailsView.Name = "serverDetailsView";
+ this.serverDetailsView.Size = new System.Drawing.Size(394, 574);
+ this.serverDetailsView.TabIndex = 1;
//
- this.menuStrip1.Dock = System.Windows.Forms.DockStyle.None;
- this.menuStrip1.ImageScalingSize = new System.Drawing.Size(32, 32);
- this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ // menuStrip
+ //
+ this.menuStrip.Dock = System.Windows.Forms.DockStyle.None;
+ this.menuStrip.ImageScalingSize = new System.Drawing.Size(32, 32);
+ this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.serverToolStripMenuItem,
this.explorerToolStripMenuItem,
this.toolsToolStripMenuItem,
this.helpToolStripMenuItem});
- this.menuStrip1.Location = new System.Drawing.Point(0, 0);
- this.menuStrip1.Name = "menuStrip1";
- this.menuStrip1.Size = new System.Drawing.Size(1744, 42);
- this.menuStrip1.TabIndex = 2;
- this.menuStrip1.Text = "menuStrip1";
+ this.menuStrip.Location = new System.Drawing.Point(0, 0);
+ this.menuStrip.Name = "menuStrip";
+ this.menuStrip.Size = new System.Drawing.Size(1084, 24);
+ this.menuStrip.TabIndex = 2;
+ this.menuStrip.Text = "menuStrip1";
//
// fileToolStripMenuItem
//
@@ -247,25 +257,25 @@ private void InitializeComponent()
this.toolStripSeparator2,
this.exitToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
- this.fileToolStripMenuItem.Size = new System.Drawing.Size(64, 38);
+ this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "&File";
//
// loadServerToolStripMenuItem
//
this.loadServerToolStripMenuItem.Name = "loadServerToolStripMenuItem";
- this.loadServerToolStripMenuItem.Size = new System.Drawing.Size(254, 38);
+ this.loadServerToolStripMenuItem.Size = new System.Drawing.Size(144, 22);
this.loadServerToolStripMenuItem.Text = "&Load Server...";
this.loadServerToolStripMenuItem.Click += new System.EventHandler(this.loadServerToolStripMenuItem_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
- this.toolStripSeparator2.Size = new System.Drawing.Size(251, 6);
+ this.toolStripSeparator2.Size = new System.Drawing.Size(141, 6);
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
- this.exitToolStripMenuItem.Size = new System.Drawing.Size(254, 38);
+ this.exitToolStripMenuItem.Size = new System.Drawing.Size(144, 22);
this.exitToolStripMenuItem.Text = "&Exit";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
//
@@ -287,80 +297,101 @@ private void InitializeComponent()
this.toolStripSeparator1,
this.testServerToolStripMenuItem});
this.serverToolStripMenuItem.Name = "serverToolStripMenuItem";
- this.serverToolStripMenuItem.Size = new System.Drawing.Size(94, 38);
+ this.serverToolStripMenuItem.Size = new System.Drawing.Size(51, 20);
this.serverToolStripMenuItem.Text = "&Server";
//
+ // installToolStripMenuItem
+ //
+ this.installToolStripMenuItem.Name = "installToolStripMenuItem";
+ this.installToolStripMenuItem.Size = new System.Drawing.Size(191, 22);
+ this.installToolStripMenuItem.Text = "&Install Assembly";
+ this.installToolStripMenuItem.Click += new System.EventHandler(this.installToolStripMenuItem_Click);
+ //
+ // uninstallToolStripMenuItem
+ //
+ this.uninstallToolStripMenuItem.Name = "uninstallToolStripMenuItem";
+ this.uninstallToolStripMenuItem.Size = new System.Drawing.Size(191, 22);
+ this.uninstallToolStripMenuItem.Text = "&Uninstall Assembly";
+ this.uninstallToolStripMenuItem.Click += new System.EventHandler(this.uninstallToolStripMenuItem_Click);
+ //
+ // toolStripSeparator7
+ //
+ this.toolStripSeparator7.Name = "toolStripSeparator7";
+ this.toolStripSeparator7.Size = new System.Drawing.Size(188, 6);
+ //
// installServerx86ToolStripMenuItem
//
this.installServerx86ToolStripMenuItem.Name = "installServerx86ToolStripMenuItem";
- this.installServerx86ToolStripMenuItem.Size = new System.Drawing.Size(356, 38);
+ this.installServerx86ToolStripMenuItem.Size = new System.Drawing.Size(191, 22);
this.installServerx86ToolStripMenuItem.Text = "Install Server (x86)";
- this.installServerx86ToolStripMenuItem.Click += new System.EventHandler(this.installServerx86ToolStripMenuItem_Click);
+ this.installServerx86ToolStripMenuItem.Click += new System.EventHandler(this.installServerX86ToolStripMenuItem_Click);
//
// registerServerx86ToolStripMenuItem
//
this.registerServerx86ToolStripMenuItem.Name = "registerServerx86ToolStripMenuItem";
- this.registerServerx86ToolStripMenuItem.Size = new System.Drawing.Size(356, 38);
+ this.registerServerx86ToolStripMenuItem.Size = new System.Drawing.Size(191, 22);
this.registerServerx86ToolStripMenuItem.Text = "Register Server (x86)";
- this.registerServerx86ToolStripMenuItem.Click += new System.EventHandler(this.registerServerx86ToolStripMenuItem_Click);
+ this.registerServerx86ToolStripMenuItem.Click += new System.EventHandler(this.registerServerX86ToolStripMenuItem_Click);
//
// unregisterServerx86ToolStripMenuItem
//
this.unregisterServerx86ToolStripMenuItem.Name = "unregisterServerx86ToolStripMenuItem";
- this.unregisterServerx86ToolStripMenuItem.Size = new System.Drawing.Size(356, 38);
+ this.unregisterServerx86ToolStripMenuItem.Size = new System.Drawing.Size(191, 22);
this.unregisterServerx86ToolStripMenuItem.Text = "Unregister Server (x86)";
- this.unregisterServerx86ToolStripMenuItem.Click += new System.EventHandler(this.unregisterServerx86ToolStripMenuItem_Click);
+ this.unregisterServerx86ToolStripMenuItem.Click += new System.EventHandler(this.unregisterServerX86ToolStripMenuItem_Click);
//
// uninstallServerx86ToolStripMenuItem
//
this.uninstallServerx86ToolStripMenuItem.Name = "uninstallServerx86ToolStripMenuItem";
- this.uninstallServerx86ToolStripMenuItem.Size = new System.Drawing.Size(356, 38);
+ this.uninstallServerx86ToolStripMenuItem.Size = new System.Drawing.Size(191, 22);
this.uninstallServerx86ToolStripMenuItem.Text = "Uninstall Server (x86)";
- this.uninstallServerx86ToolStripMenuItem.Click += new System.EventHandler(this.uninstallServerx86ToolStripMenuItem_Click);
+ this.uninstallServerx86ToolStripMenuItem.Click += new System.EventHandler(this.uninstallServerX86ToolStripMenuItem_Click);
//
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
- this.toolStripSeparator3.Size = new System.Drawing.Size(353, 6);
+ this.toolStripSeparator3.Size = new System.Drawing.Size(188, 6);
//
// installServerx64ToolStripMenuItem
//
this.installServerx64ToolStripMenuItem.Name = "installServerx64ToolStripMenuItem";
- this.installServerx64ToolStripMenuItem.Size = new System.Drawing.Size(356, 38);
+ this.installServerx64ToolStripMenuItem.Size = new System.Drawing.Size(191, 22);
this.installServerx64ToolStripMenuItem.Text = "Install Server (x64)";
- this.installServerx64ToolStripMenuItem.Click += new System.EventHandler(this.installServerx64ToolStripMenuItem_Click);
+ this.installServerx64ToolStripMenuItem.Click += new System.EventHandler(this.installServerX64ToolStripMenuItem_Click);
//
// registerServerx64ToolStripMenuItem
//
this.registerServerx64ToolStripMenuItem.Name = "registerServerx64ToolStripMenuItem";
- this.registerServerx64ToolStripMenuItem.Size = new System.Drawing.Size(356, 38);
+ this.registerServerx64ToolStripMenuItem.Size = new System.Drawing.Size(191, 22);
this.registerServerx64ToolStripMenuItem.Text = "Register Server (x64)";
- this.registerServerx64ToolStripMenuItem.Click += new System.EventHandler(this.registerServerx64ToolStripMenuItem_Click);
+ this.registerServerx64ToolStripMenuItem.Click += new System.EventHandler(this.registerServerX64ToolStripMenuItem_Click);
//
// unregisterServerx64ToolStripMenuItem
//
this.unregisterServerx64ToolStripMenuItem.Name = "unregisterServerx64ToolStripMenuItem";
- this.unregisterServerx64ToolStripMenuItem.Size = new System.Drawing.Size(356, 38);
+ this.unregisterServerx64ToolStripMenuItem.Size = new System.Drawing.Size(191, 22);
this.unregisterServerx64ToolStripMenuItem.Text = "Unregister Server (x64)";
- this.unregisterServerx64ToolStripMenuItem.Click += new System.EventHandler(this.unregisterServerx64ToolStripMenuItem_Click);
+ this.unregisterServerx64ToolStripMenuItem.Click += new System.EventHandler(this.unregisterServerX64ToolStripMenuItem_Click);
//
// uninstallServerx64ToolStripMenuItem
//
this.uninstallServerx64ToolStripMenuItem.Name = "uninstallServerx64ToolStripMenuItem";
- this.uninstallServerx64ToolStripMenuItem.Size = new System.Drawing.Size(356, 38);
+ this.uninstallServerx64ToolStripMenuItem.Size = new System.Drawing.Size(191, 22);
this.uninstallServerx64ToolStripMenuItem.Text = "Unin&stall Server (x64)";
- this.uninstallServerx64ToolStripMenuItem.Click += new System.EventHandler(this.uninstallServerx64ToolStripMenuItem_Click);
+ this.uninstallServerx64ToolStripMenuItem.Click += new System.EventHandler(this.uninstallServerX64ToolStripMenuItem_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
- this.toolStripSeparator1.Size = new System.Drawing.Size(353, 6);
+ this.toolStripSeparator1.Size = new System.Drawing.Size(188, 6);
+ this.toolStripSeparator1.Visible = false;
//
// testServerToolStripMenuItem
//
this.testServerToolStripMenuItem.Name = "testServerToolStripMenuItem";
- this.testServerToolStripMenuItem.Size = new System.Drawing.Size(356, 38);
+ this.testServerToolStripMenuItem.Size = new System.Drawing.Size(191, 22);
this.testServerToolStripMenuItem.Text = "&Test Server...";
+ this.testServerToolStripMenuItem.Visible = false;
this.testServerToolStripMenuItem.Click += new System.EventHandler(this.testServerToolStripMenuItem_Click);
//
// explorerToolStripMenuItem
@@ -370,14 +401,14 @@ private void InitializeComponent()
this.desktopProcessToolStripMenuItem,
this.restartExplorerToolStripMenuItem});
this.explorerToolStripMenuItem.Name = "explorerToolStripMenuItem";
- this.explorerToolStripMenuItem.Size = new System.Drawing.Size(113, 38);
+ this.explorerToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
this.explorerToolStripMenuItem.Text = "&Explorer";
//
// alwaysUnloadDLLToolStripMenuItem
//
this.alwaysUnloadDLLToolStripMenuItem.CheckOnClick = true;
this.alwaysUnloadDLLToolStripMenuItem.Name = "alwaysUnloadDLLToolStripMenuItem";
- this.alwaysUnloadDLLToolStripMenuItem.Size = new System.Drawing.Size(324, 38);
+ this.alwaysUnloadDLLToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.alwaysUnloadDLLToolStripMenuItem.Text = "&Always Unload DLL";
this.alwaysUnloadDLLToolStripMenuItem.Click += new System.EventHandler(this.alwaysUnloadDLLToolStripMenuItem_Click);
//
@@ -385,14 +416,14 @@ private void InitializeComponent()
//
this.desktopProcessToolStripMenuItem.CheckOnClick = true;
this.desktopProcessToolStripMenuItem.Name = "desktopProcessToolStripMenuItem";
- this.desktopProcessToolStripMenuItem.Size = new System.Drawing.Size(324, 38);
+ this.desktopProcessToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.desktopProcessToolStripMenuItem.Text = "&Desktop Process";
this.desktopProcessToolStripMenuItem.Click += new System.EventHandler(this.desktopProcessToolStripMenuItem_Click);
//
// restartExplorerToolStripMenuItem
//
this.restartExplorerToolStripMenuItem.Name = "restartExplorerToolStripMenuItem";
- this.restartExplorerToolStripMenuItem.Size = new System.Drawing.Size(324, 38);
+ this.restartExplorerToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.restartExplorerToolStripMenuItem.Text = "&Restart Explorer";
this.restartExplorerToolStripMenuItem.Click += new System.EventHandler(this.restartExplorerToolStripMenuItem_Click);
//
@@ -401,13 +432,13 @@ private void InitializeComponent()
this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.clearMostRecentlyUsedServersToolStripMenuItem});
this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
- this.toolsToolStripMenuItem.Size = new System.Drawing.Size(82, 38);
+ this.toolsToolStripMenuItem.Size = new System.Drawing.Size(47, 20);
this.toolsToolStripMenuItem.Text = "&Tools";
//
// clearMostRecentlyUsedServersToolStripMenuItem
//
this.clearMostRecentlyUsedServersToolStripMenuItem.Name = "clearMostRecentlyUsedServersToolStripMenuItem";
- this.clearMostRecentlyUsedServersToolStripMenuItem.Size = new System.Drawing.Size(459, 38);
+ this.clearMostRecentlyUsedServersToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
this.clearMostRecentlyUsedServersToolStripMenuItem.Text = "&Clear most recently used servers";
this.clearMostRecentlyUsedServersToolStripMenuItem.Click += new System.EventHandler(this.clearMostRecentlyUsedServersToolStripMenuItem_Click);
//
@@ -421,68 +452,68 @@ private void InitializeComponent()
this.toolStripSeparator5,
this.aboutToolStripMenuItem});
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
- this.helpToolStripMenuItem.Size = new System.Drawing.Size(77, 38);
+ this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "&Help";
//
// sharpShellProjectHomePageToolStripMenuItem
//
this.sharpShellProjectHomePageToolStripMenuItem.Name = "sharpShellProjectHomePageToolStripMenuItem";
- this.sharpShellProjectHomePageToolStripMenuItem.Size = new System.Drawing.Size(437, 38);
+ this.sharpShellProjectHomePageToolStripMenuItem.Size = new System.Drawing.Size(234, 22);
this.sharpShellProjectHomePageToolStripMenuItem.Text = "&SharpShell Project Home Page";
this.sharpShellProjectHomePageToolStripMenuItem.Click += new System.EventHandler(this.sharpShellProjectHomePageToolStripMenuItem_Click);
//
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
- this.toolStripSeparator4.Size = new System.Drawing.Size(434, 6);
+ this.toolStripSeparator4.Size = new System.Drawing.Size(231, 6);
//
// reportABugToolStripMenuItem
//
this.reportABugToolStripMenuItem.Name = "reportABugToolStripMenuItem";
- this.reportABugToolStripMenuItem.Size = new System.Drawing.Size(437, 38);
+ this.reportABugToolStripMenuItem.Size = new System.Drawing.Size(234, 22);
this.reportABugToolStripMenuItem.Text = "&Report a Bug";
this.reportABugToolStripMenuItem.Click += new System.EventHandler(this.reportABugToolStripMenuItem_Click);
//
// requestAFeatureToolStripMenuItem
//
this.requestAFeatureToolStripMenuItem.Name = "requestAFeatureToolStripMenuItem";
- this.requestAFeatureToolStripMenuItem.Size = new System.Drawing.Size(437, 38);
+ this.requestAFeatureToolStripMenuItem.Size = new System.Drawing.Size(234, 22);
this.requestAFeatureToolStripMenuItem.Text = "Request a &Feature";
this.requestAFeatureToolStripMenuItem.Click += new System.EventHandler(this.requestAFeatureToolStripMenuItem_Click);
//
// toolStripSeparator5
//
this.toolStripSeparator5.Name = "toolStripSeparator5";
- this.toolStripSeparator5.Size = new System.Drawing.Size(434, 6);
+ this.toolStripSeparator5.Size = new System.Drawing.Size(231, 6);
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
- this.aboutToolStripMenuItem.Size = new System.Drawing.Size(437, 38);
+ this.aboutToolStripMenuItem.Size = new System.Drawing.Size(234, 22);
this.aboutToolStripMenuItem.Text = "&About...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
//
- // toolStripMain
+ // toolStrip
//
- this.toolStripMain.Dock = System.Windows.Forms.DockStyle.None;
- this.toolStripMain.ImageScalingSize = new System.Drawing.Size(32, 32);
- this.toolStripMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.toolStrip.Dock = System.Windows.Forms.DockStyle.None;
+ this.toolStrip.ImageScalingSize = new System.Drawing.Size(32, 32);
+ this.toolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripButtonOpenTestShell,
this.toolStripButtonTestServer,
this.toolStripButtonOpenShellDialog,
this.toolStripSeparator6,
this.toolStripButtonAttachDebugger,
this.toolStripButtonShellDebugger});
- this.toolStripMain.Location = new System.Drawing.Point(3, 42);
- this.toolStripMain.Name = "toolStripMain";
- this.toolStripMain.Size = new System.Drawing.Size(1099, 39);
- this.toolStripMain.TabIndex = 3;
+ this.toolStrip.Location = new System.Drawing.Point(3, 24);
+ this.toolStrip.Name = "toolStrip";
+ this.toolStrip.Size = new System.Drawing.Size(616, 39);
+ this.toolStrip.TabIndex = 3;
//
// toolStripButtonOpenTestShell
//
this.toolStripButtonOpenTestShell.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButtonOpenTestShell.Name = "toolStripButtonOpenTestShell";
- this.toolStripButtonOpenTestShell.Size = new System.Drawing.Size(186, 36);
+ this.toolStripButtonOpenTestShell.Size = new System.Drawing.Size(92, 36);
this.toolStripButtonOpenTestShell.Text = "Open Test Shell";
this.toolStripButtonOpenTestShell.Click += new System.EventHandler(this.toolStripButtonOpenTestShell_Click);
//
@@ -490,8 +521,9 @@ private void InitializeComponent()
//
this.toolStripButtonTestServer.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButtonTestServer.Name = "toolStripButtonTestServer";
- this.toolStripButtonTestServer.Size = new System.Drawing.Size(270, 36);
+ this.toolStripButtonTestServer.Size = new System.Drawing.Size(132, 36);
this.toolStripButtonTestServer.Text = "Test Server in Test Shell";
+ this.toolStripButtonTestServer.Visible = false;
this.toolStripButtonTestServer.Click += new System.EventHandler(this.toolStripButtonTestServer_Click);
//
// toolStripButtonOpenShellDialog
@@ -500,7 +532,7 @@ private void InitializeComponent()
this.toolStripButtonOpenShellDialog.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButtonOpenShellDialog.Image")));
this.toolStripButtonOpenShellDialog.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButtonOpenShellDialog.Name = "toolStripButtonOpenShellDialog";
- this.toolStripButtonOpenShellDialog.Size = new System.Drawing.Size(213, 36);
+ this.toolStripButtonOpenShellDialog.Size = new System.Drawing.Size(105, 36);
this.toolStripButtonOpenShellDialog.Text = "Open Shell Dialog";
this.toolStripButtonOpenShellDialog.Click += new System.EventHandler(this.toolStripButtonOpenShellDialog_Click);
//
@@ -524,50 +556,52 @@ private void InitializeComponent()
this.toolStripButtonShellDebugger.Image = global::ServerManager.Properties.Resources.Debug;
this.toolStripButtonShellDebugger.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButtonShellDebugger.Name = "toolStripButtonShellDebugger";
- this.toolStripButtonShellDebugger.Size = new System.Drawing.Size(376, 36);
+ this.toolStripButtonShellDebugger.Size = new System.Drawing.Size(202, 36);
this.toolStripButtonShellDebugger.Text = "Shell Debugger (Experimental)";
this.toolStripButtonShellDebugger.Click += new System.EventHandler(this.toolStripButtonShellDebugger_Click);
//
- // installToolStripMenuItem
+ // panelPleaseWait
//
- this.installToolStripMenuItem.Name = "installToolStripMenuItem";
- this.installToolStripMenuItem.Size = new System.Drawing.Size(356, 38);
- this.installToolStripMenuItem.Text = "&Install";
- this.installToolStripMenuItem.Click += new System.EventHandler(this.installToolStripMenuItem_Click);
- //
- // uninstallToolStripMenuItem
- //
- this.uninstallToolStripMenuItem.Name = "uninstallToolStripMenuItem";
- this.uninstallToolStripMenuItem.Size = new System.Drawing.Size(356, 38);
- this.uninstallToolStripMenuItem.Text = "&Uninstall";
- this.uninstallToolStripMenuItem.Click += new System.EventHandler(this.uninstallToolStripMenuItem_Click);
+ this.panelPleaseWait.Anchor = System.Windows.Forms.AnchorStyles.None;
+ this.panelPleaseWait.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.panelPleaseWait.Controls.Add(this.label1);
+ this.panelPleaseWait.Controls.Add(this.progressBar1);
+ this.panelPleaseWait.Location = new System.Drawing.Point(400, 300);
+ this.panelPleaseWait.Name = "panelPleaseWait";
+ this.panelPleaseWait.Size = new System.Drawing.Size(300, 50);
+ this.panelPleaseWait.TabIndex = 1;
+ this.panelPleaseWait.Visible = false;
//
- // serverDetailsView1
+ // label1
//
- this.serverDetailsView1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.serverDetailsView1.Location = new System.Drawing.Point(0, 0);
- this.serverDetailsView1.Margin = new System.Windows.Forms.Padding(12);
- this.serverDetailsView1.Name = "serverDetailsView1";
- this.serverDetailsView1.Size = new System.Drawing.Size(380, 859);
- this.serverDetailsView1.TabIndex = 1;
+ this.label1.Location = new System.Drawing.Point(3, 3);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(292, 17);
+ this.label1.TabIndex = 1;
+ this.label1.Text = "Please wait ...";
+ this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
- // toolStripSeparator7
+ // progressBar1
//
- this.toolStripSeparator7.Name = "toolStripSeparator7";
- this.toolStripSeparator7.Size = new System.Drawing.Size(353, 6);
+ this.progressBar1.Location = new System.Drawing.Point(3, 23);
+ this.progressBar1.Name = "progressBar1";
+ this.progressBar1.Size = new System.Drawing.Size(292, 23);
+ this.progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Marquee;
+ this.progressBar1.TabIndex = 0;
+ this.progressBar1.Value = 33;
//
// ServerManagerForm
//
- this.AutoScaleDimensions = new System.Drawing.SizeF(192F, 192F);
+ this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
- this.ClientSize = new System.Drawing.Size(1744, 981);
+ this.ClientSize = new System.Drawing.Size(1084, 661);
+ this.Controls.Add(this.panelPleaseWait);
this.Controls.Add(this.toolStripContainer1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
- this.MainMenuStrip = this.menuStrip1;
- this.Margin = new System.Windows.Forms.Padding(6);
+ this.MainMenuStrip = this.menuStrip;
this.Name = "ServerManagerForm";
this.Text = "Server Manager";
- this.Load += new System.EventHandler(this.ServerManagerForm_Load);
+ this.Shown += new System.EventHandler(this.ServerManagerForm_Shown);
this.toolStripContainer1.BottomToolStripPanel.ResumeLayout(false);
this.toolStripContainer1.BottomToolStripPanel.PerformLayout();
this.toolStripContainer1.ContentPanel.ResumeLayout(false);
@@ -575,16 +609,17 @@ private void InitializeComponent()
this.toolStripContainer1.TopToolStripPanel.PerformLayout();
this.toolStripContainer1.ResumeLayout(false);
this.toolStripContainer1.PerformLayout();
- this.statusStrip1.ResumeLayout(false);
- this.statusStrip1.PerformLayout();
- this.splitContainer1.Panel1.ResumeLayout(false);
- this.splitContainer1.Panel2.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
- this.splitContainer1.ResumeLayout(false);
- this.menuStrip1.ResumeLayout(false);
- this.menuStrip1.PerformLayout();
- this.toolStripMain.ResumeLayout(false);
- this.toolStripMain.PerformLayout();
+ this.statusStrip.ResumeLayout(false);
+ this.statusStrip.PerformLayout();
+ this.splitContainer.Panel1.ResumeLayout(false);
+ this.splitContainer.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+ this.splitContainer.ResumeLayout(false);
+ this.menuStrip.ResumeLayout(false);
+ this.menuStrip.PerformLayout();
+ this.toolStrip.ResumeLayout(false);
+ this.toolStrip.PerformLayout();
+ this.panelPleaseWait.ResumeLayout(false);
this.ResumeLayout(false);
}
@@ -596,7 +631,7 @@ private void InitializeComponent()
private System.Windows.Forms.ColumnHeader columnHeaderServerName;
private System.Windows.Forms.ColumnHeader columnHeader;
private System.Windows.Forms.ColumnHeader columnHeaderServerType;
- private System.Windows.Forms.MenuStrip menuStrip1;
+ private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem explorerToolStripMenuItem;
@@ -606,13 +641,13 @@ private void InitializeComponent()
private System.Windows.Forms.ToolStripMenuItem installServerx86ToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem uninstallServerx86ToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
- private System.Windows.Forms.StatusStrip statusStrip1;
+ private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
private System.Windows.Forms.ToolStripMenuItem loadServerToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ImageList imageList1;
- private System.Windows.Forms.SplitContainer splitContainer1;
- private ServerDetailsView serverDetailsView1;
+ private System.Windows.Forms.SplitContainer splitContainer;
+ private ServerDetailsView serverDetailsView;
private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem clearMostRecentlyUsedServersToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem installServerx64ToolStripMenuItem;
@@ -624,7 +659,7 @@ private void InitializeComponent()
private System.Windows.Forms.ToolStripMenuItem unregisterServerx64ToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem restartExplorerToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem testServerToolStripMenuItem;
- private System.Windows.Forms.ToolStrip toolStripMain;
+ private System.Windows.Forms.ToolStrip toolStrip;
private System.Windows.Forms.ToolStripButton toolStripButtonTestServer;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem sharpShellProjectHomePageToolStripMenuItem;
@@ -643,6 +678,9 @@ private void InitializeComponent()
private System.Windows.Forms.ToolStripMenuItem installToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem uninstallToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
+ private System.Windows.Forms.Panel panelPleaseWait;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.ProgressBar progressBar1;
}
}
diff --git a/SharpShell/Tools/ServerManager/ServerManagerForm.cs b/SharpShell/Tools/ServerManager/ServerManagerForm.cs
index 2b2af8d5..4efafa4c 100644
--- a/SharpShell/Tools/ServerManager/ServerManagerForm.cs
+++ b/SharpShell/Tools/ServerManager/ServerManagerForm.cs
@@ -2,186 +2,139 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
-using System.Drawing;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using System.Windows.Forms;
-using Apex.WinForms.Interop;
-using Apex.WinForms.Shell;
+using ServerManager.Properties;
using ServerManager.ShellDebugger;
using ServerManager.TestShell;
+using ServerManager.Views;
using SharpShell;
-using SharpShell.Attributes;
using SharpShell.Diagnostics;
-using SharpShell.Helpers;
using SharpShell.ServerRegistration;
-using SharpShell.SharpContextMenu;
-using SharpShell.SharpDropHandler;
-using SharpShell.SharpIconHandler;
-using SharpShell.SharpIconOverlayHandler;
-using SharpShell.SharpInfoTipHandler;
-using SharpShell.SharpPreviewHandler;
-using SharpShell.SharpPropertySheet;
-using SharpShell.SharpThumbnailHandler;
namespace ServerManager
{
///
- /// The main class
+ /// The main class
///
- public partial class ServerManagerForm : Form
+ internal partial class ServerManagerForm : Form
{
+ ///
+ /// The explorer configuration manager.
+ ///
+ private readonly ExplorerConfigurationManager
+ _explorerConfigurationManager = new ExplorerConfigurationManager();
+
public ServerManagerForm()
{
InitializeComponent();
- if (Properties.Settings.Default.RecentlyUsedFiles == null)
- Properties.Settings.Default.RecentlyUsedFiles = new StringCollection();
+ // Setup the statusbar.
+ toolStripStatusLabelOSProcessor.Text =
+ Environment.Is64BitOperatingSystem ? "Windows (x64)" : "Windows (x86)";
+ toolStripStatusLabelProcessProcessor.Text = Environment.Is64BitProcess ? "Process (x64)" : "Process (x86)";
+
+ // Set the settings.
+ desktopProcessToolStripMenuItem.Checked = _explorerConfigurationManager.DesktopProcess;
+ alwaysUnloadDLLToolStripMenuItem.Checked = _explorerConfigurationManager.AlwaysUnloadDll;
// Set initial UI command state.
UpdateUserInterfaceCommands();
}
- public IEnumerable ServerEntries
+ #region Control Event Handlers
+
+ private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
- get { return listViewServers.Items.OfType().Select(lvi => lvi.Tag).OfType(); }
+ new AboutForm().ShowDialog(this);
}
- public void AddServer(string path, bool addToMostRecentlyUsedFiles)
+ private void alwaysUnloadDLLToolStripMenuItem_Click(object sender, EventArgs e)
{
- if (ServerEntries.Any(se => se.ServerPath == path))
- return;
-
- // Load any servers from the assembly.
- var serverEntries = ServerManagerApi.LoadServers(path);
- foreach(var serverEntry in serverEntries)
- {
- AddServerEntryToList(serverEntry);
- }
-
- if (addToMostRecentlyUsedFiles && Properties.Settings.Default.RecentlyUsedFiles.Contains(path) == false)
- {
- // We've successfully added the server - so add the path of the server to our recent files.
- Properties.Settings.Default.RecentlyUsedFiles.Insert(0, path);
- Properties.Settings.Default.Save();
- }
+ _explorerConfigurationManager.AlwaysUnloadDll = alwaysUnloadDLLToolStripMenuItem.Checked;
}
- private void AddServerEntryToList(ServerEntry serverEntry)
+ private void CheckIfRegisterOrUnregisterRequiresExplorerRestart(params SharpShellServerInfo[] servers)
{
- var listItem = new ListViewItem(
- new[]
- {
- serverEntry.ServerName,
- serverEntry.ServerType.ToString(),
- serverEntry.ClassId.ToString()
- }) {Tag = serverEntry};
-
- switch (serverEntry.ServerType)
+ if (servers?.Any(server => server?.ServerType == ServerType.ShellIconOverlayHandler) == true)
{
- case ServerType.ShellContextMenu:
- listItem.ImageIndex = 0;
- break;
- case ServerType.ShellPropertySheet:
- listItem.ImageIndex = 2;
- break;
- case ServerType.ShellIconHandler:
- listItem.ImageIndex = 1;
- break;
- case ServerType.ShellInfoTipHandler:
- listItem.ImageIndex = 3;
- break;
- case ServerType.ShellIconOverlayHandler:
- listItem.ImageIndex = 4;
- break;
- default:
- listItem.ImageIndex = 0;
- break;
+ if (MessageBox.Show(this,
+ @"This change will not take effect until Windows Explorer is restarted. Would you " +
+ @"like to restart Windows Explorer now?", @"Restart Explorer?", MessageBoxButtons.YesNo,
+ MessageBoxIcon.Question) ==
+ DialogResult.Yes)
+ {
+ ExplorerManager.RestartExplorer();
+ }
}
-
- if (serverEntry.IsInvalid)
- listItem.ForeColor = Color.FromArgb(255, 0, 0);
-
- listViewServers.Items.Add(listItem);
-
}
- public ServerEntry SelectedServerEntry
+ private void clearMostRecentlyUsedServersToolStripMenuItem_Click(object sender, EventArgs e)
{
- get { return listViewServers.SelectedItems.Count > 0 ? (ServerEntry)listViewServers.SelectedItems[0].Tag : null; }
+ ClearRecentlyUsed();
}
- private void ServerManagerForm_Load(object sender, EventArgs e)
+ private void desktopProcessToolStripMenuItem_Click(object sender, EventArgs e)
{
- // Setup the statusbar.
- toolStripStatusLabelOSProcessor.Text = Environment.Is64BitOperatingSystem ? "Windows (x64)" : "Windows (x86)";
- toolStripStatusLabelProcessProcessor.Text = Environment.Is64BitProcess ? "Process (x64)" : "Process (x86)";
-
- // Set the settings.
- desktopProcessToolStripMenuItem.Checked = explorerConfigurationManager.DesktopProcess;
- alwaysUnloadDLLToolStripMenuItem.Checked = explorerConfigurationManager.AlwaysUnloadDll;
-
- // Add the recently used servers. If any of them fail to load, we'll remove them from the list.
- var recentlyUsedFilesToRemove = new List();
- if (Properties.Settings.Default.RecentlyUsedFiles != null)
- {
- foreach(var path in Properties.Settings.Default.RecentlyUsedFiles)
- AddServer(path, false);
- }
-
- // Check for any servers added via the command line.
- var arguments = Environment.GetCommandLineArgs();
- for(int i = 1; i < arguments.Count(); i++)
- {
- var arg = arguments[i];
- if(File.Exists(arg))
- AddServer(arg, true);
- }
+ _explorerConfigurationManager.DesktopProcess = desktopProcessToolStripMenuItem.Checked;
}
- private void alwaysUnloadDLLToolStripMenuItem_Click(object sender, EventArgs e)
+ private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
- explorerConfigurationManager.AlwaysUnloadDll = alwaysUnloadDLLToolStripMenuItem.Checked;
+ Close();
}
- private void desktopProcessToolStripMenuItem_Click(object sender, EventArgs e)
+ private void installServerX64ToolStripMenuItem_Click(object sender, EventArgs e)
{
- explorerConfigurationManager.DesktopProcess = desktopProcessToolStripMenuItem.Checked;
+ // Install the server.
+ InstallServer(SelectedEntry, RegistrationScope.OS64Bit);
}
- ///
- /// The explorer configuration manager.
- ///
- private readonly ExplorerConfigurationManager explorerConfigurationManager = new ExplorerConfigurationManager();
-
- private void installServerx86ToolStripMenuItem_Click(object sender, EventArgs e)
+ private void installServerX86ToolStripMenuItem_Click(object sender, EventArgs e)
{
- if (SelectedServerEntry == null)
- return;
-
- ServerRegistrationManager.InstallServer(SelectedServerEntry.Server, RegistrationType.OS32Bit, true);
- serverDetailsView1.Initialise(SelectedServerEntry);
+ // Install the server.
+ InstallServer(SelectedEntry, RegistrationScope.OS32Bit);
}
-
- private void uninstallServerx86ToolStripMenuItem_Click(object sender, EventArgs e)
+
+ private void installToolStripMenuItem_Click(object sender, EventArgs e)
{
- if (SelectedServerEntry == null)
+ // Bail if we have no server selected.
+ if (SelectedEntry?.SharpShellServerInfo?.AssemblyInfo == null)
+ {
return;
+ }
+
+ var assembly = SelectedEntry.SharpShellServerInfo.AssemblyInfo;
+ var fromGac = string.IsNullOrEmpty(SelectedEntry.SharpShellServerInfo.AssemblyInfo.AssemblyPath);
+ var success = InstallAssembly(assembly, !fromGac);
- // Unregister the server.
- ServerRegistrationManager.UninstallServer(SelectedServerEntry.Server, RegistrationType.OS32Bit);
- serverDetailsView1.Initialise(SelectedServerEntry);
+ // Inform the user of the result.
+ if (success)
+ {
+ MessageBox.Show(@"Installed server successfully.", @"Install Server", MessageBoxButtons.OK,
+ MessageBoxIcon.Information);
+ }
+ else
+ {
+ MessageBox.Show(@"Failed to install, check the SharpShell log for details.", @"Install Server",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ }
}
- private void loadServerToolStripMenuItem_Click(object sender, EventArgs e)
+ private void listViewServers_DragDrop(object sender, DragEventArgs e)
{
- // Create a file open dialog.
- var fileOpenDialog = new OpenFileDialog();
- fileOpenDialog.Filter = "COM Servers (*.dll)|*.dll|All Files (*.*)|*.*";
- if (fileOpenDialog.ShowDialog(this) == DialogResult.OK)
+ if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
- // Try and add the server.
- AddServer(fileOpenDialog.FileName, true);
+ if (e.Data.GetData(DataFormats.FileDrop) is string[] files)
+ {
+ foreach (var file in files)
+ {
+ AddServersFromFile(file);
+ }
+ }
}
}
@@ -189,7 +142,9 @@ private void listViewServers_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
- e.Effect = ((string[]) e.Data.GetData(DataFormats.FileDrop)).Any() ? DragDropEffects.Copy : DragDropEffects.None;
+ e.Effect = ((string[])e.Data.GetData(DataFormats.FileDrop)).Any()
+ ? DragDropEffects.Copy
+ : DragDropEffects.None;
}
else
{
@@ -197,16 +152,27 @@ private void listViewServers_DragEnter(object sender, DragEventArgs e)
}
}
- private void listViewServers_DragDrop(object sender, DragEventArgs e)
+ private void listViewServers_KeyDown(object sender, KeyEventArgs e)
{
-
- if (e.Data.GetDataPresent(DataFormats.FileDrop))
+ if (SelectedEntry == null)
{
- var files = e.Data.GetData(DataFormats.FileDrop) as string[];
- if (files != null)
+ return;
+ }
+
+ if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back)
+ {
+ var selectedServerEntry = SelectedEntry;
+
+ // If we have a server selected, remove it.
+ if (selectedServerEntry?.InstallationInfo32 == null &&
+ selectedServerEntry?.InstallationInfo64 == null &&
+ selectedServerEntry?.RegistrationInfo32 == null &&
+ selectedServerEntry?.RegistrationInfo64 == null)
{
- foreach(var file in files)
- AddServer(file, true);
+ RemoveExtensionEntryFromList(selectedServerEntry);
+
+ // Remove from the most recently used files.
+ RemoveRecentlyUsed(selectedServerEntry?.SharpShellServerInfo?.AssemblyInfo?.AssemblyPath);
}
}
}
@@ -216,279 +182,603 @@ private void listViewServers_SelectedIndexChanged(object sender, EventArgs e)
// Update the user interface commands.
UpdateUserInterfaceCommands();
- // Update the details view with the selected server entry.
- serverDetailsView1.Initialise(SelectedServerEntry);
+ // Update list view
+ AddOrUpdateEntry(SelectedEntry);
}
- private void listViewServers_KeyDown(object sender, KeyEventArgs e)
+ private void loadServerToolStripMenuItem_Click(object sender, EventArgs e)
{
- if (SelectedServerEntry == null)
- return;
-
- if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back)
+ // Create a file open dialog.
+ var fileOpenDialog = new OpenFileDialog
{
- var selectedServerEntry = SelectedServerEntry;
+ Filter = @"COM Servers (*.dll)|*.dll|All Files (*.*)|*.*"
+ };
- // If we have a server selected, remove it.
- var item = listViewServers.Items.OfType().FirstOrDefault(li => li.Tag == selectedServerEntry);
- if (item != null)
- {
- listViewServers.Items.Remove(item);
-
- // Remove from the most recently used files.
- if (Properties.Settings.Default.RecentlyUsedFiles != null)
- {
- Properties.Settings.Default.RecentlyUsedFiles.Remove(selectedServerEntry.ServerPath);
- Properties.Settings.Default.Save();
- }
- }
+ if (fileOpenDialog.ShowDialog(this) == DialogResult.OK)
+ {
+ // Try and add the server.
+ AddServersFromFile(fileOpenDialog.FileName);
}
+ }
+ private void registerServerX64ToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ // Register the server
+ RegisterServer(SelectedEntry, RegistrationScope.OS64Bit);
}
- private void clearMostRecentlyUsedServersToolStripMenuItem_Click(object sender, EventArgs e)
+ private void registerServerX86ToolStripMenuItem_Click(object sender, EventArgs e)
{
- Properties.Settings.Default.RecentlyUsedFiles.Clear();
- Properties.Settings.Default.Save();
+ // Register the server
+ RegisterServer(SelectedEntry, RegistrationScope.OS32Bit);
}
- private void exitToolStripMenuItem_Click(object sender, EventArgs e)
+ private void reportABugToolStripMenuItem_Click(object sender, EventArgs e)
{
- Close();
+ Process.Start(Resources.UrlReportABug);
}
- private void installServerx64ToolStripMenuItem_Click(object sender, EventArgs e)
+ private void requestAFeatureToolStripMenuItem_Click(object sender, EventArgs e)
{
- // Get the selected server.
- var selectedServer = SelectedServerEntry;
- if (selectedServer == null)
- return;
+ Process.Start(Resources.URlSuggestAFeature);
+ }
- ServerRegistrationManager.InstallServer(SelectedServerEntry.Server, RegistrationType.OS64Bit, true);
- serverDetailsView1.Initialise(SelectedServerEntry);
+ private void restartExplorerToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ ExplorerManager.RestartExplorer();
}
- private void uninstallServerx64ToolStripMenuItem_Click(object sender, EventArgs e)
+
+ private void ServerManagerForm_Shown(object sender, EventArgs e)
{
- // Bail if we have no server selected.
- if (SelectedServerEntry == null)
- return;
+ PrepareServerList();
+ }
- ServerRegistrationManager.UninstallServer(SelectedServerEntry.Server, RegistrationType.OS64Bit);
- serverDetailsView1.Initialise(SelectedServerEntry);
+ private void sharpShellProjectHomePageToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ Process.Start(Resources.UrlSharpShellProjectHomePage);
}
- private void CheckIfRegisterOrUnregisterRequiresExplorerRestart(ISharpShellServer server)
+ private void testServerToolStripMenuItem_Click(object sender, EventArgs e)
{
- if (server.ServerType == ServerType.ShellIconOverlayHandler)
- {
- if (MessageBox.Show(this, "This change will not take effect until Windows Explorer is restarted. Would you " +
- "like to restart Windows Explorer now?", "Restart Explorer?", MessageBoxButtons.YesNo,
- MessageBoxIcon.Question) == DialogResult.Yes)
- {
- ExplorerManager.RestartExplorer();
- }
- }
+ // Call the test server command.
+ DoTestServer();
}
- private void registerServerx86ToolStripMenuItem_Click(object sender, EventArgs e)
+ private void toolStripButtonAttachDebugger_Click(object sender, EventArgs e)
{
- // Bail if we have no server selected.
- if (SelectedServerEntry == null)
- return;
+ Debugger.Launch();
+ }
- // Register the server, x86 mode.
- ServerRegistrationManager.RegisterServer(SelectedServerEntry.Server, RegistrationType.OS32Bit);
- serverDetailsView1.Initialise(SelectedServerEntry);
- CheckIfRegisterOrUnregisterRequiresExplorerRestart(SelectedServerEntry.Server);
+ private void toolStripButtonOpenShellDialog_Click(object sender, EventArgs e)
+ {
+ // Show a shell dialog.
+ new OpenFileDialog().ShowDialog(this);
}
- private void registerServerx64ToolStripMenuItem_Click(object sender, EventArgs e)
+ private void toolStripButtonOpenTestShell_Click(object sender, EventArgs e)
{
- // Bail if we have no server selected.
- if (SelectedServerEntry == null)
- return;
+ new TestShellForm().ShowDialog(this);
+ }
- // Register the server, x64 mode.
- ServerRegistrationManager.RegisterServer(SelectedServerEntry.Server, RegistrationType.OS64Bit);
- serverDetailsView1.Initialise(SelectedServerEntry);
- CheckIfRegisterOrUnregisterRequiresExplorerRestart(SelectedServerEntry.Server);
+ private void toolStripButtonShellDebugger_Click(object sender, EventArgs e)
+ {
+ // Create and show a new shell debugger.
+ new ShellDebuggerForm().ShowDialog(this);
}
- private void unregisterServerx86ToolStripMenuItem_Click(object sender, EventArgs e)
+ private void toolStripButtonTestServer_Click(object sender, EventArgs e)
{
- // Bail if we have no server selected.
- if (SelectedServerEntry == null)
- return;
+ // Call the test server command.
+ DoTestServer();
+ }
- // Unregister the server, x86 mode.
- ServerRegistrationManager.UnregisterServer(SelectedServerEntry.Server, RegistrationType.OS32Bit);
- serverDetailsView1.Initialise(SelectedServerEntry);
- CheckIfRegisterOrUnregisterRequiresExplorerRestart(SelectedServerEntry.Server);
+ private void uninstallServerX64ToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ // Uninstall the server.
+ UninstallServer(SelectedEntry, RegistrationScope.OS64Bit);
}
- private void unregisterServerx64ToolStripMenuItem_Click(object sender, EventArgs e)
+ private void uninstallServerX86ToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ // Uninstall the server.
+ UninstallServer(SelectedEntry, RegistrationScope.OS32Bit);
+ }
+
+
+ private void uninstallToolStripMenuItem_Click(object sender, EventArgs e)
{
// Bail if we have no server selected.
- if (SelectedServerEntry == null)
+ if (SelectedEntry?.SharpShellServerInfo?.AssemblyInfo == null)
+ {
return;
+ }
+
+ var assemblyInfo = SelectedEntry.SharpShellServerInfo.AssemblyInfo;
- // Unregister the server, x64 mode.
- ServerRegistrationManager.UnregisterServer(SelectedServerEntry.Server, RegistrationType.OS64Bit);
- serverDetailsView1.Initialise(SelectedServerEntry);
- CheckIfRegisterOrUnregisterRequiresExplorerRestart(SelectedServerEntry.Server);
+ // Inform the user of the result.
+ if (UninstallAssembly(assemblyInfo))
+ {
+ MessageBox.Show(@"Uninstalled server successfully.", @"Uninstall Server", MessageBoxButtons.OK,
+ MessageBoxIcon.Information);
+ }
+ else
+ {
+ MessageBox.Show(@"Failed to uninstall, check the SharpShell log for details.", @"Uninstall Server",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ }
}
- private void restartExplorerToolStripMenuItem_Click(object sender, EventArgs e)
+ private void unregisterServerX64ToolStripMenuItem_Click(object sender, EventArgs e)
{
- ExplorerManager.RestartExplorer();
+ // Unregister the server
+ UnregisterServer(SelectedEntry, RegistrationScope.OS64Bit);
}
-
- private void UpdateUserInterfaceCommands()
- {
- // Install/Uninstall etc etc only available if we have a selection.
- installServerx86ToolStripMenuItem.Enabled = SelectedServerEntry != null;
- installServerx64ToolStripMenuItem.Enabled = SelectedServerEntry != null;
- registerServerx86ToolStripMenuItem.Enabled = SelectedServerEntry != null;
- registerServerx64ToolStripMenuItem.Enabled = SelectedServerEntry != null;
- unregisterServerx86ToolStripMenuItem.Enabled = SelectedServerEntry != null;
- unregisterServerx64ToolStripMenuItem.Enabled = SelectedServerEntry != null;
- uninstallServerx86ToolStripMenuItem.Enabled = SelectedServerEntry != null;
- uninstallServerx64ToolStripMenuItem.Enabled = SelectedServerEntry != null;
- // Test functions only available for specific servers.
- testServerToolStripMenuItem.Enabled =
- (
- SelectedServerEntry != null &&
- (
- SelectedServerEntry.Server is SharpContextMenu ||
- SelectedServerEntry.Server is SharpIconHandler ||
- SelectedServerEntry.Server is SharpInfoTipHandler ||
- SelectedServerEntry.Server is SharpDropHandler ||
- SelectedServerEntry.Server is SharpPreviewHandler ||
- SelectedServerEntry.Server is SharpThumbnailHandler ||
- SelectedServerEntry.Server is SharpIconOverlayHandler
- )
- );
- toolStripButtonTestServer.Enabled = testServerToolStripMenuItem.Enabled;
+ private void unregisterServerX86ToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ // Unregister the server
+ UnregisterServer(SelectedEntry, RegistrationScope.OS32Bit);
}
- private void testServerToolStripMenuItem_Click(object sender, EventArgs e)
+ #endregion
+
+ #region Main Logic
+
+ public IEnumerable Entries
{
- // Call the test server command.
- DoTestServer();
+ get
+ {
+ return listViewServers.Items
+ .OfType()
+ .Select(item => item.ExtensionEntry);
+ }
}
- private void toolStripButtonTestServer_Click(object sender, EventArgs e)
+ public ShellExtensionEntry SelectedEntry
{
- // Call the test server command.
- DoTestServer();
+ get => listViewServers.SelectedItems.OfType().FirstOrDefault()?.ExtensionEntry;
}
///
- /// Tests the selected serer.
+ /// Tests the selected serer.
///
private void DoTestServer()
{
// If we don't have a server, bail.
- if (SelectedServerEntry == null)
+ if (SelectedEntry == null)
+ {
return;
+ }
+
+ // TODO
// Create a test shell form.
- var testShellForm = new TestShellForm { TestServer = SelectedServerEntry.Server };
+ //var testShellForm = new TestShellForm { TestServer = SelectedEntry };
// Show the form.
- testShellForm.ShowDialog(this);
+ //testShellForm.ShowDialog(this);
}
- private void sharpShellProjectHomePageToolStripMenuItem_Click(object sender, EventArgs e)
+ private void UpdateUserInterfaceCommands()
{
- Process.Start(Properties.Resources.UrlSharpShellProjectHomePage);
- }
+ // Install/Uninstall etc etc only available if we have a selection.
+ installServerx86ToolStripMenuItem.Enabled = SelectedEntry?.SharpShellServerInfo != null;
+ installServerx64ToolStripMenuItem.Enabled = SelectedEntry?.SharpShellServerInfo != null;
+ registerServerx86ToolStripMenuItem.Enabled = SelectedEntry?.SharpShellServerInfo != null;
+ registerServerx64ToolStripMenuItem.Enabled = SelectedEntry?.SharpShellServerInfo != null;
+ unregisterServerx86ToolStripMenuItem.Enabled = SelectedEntry != null;
+ unregisterServerx64ToolStripMenuItem.Enabled = SelectedEntry != null;
+ uninstallServerx86ToolStripMenuItem.Enabled = SelectedEntry != null;
+ uninstallServerx64ToolStripMenuItem.Enabled = SelectedEntry != null;
+ installToolStripMenuItem.Enabled = SelectedEntry?.SharpShellServerInfo != null;
+ uninstallToolStripMenuItem.Enabled = SelectedEntry != null;
+
+ // Get selected managed server type
+ var serverType = SelectedEntry?.SharpShellServerInfo?.ServerType;
- private void reportABugToolStripMenuItem_Click(object sender, EventArgs e)
+ // Test functions only available for specific servers.
+ testServerToolStripMenuItem.Enabled =
+ SelectedEntry != null &&
+ (
+ serverType == ServerType.ShellContextMenu ||
+ serverType == ServerType.ShellIconHandler ||
+ serverType == ServerType.ShellInfoTipHandler ||
+ serverType == ServerType.ShellDropHandler ||
+ serverType == ServerType.ShellPreviewHandler ||
+ serverType == ServerType.ShellThumbnailHandler ||
+ serverType == ServerType.ShellIconOverlayHandler
+ );
+
+ toolStripButtonTestServer.Enabled = testServerToolStripMenuItem.Enabled;
+ }
+
+ private bool InstallAssembly(ManagedAssemblyInfo assembly, bool codeBase)
{
- Process.Start(Properties.Resources.UrlReportABug);
+ // Get all server types
+ var servers = SharpShellServerInfo.FromAssembly(assembly).ToArray();
+
+ var registrationScope = Environment.Is64BitOperatingSystem
+ ? RegistrationScope.OS64Bit
+ : RegistrationScope.OS32Bit;
+
+ var success = true;
+
+ foreach (var server in servers)
+ {
+ try
+ {
+ ServerRegistrationManager.InstallServer(server, registrationScope, codeBase);
+ ServerRegistrationManager.RegisterAndApproveServer(server, registrationScope);
+ }
+ catch (Exception exception)
+ {
+ Logging.Error($"Failed to uninstall and unregister a server. [{server.DisplayName}]", exception);
+ success = false;
+ }
+
+ AddOrUpdateEntry(new ShellExtensionEntry(server));
+ }
+
+ CheckIfRegisterOrUnregisterRequiresExplorerRestart(servers);
+
+ return success;
}
+
+ private bool UninstallAssembly(ManagedAssemblyInfo assemblyInfo)
+ {
+ // Get all server types
+ var servers = SharpShellServerInfo.FromAssembly(assemblyInfo).ToArray();
- private void requestAFeatureToolStripMenuItem_Click(object sender, EventArgs e)
+ var registrationScope = Environment.Is64BitOperatingSystem
+ ? RegistrationScope.OS64Bit
+ : RegistrationScope.OS32Bit;
+
+ var success = true;
+
+ foreach (var server in servers)
+ {
+ try
+ {
+ ServerRegistrationManager.UnregisterAndUnApproveServer(server, registrationScope);
+ ServerRegistrationManager.UninstallServer(server, registrationScope);
+ }
+ catch (Exception exception)
+ {
+ Logging.Error($"Failed to uninstall and unregister a server. [{server.DisplayName}]", exception);
+ success = false;
+ }
+
+ AddOrUpdateEntry(new ShellExtensionEntry(server));
+ }
+
+ CheckIfRegisterOrUnregisterRequiresExplorerRestart(servers);
+
+ return success;
+ }
+
+ private void RemoveRecentlyUsed(string filePath)
{
- Process.Start(Properties.Resources.URlSuggestAFeature);
+ if (Settings.Default.RecentlyUsedFiles != null && !string.IsNullOrEmpty(filePath))
+ {
+ Settings.Default.RecentlyUsedFiles.Remove(filePath);
+ Settings.Default.Save();
+ }
}
- private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
+ private void AddRecentlyUsed(string filePath)
{
- (new AboutForm()).ShowDialog(this);
+ if (Settings.Default.RecentlyUsedFiles == null)
+ {
+ Settings.Default.RecentlyUsedFiles = new StringCollection();
+ }
+
+ if (!string.IsNullOrEmpty(filePath) &&
+ !Settings.Default.RecentlyUsedFiles.Contains(filePath))
+ {
+ Settings.Default.RecentlyUsedFiles.Insert(0, filePath);
+ Settings.Default.Save();
+ }
}
-
- private void toolStripButtonOpenTestShell_Click(object sender, EventArgs e)
+
+ private void ClearRecentlyUsed()
{
- (new TestShellForm()).ShowDialog(this);
+ if (Settings.Default.RecentlyUsedFiles != null)
+ {
+ Settings.Default.RecentlyUsedFiles.Clear();
+ Settings.Default.Save();
+ }
}
- private void toolStripButtonOpenShellDialog_Click(object sender, EventArgs e)
+ private bool InstallServer(ShellExtensionEntry entry, RegistrationScope registrationScope)
{
- // Show a shell dialog.
- var openFileDialog = new OpenFileDialog();
- openFileDialog.ShowDialog(this);
+ if (entry?.SharpShellServerInfo?.AssemblyInfo == null)
+ {
+ return false;
+ }
+
+ var codeBase = !string.IsNullOrEmpty(entry?.SharpShellServerInfo?.AssemblyInfo?.AssemblyPath);
+
+ ServerRegistrationManager.InstallServer(entry.SharpShellServerInfo, registrationScope, codeBase);
+
+ if (registrationScope == RegistrationScope.OS64Bit)
+ {
+ entry.UpdateInstallationInfo64();
+ }
+ else
+ {
+ entry.UpdateInstallationInfo32();
+ }
+
+ AddOrUpdateEntry(entry);
+
+ return true;
}
- private void toolStripButtonShellDebugger_Click(object sender, EventArgs e)
+ private bool UninstallServer(ShellExtensionEntry entry, RegistrationScope registrationScope)
{
- // Create and show a new shell debugger.
- var debugger = new ShellDebuggerForm();
- debugger.ShowDialog(this);
+ if (entry == null)
+ {
+ return false;
+ }
+
+ ServerRegistrationManager.UninstallServer(entry.ServerClassId, registrationScope);
+
+ if (registrationScope == RegistrationScope.OS64Bit)
+ {
+ entry.UpdateInstallationInfo64();
+ }
+ else
+ {
+ entry.UpdateInstallationInfo32();
+ }
+
+ AddOrUpdateEntry(entry);
+
+ return true;
}
- private void toolStripButtonAttachDebugger_Click(object sender, EventArgs e)
+ private bool RegisterServer(ShellExtensionEntry entry, RegistrationScope registrationScope)
{
- Debugger.Launch();
+ if (entry?.SharpShellServerInfo == null)
+ {
+ return false;
+ }
+
+ ServerRegistrationManager.RegisterAndApproveServer(entry.SharpShellServerInfo, registrationScope);
+
+ if (registrationScope == RegistrationScope.OS64Bit)
+ {
+ entry.UpdateRegistrationInfo64();
+ }
+ else
+ {
+ entry.UpdateRegistrationInfo32();
+ }
+
+ AddOrUpdateEntry(entry);
+
+ CheckIfRegisterOrUnregisterRequiresExplorerRestart(SelectedEntry?.SharpShellServerInfo);
+
+ return true;
}
- private void installToolStripMenuItem_Click(object sender, EventArgs e)
+ private bool UnregisterServer(ShellExtensionEntry entry, RegistrationScope registrationScope)
{
- // Bail if we have no server selected.
- if (SelectedServerEntry == null)
- return;
+ if (entry == null)
+ {
+ return false;
+ }
- // Create a regasm instance and register the server.
- var regasm = new RegAsm();
- var success = Environment.Is64BitOperatingSystem ? regasm.Register64(SelectedServerEntry.ServerPath, true) : regasm.Register32(SelectedServerEntry.ServerPath, true);
-
- // Inform the user of the result.
- if (success)
+ if (entry.SharpShellServerInfo == null)
{
- MessageBox.Show(@"Installed server successfully.", @"Install Server", MessageBoxButtons.OK,
- MessageBoxIcon.Information);
+ ServerRegistrationManager.UnregisterAndUnApproveServer(entry.ServerClassId, registrationScope);
}
else
{
- MessageBox.Show(@"Failed to install, check the SharpShell log for details.", @"Install Server", MessageBoxButtons.OK,
- MessageBoxIcon.Error);
+ ServerRegistrationManager.UnregisterAndUnApproveServer(entry.SharpShellServerInfo, registrationScope);
+ }
+
+ if (registrationScope == RegistrationScope.OS64Bit)
+ {
+ entry.UpdateRegistrationInfo64();
}
+ else
+ {
+ entry.UpdateRegistrationInfo32();
+ }
+
+ AddOrUpdateEntry(entry);
+
+ CheckIfRegisterOrUnregisterRequiresExplorerRestart(SelectedEntry?.SharpShellServerInfo);
+
+ return true;
}
- private void uninstallToolStripMenuItem_Click(object sender, EventArgs e)
+ public void PrepareServerList()
{
- // Bail if we have no server selected.
- if (SelectedServerEntry == null)
+ // Add the recently used servers. If any of them fail to load, we'll remove them from the list.
+ var recentlyUsedFilesToRemove = new List();
+
+ if (Settings.Default.RecentlyUsedFiles != null)
+ {
+ foreach (var path in Settings.Default.RecentlyUsedFiles)
+ {
+ if (!AddServersFromFile(path))
+ {
+ recentlyUsedFilesToRemove.Add(path);
+ }
+ }
+ }
+
+ foreach (var fileToRemove in recentlyUsedFilesToRemove)
+ {
+ Settings.Default.RecentlyUsedFiles?.Remove(fileToRemove);
+ }
+
+ Settings.Default.Save();
+
+ // Check for any servers added via the command line.
+ var arguments = Environment.GetCommandLineArgs();
+
+ for (var i = 1; i < arguments.Length; i++)
+ {
+ var arg = arguments[i];
+
+ if (File.Exists(arg))
+ {
+ AddServersFromFile(arg);
+ }
+ }
+
+ var _ = StartBlockingAction(() =>
+ {
+ foreach (var shellExtensionEntry in ShellExtensionEntry.GetRegisteredEntries())
+ {
+ Invoke(new Action(() =>
+ {
+ AddOrUpdateEntry(shellExtensionEntry);
+ }));
+ }
+ });
+ }
+
+ private async Task StartBlockingAction(Action action)
+ {
+ splitContainer.Enabled = false;
+ toolStrip.Enabled = false;
+ menuStrip.Enabled = false;
+ statusStrip.Enabled = false;
+ panelPleaseWait.Visible = true;
+
+ try
+ {
+ await Task.Factory.StartNew(action).ConfigureAwait(true);
+ }
+ finally
+ {
+ panelPleaseWait.Visible = false;
+
+ splitContainer.Enabled = true;
+ toolStrip.Enabled = true;
+ menuStrip.Enabled = true;
+ statusStrip.Enabled = true;
+ }
+ }
+
+ public bool AddServersFromFile(string path)
+ {
+ if (Entries.Any(se => se.ServerPath == path))
+ {
+ return true;
+ }
+
+ try
+ {
+ // Load any servers from the assembly.
+ var servers = SharpShellServerInfo.FromExternalAssemblyFile(path);
+
+ foreach (var server in servers)
+ {
+ AddOrUpdateEntry(new ShellExtensionEntry(server));
+ }
+ }
+ catch
+ {
+ MessageBox.Show($@"The file \'{Path.GetFileName(path)}\' is not a SharpShell Server.", @"Warning");
+
+ return false;
+ }
+
+ // We've successfully added the server - so add the path of the server to our recent files.
+ AddRecentlyUsed(path);
+
+ return true;
+ }
+
+ public void AddOrUpdateEntry(ShellExtensionEntry extensionEntry)
+ {
+ if (extensionEntry == null)
+ {
+ serverDetailsView.ExtensionEntry = null;
+
return;
+ }
- // Create a regasm instance and register the server.
- var regasm = new RegAsm();
- var success = Environment.Is64BitOperatingSystem ? regasm.Unregister64(SelectedServerEntry.ServerPath) : regasm.Unregister32(SelectedServerEntry.ServerPath);
+ if (extensionEntry.InstallationInfo32 == null &&
+ extensionEntry.InstallationInfo64 == null &&
+ extensionEntry.RegistrationInfo32 == null &&
+ extensionEntry.RegistrationInfo64 == null &&
+ extensionEntry.SharpShellServerInfo == null)
+ {
+ RemoveExtensionEntryFromList(extensionEntry);
+ serverDetailsView.ExtensionEntry = null;
- // Inform the user of the result.
- if (success)
+ return;
+ }
+
+ var listViewItem = listViewServers.Items
+ .Cast()
+ .FirstOrDefault(item =>
+ item.ExtensionEntry?.ServerClassId == extensionEntry.ServerClassId
+ );
+
+
+ if (listViewItem == null)
{
- MessageBox.Show(@"Uninstalled server successfully.", @"Uninstall Server", MessageBoxButtons.OK,
- MessageBoxIcon.Information);
+ listViewItem = new ServerListViewItem(extensionEntry);
+ listViewServers.Items.Add(listViewItem);
}
else
{
- MessageBox.Show(@"Failed to uninstall, check the SharpShell log for details.", @"Uninstall Server", MessageBoxButtons.OK,
- MessageBoxIcon.Error);
+ listViewItem.ExtensionEntry = extensionEntry;
+ listViewServers.Refresh();
}
+
+ if (!listViewServers.SelectedItems.Contains(listViewItem))
+ {
+ if (listViewServers.SelectedIndices.Count > 0)
+ {
+ listViewServers.SelectedIndices.Clear();
+ }
+
+ var itemIndex = listViewServers.Items.IndexOf(listViewItem);
+
+ if (itemIndex >= 0)
+ {
+ listViewServers.SelectedIndices.Add(itemIndex);
+ }
+ }
+
+ // Update the details view with the selected server entry.
+ serverDetailsView.ExtensionEntry = extensionEntry;
}
+
+ public void RemoveExtensionEntryFromList(ShellExtensionEntry extensionEntry)
+ {
+ var listViewItem = listViewServers.Items
+ .Cast()
+ .FirstOrDefault(item =>
+ item.ExtensionEntry?.ServerClassId == extensionEntry.ServerClassId
+ );
+
+ if (listViewItem != null)
+ {
+ if (listViewServers.SelectedItems.OfType().Contains(listViewItem))
+ {
+ listViewServers.SelectedIndices.Clear();
+ }
+
+ if (serverDetailsView.ExtensionEntry == extensionEntry)
+ {
+ serverDetailsView.ExtensionEntry = null;
+ }
+
+ listViewServers.Items.Remove(listViewItem);
+ }
+ }
+
+ #endregion
}
-}
+}
\ No newline at end of file
diff --git a/SharpShell/Tools/ServerManager/ServerManagerForm.resx b/SharpShell/Tools/ServerManager/ServerManagerForm.resx
index 35c12f4e..98298a40 100644
--- a/SharpShell/Tools/ServerManager/ServerManagerForm.resx
+++ b/SharpShell/Tools/ServerManager/ServerManagerForm.resx
@@ -117,7 +117,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
443, 17
@@ -127,119 +127,121 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
- ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACs
- FwAAAk1TRnQBSQFMAgEBBQEAAaABAQGgAQEBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
- AwABIAMAAQEBAAEgBgABIDIAAw4BEwNIAYUDXQHTA2IB9gNdAdMDSAGGAw8BFMgAAZsBVAE5Af8BgAEw
- AREB/wFoAS8BDwH/AWgBLQENAf8BZwErAQsB/wFmASkBCAH/AWQBKQEKAf8BgQFYAU8B/wHBAaYBnwH/
- AcQBXQFHAf8BoQFDASwB/wGuAVYBQgH/AcMBpQGfAf8BgAFVAUsB/wMPARTEAAGeAVgBPQH/AYsB0AGY
- Af8BiQHRAZgB/wFfAcUBiAH/AUgBtwFdAf8BMgGpAUwB/wFEAYwBUQH/AcEBqQGhAf8BsgExAQ4B/wHL
- AYsBXgH/AfgC9wH/AbABSwE2Af8BvwEtAQ8B/wHCAaUBnwH/A0gBhsQAAaIBXgFEAf8BugHmAcIB/wGn
- AeABsgH/AZIB1wGfAf8BZgHJAY4B/wFOAboBYwH/AYYBlAGHAf8ByAFlAUgB/wGwAS8BCQH/AcsBiwFf
- Af8B5wHoAekB/wGwAVIBPgH/AbcBKAEGAf8BvQFTAToB/wNdAdPEAAGnAWQBSwH/AaQB3gGvAf8B0QHv
- AdYB/wGnAeABsgH/AY0B1AGbAf8BYAHFAYkB/wKVAZIB/wHNAVYBMQH/AckBSwEkAf8BzwGRAWQB/wHo
- AekB6gH/AbIBWQFDAf8BsAEpAQQB/wGuATIBEAH/A2IB9sQAAawBgwFTAf8BmwGkAYUB/wGnAeABsgH/
- AdEB7wHWAf8BpwHgAbIB/wGJAdEBmAH/AYwBlwGNAf8B1gGPAVsB/wHWAVoBMQH/AdoBkQFfAf8B8wHM
- Ab0B/wG8AU0BLQH/AbQBNQEPAf8BvAFbAT8B/wNdAdPEAAGyAYsBXAH/Ae0B4wHdAf8BmwGeAYIB/wGl
- Ad8BsAH/AdAB7gHWAf8BpQHeAbAB/wFoAaIBhgH/AckBsgGqAf8B5AGAAUAB/wHvAY0BTwH/AfoB7wHo
- Af8B5QGAAUIB/wHNAVYBLgH/AcQBrAGjAf8DSAGFxAABuAGSAWUC/wH8AfsB/wHtAeMB3QH/AZsBggFa
- Af8BpgHeAbAB/wGxAeIBugH/AVEBSAE1Af8BlgGMAYcB/wHJAbIBqwH/AegBngFnAf8B8gGjAYMB/wHj
- AZABVwH/AcYBrgGmAf8BgQFYAU8B/wMOARPEAAG9AZoBhAL/AfwB+wL/AfwB+wH/AekB3gHYAf8BmwGC
- AVoB/wGbAYIBWgH/Ae4B1gHJAf8B8gHWAcgB/wG7AagBnwH/AaQBmgGWAf8BmgGVAZQB/wGkAZgBkwH/
- AZ8BjgGGAf8BZAEpAQoB/8gAAcIBoAGLAv8B/AH7Av8B/AH7Av8B/AH7Av8B+AH1Af8B/gHzAe0B/wH+
- Ae0B5AH/AdQBxQHSAf8BCQE8AcsB/wEIAToBxgH/AdEBsQGvAf8B/AHKAbAB/wHKAacBlQH/AWYBKQEI
- Af/IAAHGAaYBkgL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/AfgB9QH/Af4B8wHtAf8BGQFHAdQB/wFb
- Ab4B+QH/AS0BjAHLAf8BCAE6AcYB/wH8AdABuQH/AdIBrQGaAf8BZwErAQsB/8gAAckBqgGWAv8B/AH7
- Av8B/AH7Av8B/AH7Av8B/AH7Av8B/AH7Av8B+AH1Af8BGgFJAdcB/wG5AeQC/wFbAb4B+QH/AQkBPAHL
- Af8B/QHXAcMB/wHZAbMBnwH/AWgBLQENAf/IAAHJAaoBlgL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/
- AfwB+wL/AfwB+wH/AdcB1AHsAf8BGgFJAdcB/wEZAUgB1AH/AdQBxQHSAf8B/QHfAc8B/wHeAbcBowH/
- AWgBLwEPAf/IAAHJAaoBlgL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/
- AfgB9QH/Af4B8wHtAf8B/gHtAeQB/wH9AeYB2gH/Af0B3wHPAf8BgAEwAREB/8gAAckBqgGWAf8ByQGq
- AZYB/wHJAaoBlgH/AckBqgGWAf8BxgGmAZIB/wHCAaABiwH/Ab0BmgGEAf8BuAGSAWUB/wGyAYsBXAH/
- AawBgwFTAf8BpwFkAUsB/wGiAV4BRAH/AZ4BWAE9Af8BmwFUATkB//8A/wCOAAG6AaEBkgH/Aa0BlwGI
- Af8BpgGQAYAB/wGfAYgBVgH/AZkBggFPAf8BkwFaAUgB/wGMAVIBQQH/AYYBSwE5Af8BXQFEATEB/wFW
- AT0BKgH/AVABNgEiAf8BSgEwARsB/wFFASoBFgH/AUIBJwERAf9EAAGbATcBHAH/AYABEwEAAf8BSwES
- AQAB/wFLARABAAH/AUoBDgEAAf8BSQEMAQAB/wFIAQkBAAH/AUcBBwEAAf8BRgEEAQAB/wFFAQEBAAH/
- AUQCAAH/AUMCAAH/AUMCAAH/AUICAAH/TAABvQGmAZgB/wEAA/8BAAP/AQAD/wEAA/8BAAP/AQAD/wEA
- A/8BAAP/AQAD/wEAA/8BAAP/AQAD/wFIAS4BGQH/BAADYgHvAZkBqAGsAf8BmQGoAawB/wGZAagBrAH/
- AZkBqAGsAf8BmQGoAawB/wGZAagBrAH/AZkBqAGsAf8BmQGoAawB/wGZAagBrAH/AZkBqAGsAf8BmQGo
- AawB/wNcAc8MAAGeATsBIAH/AYsB0AGYAf8BiQHRAZgB/wFCAcUBiAH/ASsBtwFAAf8BFQGpAS8B/wEA
- AZwBHQH/AQABjwENAf8BAAGIAQMB/wEAAYgBAwH/AQABiAEDAf8BAAFFAQIB/wEZAQYBAAH/AUMCAAH/
- CAADKgFAAZwBmwGRAf8BnAGbAZEB/wGcAZsBkQH/AZwBmwGRAf8BnAGbAZEB/wGcAZsBkQH/AZwBmwGR
- Af8BnAGbAZEB/wGcAZsBkQH/AZwBmwGRAf8BnAGbAZEB/wGcAZsBkQH/A0cBgAwAAcIBqgGdAf8BAAP/
- Af0BkgE8Af8B7QGHATIB/wHZAVgBKwH/AccBTQEiAf8BswFAARgB/wGmATYBEQH/AQAD/wH9AZIBPAH/
- Ae0BhwEyAf8B2QFYASsB/wEAA/8BUQE4ASMB/wQAA2IB7wHyAfQB9Qn/A90B/wPOAf8DzgH/A+cN/wHm
- AekB6gH/A1wBzwwAAaIBQQEnAf8BugHmAcIB/wGnAeABsgH/AZIB1wGfAf8BSQHJAY4B/wExAboBRgH/
- ARoBrAEyAf8BAQGcAR0B/wEAAY4BDAH/AQABiAEDAf8BDwElAQEB/wE6ASUBFgH/AS8BGgELAf8BQwIA
- Af8IAAMqAUABzQHMAccB/wH+AvwB/wH+AvwB/wH+AvwB/wH+AvwB/wH+AvwB/wH+AvwB/wH+AvwB/wH+
- AvwB/wH+AvwB/wH+AvwB/wHmAeQB4QH/A0cBgAwAAcUBrgGjAf8BAAP/AQAD/wMAAf8DAAH/AwAB/wEA
- A/8BAAP/AQAD/wEAA/8BAAP/AQAD/wEAA/8BXAFDAS8B/wQAA2IB7wHyAfQB9QX/AdoB0QHJAf8BoQGN
- AUkB/wEBAgAB/wEeARkBFAH/AYUBPwExAf8BPgEkARAB/wGjAZIBhQX/AeYB6QHqAf8DXAHPDAABpwFH
- AS4B/wGkAd4BrwH/AdEB7wHWAf8BpwHgAbIB/wGNAdQBmwH/AUMBxQGJAf8BKwG2AUEB/wEUAagBLQH/
- AQABlQEWAf8BGwEVAQAB/wGSAUgBOwH/AY0BRAE2Af8DAAH/AUQCAAH/CAADKgFAAc0BzAHHAf8B8wL2
- Af8B7wHzAfQB/wHvAfQB9QH/Ae8B9AH1Af8B7wHzAfUB/wHwAvQB/wHwAfQB9QH/Ae8B9AH1Af8B7wL0
- Af8B7wHzAfUB/wHmAeQB4QH/A0cBgAwAAckBtAGoAf8BxAGtAaEB/wHAAagBmwH/AwAF/wMAAf8BrQGV
- AYQB/wGpAZABXQH/AaQBiwFXAf8BnwGEAVEB/wGaAV0BSwH/AZYBWQFHAf8BlQFYAUUB/wGVAVgBRQH/
- BAADYgLvAvAF/wGqAZgBiQH/AdsB1AHOAf8DLAH/A0AB/wPnDf8B5gHpAeoB/wNcAc8MAAGsAYMBNgH/
- AZsBpAGFAf8BpwHgAbIB/wHRAe8B1gH/AacB4AGyAf8BiQHRAZgB/wE9AcEBhAH/ASEBsAE4Af8BLQE6
- AR4B/wG/AasBoQH/AbMBnQGQAf8DAAH/Aa4BkQGDAf8BRQEBAQAB/wgAAyoBQAHNAcwBxwH/AfQB9wH4
- Af8B8QH0AfUB/wHxAvUB/wHxAvUB/wHxAfQB9QH/AfEB9QH2Af8B8QL1Af8B8QH1AfYB/wHxAfQB9QH/
- AfEB9QH2Af8B5gHkAeEB/wNHAYAXAAX/AwAB/ygAA2IB7wHGAcMBwQH/A84B/wGdAYsBSQH/AdsB1AHO
- Af8DLAH/AR4BGQEUAf8BhQE/ATEB/wE+ASQBEAH/AaMBkgGFBf8B5gHpAeoB/wNcAc8MAAGyAYsBPwH/
- Ae0B4wHdAf8BmwGeAYIB/wGlAd8BsAH/AdAB7gHWAf8BpQHeAbAB/wFLAcsBjwH/ATQBRAEmAf8BzwG8
- AbIB/wHTAcEBtwH/AwAB/wHsAbYBmQH/AbQBlgGHAf8BRgEEAQAB/wgAAyoBQAHNAcwBxwH/AfYB9wH4
- Af8B8wH2AfcB/wHzAfYB9wH/AfMB9gH3Af8B8wH2AfcB/wHzAfUB9gH/AfMB9gH3Af8B9AH2AfcB/wHz
- AvYB/wHzAfYB9wH/AeYB5AHhAf8DRwGACwAB/wsABf8DAAH/KAADYgHvAwAB/wMAAf8DvwH/AxwB/wOB
- Af8DzgH/A+cN/wHmAekB6gH/A1wBzwwAAbgBkgFIAv8B/AH7Af8B7QHjAd0B/wGbAYIBPQH/AaYB3gGw
- Af8BsQHiAboB/wE0ASoBFgH/Ac4BrgGbAf8BMQEbAQsB/wExARsBCwH/AdgBsAGZAf8B+wHBAaIB/wG7
- AZsBjAH/AUcBBwEAAf8IAAMqAUABzQHMAccB/wH3AfgB+QH/AfYC9wH/AfUC9wH/AfUB9wH4Af8B9gH3
- AfgB/wH1AvcB/wH1AfYB+AH/AfUB9wH4Af8B9QH3AfgB/wH1AvcB/wHmAeQB4QH/A0cBgAsAAf8DAAH/
- AwAF/wMAAf8sAANiAe8B8QHuAesJ/wMcAf8DAAH/AwAB/wEkAR0BFwH/AZEBSgE6Af8BowGSAYUF/wHm
- AekB6gH/A1wBzwwAAb0BmgGEAv8B/AH7Av8B/AH7Af8B6QHeAdgB/wGbAYIBPQH/AZsBggE9Af8B7gHW
- AckB/wH9Ad8BzwH/Af0B1wHDAf8B/AHQAbkB/wH8AcoBsAH/AfsBxQGoAf8BwgGhAZAB/wFIAQkBAAH/
- CAADKgFAAc0BzAHHAf8C+QH6Af8B9wH4AfkB/wH2AfgB+QH/AfcB+AH5Af8B9wH4AfkB/wH3AvgB/wH3
- AfgB+QH/AfcB+AH5Af8B9wH4AfkB/wH3AfgB+QH/AeYB5AHhAf8DRwGACwAN/wMAAf8DAAH/AwAB/yQA
- A2IB7wHxAe4B6w3/AywB/wOPEf8B5gHpAeoB/wNcAc8MAAHCAaABiwL/AfwB+wL/AfwB+wL/AfwB+wL/
- AfgB9QH/Af4B8wHtAf8B/gHtAeQB/wHUAcUB0gH/AQABHwHLAf8BAAEdAcYB/wHRAbEBrwH/AfwBygGw
- Af8BygGnAZUB/wFJAQwBAAH/CAADKgFAAc0BzAHHAf8B+gH7AfoB/wH5AfoB+QH/A/kB/wH5AvoB/wL5
- AfoB/wL5AfoB/wH4AvkB/wH5AvoB/wP5Af8B+AH5AfoB/wHmAeQB4QH/A0cBgAsAEf8DAAH/KAADYgHv
- AfEB7gHrCf8DHAH/AUMBOwE0Af8BnQGKAUcB/wFJATEBHQH/AT4BIwEPAf8BowGSAYUF/wHmAekB6gH/
- A1wBzwwAAcYBpgGSAv8B/AH7Av8B/AH7Av8B/AH7Av8B/AH7Av8B+AH1Af8B/gHzAe0B/wEAASoB1AH/
- AT4BvgH5Af8BEAGMAcsB/wEAAR0BxgH/AfwB0AG5Af8B0gGtAZoB/wFKAQ4BAAH/CAADKgFAAc0BzAHH
- Af8B/AL7Af8B+wH6AfsB/wP7Af8B/QH7AfwB/wH+AvwB/wH+AvwB/wH+AvwB/wH+AvwB/wH+AvwB/wH+
- AvwB/wHmAeQB4QH/A0cBgAsADf8DAAH/LAADYgHvAfEB7gHrBf8DDAH/A68Z/wHmAekB6gH/A1wBzwwA
- AckBqgGWAv8B/AH7Av8B/AH7Av8B/AH7Av8B/AH7Av8B/AH7Av8B+AH1Af8BAAEsAdcB/wG5AeQC/wE+
- Ab4B+QH/AQABHwHLAf8B/QHXAcMB/wHZAbMBnwH/AUsBEAEAAf8IAAMqAUABzQHMAccB/wH9AfwB+wH/
- AvwB+wH/Af0C/AH/Af4C/AH/AbUBswGsAf8BnAGbAZEB/wGcAZsBkQH/AZwBmwGRAf8BnAGbAZEB/wGc
- AZsBkQH/A1kBvw8ACf8DAAH/MAADYgHvAfEB7gHrAf8DAAH/AZsBkQGKAf8BrQGZAYsB/wGWAUsBOQH/
- AYoBPgEsAf8BSQEwAR4B/wE9ASMBEAH/AaMBkgGFBf8B5gHpAeoB/wNcAc8MAAHJAaoBlgL/AfwB+wL/
- AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wH/AdcB1AHsAf8BAAEsAdcB/wEAASsB1AH/AdQBxQHS
- Af8B/QHfAc8B/wHeAbcBowH/AUsBEgEAAf8IAAMqAUABpgHAAcUB/wGvAeQB+QH/Aa8B5AH5Af8BrwHk
- AfkB/wGvAeQB+QH/AaEBrQGrAf8B9gH3AfgB/wH2AfcB+AH/AfYC+AH/AfYB9wH4Af8B9gH3AfgB/wNZ
- Ab8PAAX/AwAB/zQAA2IB7wMAAf8DzyH/AeYB6QHqAf8DXAHPDAAByQGqAZYC/wH8AfsC/wH8AfsC/wH8
- AfsC/wH8AfsC/wH8AfsC/wH8AfsC/wH8AfsC/wH4AfUB/wH+AfMB7QH/Af4B7QHkAf8B/QHmAdoB/wH9
- Ad8BzwH/AYABEwEAAf8IAAMqAUABggG3AccB/wEzAdIB/AH/ATMB0gH8Af8BMwHSAfwB/wEzAdIB/AH/
- AY8BqQGsAf8BtAGnAZEB/wG0AacBkQH/AbQBpwGRAf8BtAGnAZEB/wG0AacBkQH/EwAB/wMAAf84AANi
- Ae8BmAGiAaMB/wGZAagBrAH/AZkBqAGsAf8BmQGoAawB/wGZAagBrAH/AZkBqAGsAf8BmQGoAawB/wGZ
- AagBrAH/AZkBqAGsAf8BmQGoAawB/wGZAagBrAH/A1wBzwwAAckBqgGWAf8ByQGqAZYB/wHJAaoBlgH/
- AckBqgGWAf8BxgGmAZIB/wHCAaABiwH/Ab0BmgGEAf8BuAGSAUgB/wGyAYsBPwH/AawBgwE2Af8BpwFH
- AS4B/wGiAUEBJwH/AZ4BOwEgAf8BmwE3ARwB/wwAA0cBgAGcAZsBkQH/AZwBmwGRAf8BnAGbAZEB/wGc
- AZsBkQH/AyoBQCcAAf//ADkAAUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYAA/8BAAH/
- AQEGAAGABwABgAcAAYAHAAGABwABgAcAAYAHAAGABwABgAEBBgABgAEBBgABgAEBBgABgAEBBgABgAEB
- BgABgAEBBgABgAEBBgAC/wYABv8BwAEAAv8BgAEBAv8BwAEAAYABAwGAAQEBgAEBAcABAAGAAQMBgAEB
- AYABAQHAAQABgAEDAYABAQGAAQEBwAEAAYABAwGAAQEBgAEBAfEB/wGAAQMBgAEBAYABAQGxAf8BgAED
- AYABAQGAAQEBgwH/AYABAwGAAQEBgAEBAYAB/wGAAQMBgAEBAYABAQGBAf8BgAEDAYABAQGAAQEBgwH/
- AYABAwGAAQEBgAEDAYcB/wGAAQMBgAEBAYABAwGPAf8BgAEDAYABAQGAAQcBnwH/AYABAwGAAQEBwAH/
- Ab8J/ws=
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACY
+ FwAAAk1TRnQBSQFMAgEBBQEAAegBAQHoAQEBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+ AwABIAMAAQEBAAEgBgABIDIAAw4BEwNIAYUDXQHTA2IB9gNdAdMDSAGGAw8BFMgAAZsBSwEwAf8BgAEn
+ AQgB/wFfASYBBgH/AV8BJAEEAf8BXgEiAQIB/wFdASABAAH/AVsBIAEBAf8BgQFPAUYB/wHBAaYBnwH/
+ AcQBVAE+Af8BoQE6ASMB/wGuAU0BOQH/AcMBpQGfAf8BgAFMAUIB/wMPARTEAAGeAU8BNAH/AYsB0AGY
+ Af8BiQHRAZgB/wFWAcUBiAH/AT8BtwFUAf8BKQGpAUMB/wE7AYwBSAH/AcEBqQGhAf8BsgEoAQUB/wHL
+ AYsBVQH/AfgC9wH/AbABQgEtAf8BvwEkAQYB/wHCAaUBnwH/A0gBhsQAAaIBVQE7Af8BugHmAcIB/wGn
+ AeABsgH/AZIB1wGfAf8BXQHJAY4B/wFFAboBWgH/AYYBlAGHAf8ByAFcAT8B/wGwASYBAAH/AcsBiwFW
+ Af8B5wHoAekB/wGwAUkBNQH/AbcBHwEAAf8BvQFKATEB/wNdAdPEAAGnAVsBQgH/AaQB3gGvAf8B0QHv
+ AdYB/wGnAeABsgH/AY0B1AGbAf8BVwHFAYkB/wKVAZIB/wHNAU0BKAH/AckBQgEbAf8BzwGRAVsB/wHo
+ AekB6gH/AbIBUAE6Af8BsAEgAQAB/wGuASkBBwH/A2IB9sQAAawBgwFKAf8BmwGkAYUB/wGnAeABsgH/
+ AdEB7wHWAf8BpwHgAbIB/wGJAdEBmAH/AYwBlwGNAf8B1gGPAVIB/wHWAVEBKAH/AdoBkQFWAf8B8wHM
+ Ab0B/wG8AUQBJAH/AbQBLAEGAf8BvAFSATYB/wNdAdPEAAGyAYsBUwH/Ae0B4wHdAf8BmwGeAYIB/wGl
+ Ad8BsAH/AdAB7gHWAf8BpQHeAbAB/wFfAaIBhgH/AckBsgGqAf8B5AGAATcB/wHvAY0BRgH/AfoB7wHo
+ Af8B5QGAATkB/wHNAU0BJQH/AcQBrAGjAf8DSAGFxAABuAGSAVwC/wH8AfsB/wHtAeMB3QH/AZsBggFR
+ Af8BpgHeAbAB/wGxAeIBugH/AUgBPwEsAf8BlgGMAYcB/wHJAbIBqwH/AegBngFeAf8B8gGjAYMB/wHj
+ AZABTgH/AcYBrgGmAf8BgQFPAUYB/wMOARPEAAG9AZoBhAL/AfwB+wL/AfwB+wH/AekB3gHYAf8BmwGC
+ AVEB/wGbAYIBUQH/Ae4B1gHJAf8B8gHWAcgB/wG7AagBnwH/AaQBmgGWAf8BmgGVAZQB/wGkAZgBkwH/
+ AZ8BjgGGAf8BWwEgAQEB/8gAAcIBoAGLAv8B/AH7Av8B/AH7Av8B/AH7Av8B+AH1Af8B/gHzAe0B/wH+
+ Ae0B5AH/AdQBxQHSAf8BAAEzAcsB/wEAATEBxgH/AdEBsQGvAf8B/AHKAbAB/wHKAacBlQH/AV0BIAEA
+ Af/IAAHGAaYBkgL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/AfgB9QH/Af4B8wHtAf8BEAE+AdQB/wFS
+ Ab4B+QH/ASQBjAHLAf8BAAExAcYB/wH8AdABuQH/AdIBrQGaAf8BXgEiAQIB/8gAAckBqgGWAv8B/AH7
+ Av8B/AH7Av8B/AH7Av8B/AH7Av8B/AH7Av8B+AH1Af8BEQFAAdcB/wG5AeQC/wFSAb4B+QH/AQABMwHL
+ Af8B/QHXAcMB/wHZAbMBnwH/AV8BJAEEAf/IAAHJAaoBlgL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/
+ AfwB+wL/AfwB+wH/AdcB1AHsAf8BEQFAAdcB/wEQAT8B1AH/AdQBxQHSAf8B/QHfAc8B/wHeAbcBowH/
+ AV8BJgEGAf/IAAHJAaoBlgL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/AfwB+wL/
+ AfgB9QH/Af4B8wHtAf8B/gHtAeQB/wH9AeYB2gH/Af0B3wHPAf8BgAEnAQgB/8gAAckBqgGWAf8ByQGq
+ AZYB/wHJAaoBlgH/AckBqgGWAf8BxgGmAZIB/wHCAaABiwH/Ab0BmgGEAf8BuAGSAVwB/wGyAYsBUwH/
+ AawBgwFKAf8BpwFbAUIB/wGiAVUBOwH/AZ4BTwE0Af8BmwFLATAB//8A/wCOAAG6AaEBkgH/Aa0BlwGI
+ Af8BpgGQAYAB/wGfAYgBTQH/AZkBggFGAf8BkwFRAT8B/wGMAUkBOAH/AYYBQgEwAf8BVAE7ASgB/wFN
+ ATQBIQH/AUcBLQEZAf8BQQEnARIB/wE8ASEBDQH/ATkBHgEIAf9EAAGbAS4BEwH/AYABCgEAAf8BQgEJ
+ AQAB/wFCAQcBAAH/AUEBBQEAAf8BQAEDAQAB/wE/AgAB/wE+AgAB/wE9AgAB/wE8AgAB/wE7AgAB/wE6
+ AgAB/wE6AgAB/wE5AgAB/0wAAb0BpgGYAf8BAAP/AQAD/wEAA/8BAAP/AQAD/wEAA/8BAAP/AQAD/wEA
+ A/8BAAP/AQAD/wEAA/8BPwElARAB/wQAA2IB7wGZAagBrAH/AZkBqAGsAf8BmQGoAawB/wGZAagBrAH/
+ AZkBqAGsAf8BmQGoAawB/wGZAagBrAH/AZkBqAGsAf8BmQGoAawB/wGZAagBrAH/AZkBqAGsAf8DXAHP
+ DAABngEyARcB/wGLAdABmAH/AYkB0QGYAf8BOQHFAYgB/wEiAbcBNwH/AQwBqQEmAf8BAAGcARQB/wEA
+ AY8BBAH/AQABiAEAAf8BAAGIAQAB/wEAAYgBAAH/AQABPAEAAf8BEAIAAf8BOgIAAf8IAAMqAUABnAGb
+ AZEB/wGcAZsBkQH/AZwBmwGRAf8BnAGbAZEB/wGcAZsBkQH/AZwBmwGRAf8BnAGbAZEB/wGcAZsBkQH/
+ AZwBmwGRAf8BnAGbAZEB/wGcAZsBkQH/AZwBmwGRAf8DRwGADAABwgGqAZ0B/wEAA/8B/QGSATMB/wHt
+ AYcBKQH/AdkBTwEiAf8BxwFEARkB/wGzATcBDwH/AaYBLQEIAf8BAAP/Af0BkgEzAf8B7QGHASkB/wHZ
+ AU8BIgH/AQAD/wFIAS8BGgH/BAADYgHvAfIB9AH1Cf8D3QH/A84B/wPOAf8D5w3/AeYB6QHqAf8DXAHP
+ DAABogE4AR4B/wG6AeYBwgH/AacB4AGyAf8BkgHXAZ8B/wFAAckBjgH/ASgBugE9Af8BEQGsASkB/wEA
+ AZwBFAH/AQABjgEDAf8BAAGIAQAB/wEGARwBAAH/ATEBHAENAf8BJgERAQIB/wE6AgAB/wgAAyoBQAHN
+ AcwBxwH/Af4C/AH/Af4C/AH/Af4C/AH/Af4C/AH/Af4C/AH/Af4C/AH/Af4C/AH/Af4C/AH/Af4C/AH/
+ Af4C/AH/AeYB5AHhAf8DRwGADAABxQGuAaMB/wEAA/8BAAP/AwAB/wMAAf8DAAH/AQAD/wEAA/8BAAP/
+ AQAD/wEAA/8BAAP/AQAD/wFTAToBJgH/BAADYgHvAfIB9AH1Bf8B2gHRAckB/wGhAY0BQAH/AwAB/wEV
+ ARABCwH/AYUBNgEoAf8BNQEbAQcB/wGjAZIBhQX/AeYB6QHqAf8DXAHPDAABpwE+ASUB/wGkAd4BrwH/
+ AdEB7wHWAf8BpwHgAbIB/wGNAdQBmwH/AToBxQGJAf8BIgG2ATgB/wELAagBJAH/AQABlQENAf8BEgEM
+ AQAB/wGSAT8BMgH/AY0BOwEtAf8DAAH/ATsCAAH/CAADKgFAAc0BzAHHAf8B8wL2Af8B7wHzAfQB/wHv
+ AfQB9QH/Ae8B9AH1Af8B7wHzAfUB/wHwAvQB/wHwAfQB9QH/Ae8B9AH1Af8B7wL0Af8B7wHzAfUB/wHm
+ AeQB4QH/A0cBgAwAAckBtAGoAf8BxAGtAaEB/wHAAagBmwH/AwAF/wMAAf8BrQGVAYQB/wGpAZABVAH/
+ AaQBiwFOAf8BnwGEAUgB/wGaAVQBQgH/AZYBUAE+Af8BlQFPATwB/wGVAU8BPAH/BAADYgLvAvAF/wGq
+ AZgBiQH/AdsB1AHOAf8DIwH/AzcB/wPnDf8B5gHpAeoB/wNcAc8MAAGsAYMBLQH/AZsBpAGFAf8BpwHg
+ AbIB/wHRAe8B1gH/AacB4AGyAf8BiQHRAZgB/wE0AcEBhAH/ARgBsAEvAf8BJAExARUB/wG/AasBoQH/
+ AbMBnQGQAf8DAAH/Aa4BkQGDAf8BPAIAAf8IAAMqAUABzQHMAccB/wH0AfcB+AH/AfEB9AH1Af8B8QL1
+ Af8B8QL1Af8B8QH0AfUB/wHxAfUB9gH/AfEC9QH/AfEB9QH2Af8B8QH0AfUB/wHxAfUB9gH/AeYB5AHh
+ Af8DRwGAFwAF/wMAAf8oAANiAe8BxgHDAcEB/wPOAf8BnQGLAUAB/wHbAdQBzgH/AyMB/wEVARABCwH/
+ AYUBNgEoAf8BNQEbAQcB/wGjAZIBhQX/AeYB6QHqAf8DXAHPDAABsgGLATYB/wHtAeMB3QH/AZsBngGC
+ Af8BpQHfAbAB/wHQAe4B1gH/AaUB3gGwAf8BQgHLAY8B/wErATsBHQH/Ac8BvAGyAf8B0wHBAbcB/wMA
+ Af8B7AG2AZkB/wG0AZYBhwH/AT0CAAH/CAADKgFAAc0BzAHHAf8B9gH3AfgB/wHzAfYB9wH/AfMB9gH3
+ Af8B8wH2AfcB/wHzAfYB9wH/AfMB9QH2Af8B8wH2AfcB/wH0AfYB9wH/AfMC9gH/AfMB9gH3Af8B5gHk
+ AeEB/wNHAYALAAH/CwAF/wMAAf8oAANiAe8DAAH/AwAB/wO/Af8DEwH/A4EB/wPOAf8D5w3/AeYB6QHq
+ Af8DXAHPDAABuAGSAT8C/wH8AfsB/wHtAeMB3QH/AZsBggE0Af8BpgHeAbAB/wGxAeIBugH/ASsBIQEN
+ Af8BzgGuAZsB/wEoARIBAgH/ASgBEgECAf8B2AGwAZkB/wH7AcEBogH/AbsBmwGMAf8BPgIAAf8IAAMq
+ AUABzQHMAccB/wH3AfgB+QH/AfYC9wH/AfUC9wH/AfUB9wH4Af8B9gH3AfgB/wH1AvcB/wH1AfYB+AH/
+ AfUB9wH4Af8B9QH3AfgB/wH1AvcB/wHmAeQB4QH/A0cBgAsAAf8DAAH/AwAF/wMAAf8sAANiAe8B8QHu
+ AesJ/wMTAf8DAAH/AwAB/wEbARQBDgH/AZEBQQExAf8BowGSAYUF/wHmAekB6gH/A1wBzwwAAb0BmgGE
+ Av8B/AH7Av8B/AH7Af8B6QHeAdgB/wGbAYIBNAH/AZsBggE0Af8B7gHWAckB/wH9Ad8BzwH/Af0B1wHD
+ Af8B/AHQAbkB/wH8AcoBsAH/AfsBxQGoAf8BwgGhAZAB/wE/AgAB/wgAAyoBQAHNAcwBxwH/AvkB+gH/
+ AfcB+AH5Af8B9gH4AfkB/wH3AfgB+QH/AfcB+AH5Af8B9wL4Af8B9wH4AfkB/wH3AfgB+QH/AfcB+AH5
+ Af8B9wH4AfkB/wHmAeQB4QH/A0cBgAsADf8DAAH/AwAB/wMAAf8kAANiAe8B8QHuAesN/wMjAf8DjxH/
+ AeYB6QHqAf8DXAHPDAABwgGgAYsC/wH8AfsC/wH8AfsC/wH8AfsC/wH4AfUB/wH+AfMB7QH/Af4B7QHk
+ Af8B1AHFAdIB/wEAARYBywH/AQABFAHGAf8B0QGxAa8B/wH8AcoBsAH/AcoBpwGVAf8BQAEDAQAB/wgA
+ AyoBQAHNAcwBxwH/AfoB+wH6Af8B+QH6AfkB/wP5Af8B+QL6Af8C+QH6Af8C+QH6Af8B+AL5Af8B+QL6
+ Af8D+QH/AfgB+QH6Af8B5gHkAeEB/wNHAYALABH/AwAB/ygAA2IB7wHxAe4B6wn/AxMB/wE6ATIBKwH/
+ AZ0BigE+Af8BQAEoARQB/wE1ARoBBgH/AaMBkgGFBf8B5gHpAeoB/wNcAc8MAAHGAaYBkgL/AfwB+wL/
+ AfwB+wL/AfwB+wL/AfwB+wL/AfgB9QH/Af4B8wHtAf8BAAEhAdQB/wE1Ab4B+QH/AQcBjAHLAf8BAAEU
+ AcYB/wH8AdABuQH/AdIBrQGaAf8BQQEFAQAB/wgAAyoBQAHNAcwBxwH/AfwC+wH/AfsB+gH7Af8D+wH/
+ Af0B+wH8Af8B/gL8Af8B/gL8Af8B/gL8Af8B/gL8Af8B/gL8Af8B/gL8Af8B5gHkAeEB/wNHAYALAA3/
+ AwAB/ywAA2IB7wHxAe4B6wX/AwMB/wOvGf8B5gHpAeoB/wNcAc8MAAHJAaoBlgL/AfwB+wL/AfwB+wL/
+ AfwB+wL/AfwB+wL/AfwB+wL/AfgB9QH/AQABIwHXAf8BuQHkAv8BNQG+AfkB/wEAARYBywH/Af0B1wHD
+ Af8B2QGzAZ8B/wFCAQcBAAH/CAADKgFAAc0BzAHHAf8B/QH8AfsB/wL8AfsB/wH9AvwB/wH+AvwB/wG1
+ AbMBrAH/AZwBmwGRAf8BnAGbAZEB/wGcAZsBkQH/AZwBmwGRAf8BnAGbAZEB/wNZAb8PAAn/AwAB/zAA
+ A2IB7wHxAe4B6wH/AwAB/wGbAZEBigH/Aa0BmQGLAf8BlgFCATAB/wGKATUBIwH/AUABJwEVAf8BNAEa
+ AQcB/wGjAZIBhQX/AeYB6QHqAf8DXAHPDAAByQGqAZYC/wH8AfsC/wH8AfsC/wH8AfsC/wH8AfsC/wH8
+ AfsC/wH8AfsB/wHXAdQB7AH/AQABIwHXAf8BAAEiAdQB/wHUAcUB0gH/Af0B3wHPAf8B3gG3AaMB/wFC
+ AQkBAAH/CAADKgFAAaYBwAHFAf8BrwHkAfkB/wGvAeQB+QH/Aa8B5AH5Af8BrwHkAfkB/wGhAa0BqwH/
+ AfYB9wH4Af8B9gH3AfgB/wH2AvgB/wH2AfcB+AH/AfYB9wH4Af8DWQG/DwAF/wMAAf80AANiAe8DAAH/
+ A88h/wHmAekB6gH/A1wBzwwAAckBqgGWAv8B/AH7Av8B/AH7Av8B/AH7Av8B/AH7Av8B/AH7Av8B/AH7
+ Av8B/AH7Av8B+AH1Af8B/gHzAe0B/wH+Ae0B5AH/Af0B5gHaAf8B/QHfAc8B/wGAAQoBAAH/CAADKgFA
+ AYIBtwHHAf8BKgHSAfwB/wEqAdIB/AH/ASoB0gH8Af8BKgHSAfwB/wGPAakBrAH/AbQBpwGRAf8BtAGn
+ AZEB/wG0AacBkQH/AbQBpwGRAf8BtAGnAZEB/xMAAf8DAAH/OAADYgHvAZgBogGjAf8BmQGoAawB/wGZ
+ AagBrAH/AZkBqAGsAf8BmQGoAawB/wGZAagBrAH/AZkBqAGsAf8BmQGoAawB/wGZAagBrAH/AZkBqAGs
+ Af8BmQGoAawB/wNcAc8MAAHJAaoBlgH/AckBqgGWAf8ByQGqAZYB/wHJAaoBlgH/AcYBpgGSAf8BwgGg
+ AYsB/wG9AZoBhAH/AbgBkgE/Af8BsgGLATYB/wGsAYMBLQH/AacBPgElAf8BogE4AR4B/wGeATIBFwH/
+ AZsBLgETAf8MAANHAYABnAGbAZEB/wGcAZsBkQH/AZwBmwGRAf8BnAGbAZEB/wMqAUAnAAH//wA5AAFC
+ AU0BPgcAAT4DAAEoAwABQAMAASADAAEBAQABAQYAAQEWAAP/AQAB/wEBBgABgAcAAYAHAAGABwABgAcA
+ AYAHAAGABwABgAcAAYABAQYAAYABAQYAAYABAQYAAYABAQYAAYABAQYAAYABAQYAAYABAQYAAv8GAAb/
+ AcABAAL/AYABAQL/AcABAAGAAQMBgAEBAYABAQHAAQABgAEDAYABAQGAAQEBwAEAAYABAwGAAQEBgAEB
+ AcABAAGAAQMBgAEBAYABAQHxAf8BgAEDAYABAQGAAQEBsQH/AYABAwGAAQEBgAEBAYMB/wGAAQMBgAEB
+ AYABAQGAAf8BgAEDAYABAQGAAQEBgQH/AYABAwGAAQEBgAEBAYMB/wGAAQMBgAEBAYABAwGHAf8BgAED
+ AYABAQGAAQMBjwH/AYABAwGAAQEBgAEHAZ8B/wGAAQMBgAEBAcAB/wG/Cf8L
-
+
+ 328, 17
+
+
669, 17
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAAAJcEhZcwAAHYcAAB2HAY/l8WUAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
@@ -251,9 +253,6 @@
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
-
- 328, 17
-
AAABAAgAICAQAAEABADoAgAAhgAAABAQEAABAAQAKAEAAG4DAAAwMAAAAQAIAKgOAACWBAAAICAAAAEA
diff --git a/SharpShell/Tools/ServerManager/ShellDebugger/ShellDebuggerForm.Designer.cs b/SharpShell/Tools/ServerManager/ShellDebugger/ShellDebuggerForm.Designer.cs
index b02b209b..dd2cec9f 100644
--- a/SharpShell/Tools/ServerManager/ShellDebugger/ShellDebuggerForm.Designer.cs
+++ b/SharpShell/Tools/ServerManager/ShellDebugger/ShellDebuggerForm.Designer.cs
@@ -29,9 +29,9 @@ protected override void Dispose(bool disposing)
private void InitializeComponent()
{
this.splitContainerTreeAndDetails = new System.Windows.Forms.SplitContainer();
- this.shellTreeView = new ServerManager.ShellDebugger.ShellTreeView();
this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer();
this.toolStripViewMode = new System.Windows.Forms.ToolStrip();
+ this.shellTreeView = new ServerManager.ShellDebugger.ShellTreeView();
((System.ComponentModel.ISupportInitialize)(this.splitContainerTreeAndDetails)).BeginInit();
this.splitContainerTreeAndDetails.Panel1.SuspendLayout();
this.splitContainerTreeAndDetails.SuspendLayout();
@@ -49,19 +49,13 @@ private void InitializeComponent()
// splitContainerTreeAndDetails.Panel1
//
this.splitContainerTreeAndDetails.Panel1.Controls.Add(this.shellTreeView);
- this.splitContainerTreeAndDetails.Size = new System.Drawing.Size(584, 416);
- this.splitContainerTreeAndDetails.SplitterDistance = 194;
- this.splitContainerTreeAndDetails.TabIndex = 2;
//
- // shellTreeView
+ // splitContainerTreeAndDetails.Panel2
//
- this.shellTreeView.Dock = System.Windows.Forms.DockStyle.Fill;
- this.shellTreeView.Location = new System.Drawing.Point(0, 0);
- this.shellTreeView.Name = "shellTreeView";
- this.shellTreeView.ShowFiles = false;
- this.shellTreeView.ShowHiddenFilesAndFolders = false;
- this.shellTreeView.Size = new System.Drawing.Size(194, 416);
- this.shellTreeView.TabIndex = 0;
+ this.splitContainerTreeAndDetails.Panel2.Resize += new System.EventHandler(this.splitContainerTreeAndDetails_Panel2_Resize);
+ this.splitContainerTreeAndDetails.Size = new System.Drawing.Size(584, 416);
+ this.splitContainerTreeAndDetails.SplitterDistance = 140;
+ this.splitContainerTreeAndDetails.TabIndex = 2;
//
// toolStripContainer1
//
@@ -86,9 +80,19 @@ private void InitializeComponent()
this.toolStripViewMode.Dock = System.Windows.Forms.DockStyle.None;
this.toolStripViewMode.Location = new System.Drawing.Point(3, 0);
this.toolStripViewMode.Name = "toolStripViewMode";
- this.toolStripViewMode.Size = new System.Drawing.Size(43, 25);
+ this.toolStripViewMode.Size = new System.Drawing.Size(111, 25);
this.toolStripViewMode.TabIndex = 0;
//
+ // shellTreeView
+ //
+ this.shellTreeView.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.shellTreeView.Location = new System.Drawing.Point(0, 0);
+ this.shellTreeView.Name = "shellTreeView";
+ this.shellTreeView.ShowFiles = false;
+ this.shellTreeView.ShowHiddenFilesAndFolders = false;
+ this.shellTreeView.Size = new System.Drawing.Size(140, 416);
+ this.shellTreeView.TabIndex = 0;
+ //
// ShellDebuggerForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
diff --git a/SharpShell/Tools/ServerManager/ShellDebugger/ShellDebuggerForm.cs b/SharpShell/Tools/ServerManager/ShellDebugger/ShellDebuggerForm.cs
index fdbc4615..edd09f6d 100644
--- a/SharpShell/Tools/ServerManager/ShellDebugger/ShellDebuggerForm.cs
+++ b/SharpShell/Tools/ServerManager/ShellDebugger/ShellDebuggerForm.cs
@@ -173,11 +173,11 @@ int IShellBrowser.BrowseObject(IntPtr pidl, SBSP wFlags)
}
// Check that we have a new pidl
- if (Shell32.ILIsEqual(pidlTmp, currentAbsolutePidl))
- {
- Shell32.ILFree(pidlTmp);
- return WinError.S_OK;
- }
+ //if (Shell32.ILIsEqual(pidlTmp, currentAbsolutePidl))
+ //{
+ // Shell32.ILFree(pidlTmp);
+ // return WinError.S_OK;
+ //}
currentFolder = folderTmp;
@@ -331,5 +331,17 @@ int ICommDlgBrowser.IncludeObject(IntPtr ppshv, IntPtr pidl)
{
return WinError.S_OK;
}
+
+ private void splitContainerTreeAndDetails_Panel2_Resize(object sender, EventArgs e)
+ {
+ var selectedNode = shellTreeView.SelectedNode;
+
+ if (selectedNode != null)
+ {
+ var shellItem = shellTreeView.GetShellItem(selectedNode);
+ // Browse to the selected item if it is a folder.
+ ((IShellBrowser) this).BrowseObject(shellItem.PIDL, SBSP.SBSP_SAMEBROWSER | SBSP.SBSP_ABSOLUTE);
+ }
+ }
}
}
diff --git a/SharpShell/Tools/ServerManager/ShellDebugger/ShellTreeView.cs b/SharpShell/Tools/ServerManager/ShellDebugger/ShellTreeView.cs
index 08000c09..1115e151 100644
--- a/SharpShell/Tools/ServerManager/ShellDebugger/ShellTreeView.cs
+++ b/SharpShell/Tools/ServerManager/ShellDebugger/ShellTreeView.cs
@@ -6,7 +6,6 @@
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
-using System.Windows.Forms.VisualStyles;
using SharpShell.Interop;
using SharpShell.Pidl;
@@ -28,7 +27,7 @@ public ShellTreeView()
// Set the image list to the shell image list.
this.SetImageList(TreeViewExtensions.ImageListType.Normal, ShellImageList.GetImageList(ShellImageListSize.Small));
- this.AfterSelect += ShellTreeView_AfterSelect;
+ AfterSelect += ShellTreeView_AfterSelect;
}
@@ -68,7 +67,7 @@ private void AddDesktopNode()
};
// Map it and add it.
- nodesToFolders[desktopNode] = desktopFolder;
+ _nodesToFolders[desktopNode] = desktopFolder;
Nodes.Add(desktopNode);
// Fire the event.
@@ -92,7 +91,7 @@ protected override void OnBeforeExpand(TreeViewCancelEventArgs e)
node.Nodes.Clear();
// Get the shell folder.
- var shellFolder = nodesToFolders[node];
+ var shellFolder = _nodesToFolders[node];
// Create the enum flags.
var childFlags = ChildTypes.Folders | ChildTypes.Files;
@@ -109,14 +108,14 @@ protected override void OnBeforeExpand(TreeViewCancelEventArgs e)
{
// Create a child node.
var childNode = new TreeNode
- {
- Text = child.DisplayName,
- ImageIndex = child.IconIndex,
- SelectedImageIndex = child.IconIndex,
- };
+ {
+ Text = child.DisplayName,
+ ImageIndex = child.IconIndex,
+ SelectedImageIndex = child.IconIndex,
+ };
// Map the node to the shell folder.
- nodesToFolders[childNode] = child;
+ _nodesToFolders[childNode] = child;
// If this item has children, add a child node as a placeholder.
if (child.HasSubFolders)
@@ -143,8 +142,7 @@ protected override void OnBeforeExpand(TreeViewCancelEventArgs e)
/// The shell item for the tree node.
public ShellItem GetShellItem(TreeNode node)
{
- ShellItem shellFolder;
- if(nodesToFolders.TryGetValue(node, out shellFolder))
+ if(_nodesToFolders.TryGetValue(node, out var shellFolder))
return shellFolder;
return null;
}
@@ -156,22 +154,18 @@ public ShellItem GetShellItem(TreeNode node)
private void FireOnShellItemAdded(TreeNode nodeAdded)
{
// Fire the event if we have it.
- var theEvent = OnShellItemAdded;
- if(theEvent != null)
- theEvent(this, new TreeViewEventArgs(nodeAdded));
+ OnShellItemAdded?.Invoke(this, new TreeViewEventArgs(nodeAdded));
}
private void FireOnShellItemSelected(ShellItem shellItem)
{
- var theEvent = OnShellItemSelected;
- if(theEvent != null)
- theEvent(this, new ShellTreeEventArgs(shellItem));
+ OnShellItemSelected?.Invoke(this, new ShellTreeEventArgs(shellItem));
}
///
/// A map of tree nodes to the Shell Folders.
///
- private readonly Dictionary nodesToFolders = new Dictionary();
+ private readonly Dictionary _nodesToFolders = new Dictionary();
///
/// Gets or sets a value indicating whether to show hidden files and folders.
@@ -199,7 +193,7 @@ private void FireOnShellItemSelected(ShellItem shellItem)
/// true if the is in design mode; otherwise, false.
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public new bool DesignMode { get { return (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv"); } }
+ public new bool DesignMode { get => System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv"; }
///
/// Occurs when a shell item is added.
@@ -212,11 +206,11 @@ private void FireOnShellItemSelected(ShellItem shellItem)
private void InitializeComponent()
{
- this.SuspendLayout();
+ SuspendLayout();
//
// ShellTreeView
//
- this.ResumeLayout(false);
+ ResumeLayout(false);
}
@@ -253,7 +247,7 @@ private void OpenItemContextMenu(ShellItem itemHit, int x, int y)
// Get the UI object of the context menu.
- IntPtr apidl = PidlManager.PidlsToAPidl(new IntPtr[] {PidlManager.IdListToPidl(fullIdList)});
+ IntPtr apidl = PidlManager.PidlsToAPidl(new[] {PidlManager.IdListToPidl(fullIdList)});
IntPtr ppv = IntPtr.Zero;
@@ -362,15 +356,14 @@ static ShellImageList()
public static IntPtr GetImageList(ShellImageListSize imageListSize)
{
// Do we have the image list?
- IImageList imageList;
- if (imageLists.TryGetValue(imageListSize, out imageList))
+ if (ImageLists.TryGetValue(imageListSize, out var imageList))
return GetImageListHandle(imageList);
// We don't have the image list, create it.
Shell32.SHGetImageList((int)imageListSize, ref Shell32.IID_IImageList, ref imageList);
// Add it to the dictionary.
- imageLists.Add(imageListSize, imageList);
+ ImageLists.Add(imageListSize, imageList);
// Return it.
return GetImageListHandle(imageList);
@@ -389,7 +382,7 @@ private static IntPtr GetImageListHandle(IImageList imageList)
///
/// The shell image lists.
///
- private readonly static Dictionary imageLists = new Dictionary();
+ private static readonly Dictionary ImageLists = new Dictionary();
}
///
@@ -444,8 +437,8 @@ static ShellItem()
public ShellItem()
{
// Create the lazy path.
- path = new Lazy(CreatePath);
- overlayIcon = new Lazy(CreateOverlayIcon);
+ _path = new Lazy(CreatePath);
+ _overlayIcon = new Lazy(CreateOverlayIcon);
}
///
@@ -468,8 +461,7 @@ private Icon CreateOverlayIcon()
private static ShellItem CreateDesktopShellFolder()
{
// Get the desktop shell folder interface.
- IShellFolder desktopShellFolderInterface = null;
- var result = Shell32.SHGetDesktopFolder(out desktopShellFolderInterface);
+ var result = Shell32.SHGetDesktopFolder(out var desktopShellFolderInterface);
// Validate the result.
if (result != 0)
@@ -478,10 +470,10 @@ private static ShellItem CreateDesktopShellFolder()
Marshal.ThrowExceptionForHR(result);
}
- // Get the dekstop PDIL.
- var desktopPIDL = IntPtr.Zero;
- result = Shell32.SHGetSpecialFolderLocation(IntPtr.Zero, CSIDL.CSIDL_DESKTOP, ref desktopPIDL);
- result = Shell32.SHGetFolderLocation(IntPtr.Zero, CSIDL.CSIDL_DESKTOP, IntPtr.Zero, 0, out desktopPIDL);
+ // Get the desktop PDIL.
+ // TODO
+ //result = Shell32.SHGetSpecialFolderLocation(IntPtr.Zero, CSIDL.CSIDL_DESKTOP, ref desktopPIDL);
+ result = Shell32.SHGetFolderLocation(IntPtr.Zero, CSIDL.CSIDL_DESKTOP, IntPtr.Zero, 0, out var desktopPIDL);
// Validate the result.
if (result != 0)
@@ -509,11 +501,11 @@ private static ShellItem CreateDesktopShellFolder()
}
///
- /// Initialises the ShellItem, from its PIDL and parent.
+ /// Initializes the ShellItem, from its PIDL and parent.
///
/// The pidl.
/// The parent folder.
- private void Initialise(IntPtr pidl, ShellItem parentFolder)
+ private void Initialize(IntPtr pidl, ShellItem parentFolder)
{
// Set the parent item and relative pidl.
ParentItem = parentFolder;
@@ -549,18 +541,20 @@ private void Initialise(IntPtr pidl, ShellItem parentFolder)
if (IsFolder)
{
// Bind the shell folder interface.
- IShellFolder shellFolderInterface;
- IntPtr ppv = IntPtr.Zero;
- var result = parentFolder.ShellFolderInterface.BindToObject(pidl, IntPtr.Zero, ref Shell32.IID_IShellFolder,
- out ppv);//out shellFolderInterface);
- shellFolderInterface = ((IShellFolder) Marshal.GetObjectForIUnknown(ppv));
+ var result = parentFolder.ShellFolderInterface.BindToObject(
+ pidl,
+ IntPtr.Zero,
+ ref Shell32.IID_IShellFolder,
+ out var ppv
+ );//out shellFolderInterface);
+ var shellFolderInterface = ((IShellFolder) Marshal.GetObjectForIUnknown(ppv));
ShellFolderInterface = shellFolderInterface;
// Validate the result.
if (result != 0)
{
// Throw the failure as an exception.
- Marshal.ThrowExceptionForHR((int)result);
+ Marshal.ThrowExceptionForHR(result);
}
}
}
@@ -588,7 +582,7 @@ public IEnumerable GetChildren(ChildTypes childTypes)
// We'll return a list of children.
var children = new List();
- // Create the enum flags from the childtypes.
+ // Create the enum flags from the child-types.
SHCONTF enumFlags = 0;
if (childTypes.HasFlag(ChildTypes.Folders))
enumFlags |= SHCONTF.SHCONTF_FOLDERS;
@@ -607,7 +601,7 @@ public IEnumerable GetChildren(ChildTypes childTypes)
if (result != 0)
{
// Throw the failure as an exception.
- Marshal.ThrowExceptionForHR((int)result);
+ Marshal.ThrowExceptionForHR(result);
}
// TODO: This logic should go in the pidl manager.
@@ -615,11 +609,10 @@ public IEnumerable GetChildren(ChildTypes childTypes)
// Enumerate the children, ten at a time.
const int batchSize = 10;
var pidlArray = Marshal.AllocCoTaskMem(IntPtr.Size * 10);
- uint itemsFetched;
- result = WinError.S_OK;
+
do
{
- result = pEnum.Next(batchSize, pidlArray, out itemsFetched);
+ result = pEnum.Next(batchSize, pidlArray, out var itemsFetched);
// Get each pidl.
var pidls = new IntPtr[itemsFetched];
@@ -632,11 +625,11 @@ public IEnumerable GetChildren(ChildTypes childTypes)
// Initialize it.
try
{
- childShellFolder.Initialise(childPidl, this);
+ childShellFolder.Initialize(childPidl, this);
}
catch (Exception exception)
{
- throw new InvalidOperationException("Failed to initialise child.", exception);
+ throw new InvalidOperationException("Failed to initialize child.", exception);
}
// Add the child.
@@ -659,15 +652,17 @@ public IEnumerable GetChildren(ChildTypes childTypes)
}
// Sort the children.
- var sortedChildren = children.Where(c => c.IsFolder).ToList();
- sortedChildren.AddRange(children.Where(c => !c.IsFolder));
+ var sortedChildren = children
+ .Where(c => c.IsFolder)
+ .Concat(children.Where(c => !c.IsFolder))
+ .ToList();
// Return the children.
return sortedChildren;
}
///
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting un-managed resources.
///
public void Dispose()
{
@@ -702,12 +697,12 @@ public override string ToString()
///
/// The lazy path.
///
- private readonly Lazy path;
+ private readonly Lazy _path;
///
/// The overlay icon.
///
- private readonly Lazy overlayIcon;
+ private readonly Lazy _overlayIcon;
///
/// Gets the parent item.
@@ -751,7 +746,10 @@ public override string ToString()
///
/// Gets the ShellFolder of the Desktop.
///
- public static ShellItem DesktopShellFolder { get { return desktopShellFolder.Value; } }
+ public static ShellItem DesktopShellFolder
+ {
+ get => desktopShellFolder.Value;
+ }
///
/// Gets the shell folder interface.
@@ -779,7 +777,10 @@ public override string ToString()
///
/// Gets the path.
///
- public string Path { get { return path.Value; } }
+ public string Path
+ {
+ get => _path.Value;
+ }
///
/// Gets the overlay icon.
@@ -787,7 +788,10 @@ public override string ToString()
///
/// The overlay icon.
///
- public Icon OverlayIcon { get { return overlayIcon.Value; } }
+ public Icon OverlayIcon
+ {
+ get => _overlayIcon.Value;
+ }
}
///
/// The Child Type flags.
diff --git a/SharpShell/Tools/ServerManager/ShellExtensionEntry.cs b/SharpShell/Tools/ServerManager/ShellExtensionEntry.cs
new file mode 100644
index 00000000..d6dd9fcd
--- /dev/null
+++ b/SharpShell/Tools/ServerManager/ShellExtensionEntry.cs
@@ -0,0 +1,419 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using SharpShell.ServerRegistration;
+
+namespace ServerManager
+{
+ internal class ShellExtensionEntry : INotifyPropertyChanged, IEquatable
+ {
+ private ServerInstallationInfo _installationInfo32;
+ private ServerInstallationInfo _installationInfo64;
+ private bool _isNative;
+ private ShellExtensionRegistrationInfo _registrationInfo32;
+ private ShellExtensionRegistrationInfo _registrationInfo64;
+ private SharpShellServerInfo _sharpShellServerInfo;
+
+ public ShellExtensionEntry(Guid serverClassId)
+ {
+ ServerClassId = serverClassId;
+ }
+
+ public ShellExtensionEntry(SharpShellServerInfo serverInfo) : this(serverInfo.ClassId)
+ {
+ SharpShellServerInfo = serverInfo;
+ UpdateInstallationInfo32();
+ UpdateInstallationInfo64();
+ UpdateRegistrationInfo32();
+ UpdateRegistrationInfo64();
+ }
+
+ public ServerInstallationInfo InstallationInfo32
+ {
+ get => _installationInfo32;
+ private set
+ {
+ _installationInfo32 = value;
+ OnPropertyChanged(nameof(InstallationInfo32));
+ OnPropertyChanged(nameof(ServerPath));
+ OnPropertyChanged(nameof(IsNative));
+ OnPropertyChanged(nameof(ServerDisplayName));
+ }
+ }
+
+ public ServerInstallationInfo InstallationInfo64
+ {
+ get => _installationInfo64;
+ private set
+ {
+ _installationInfo64 = value;
+ OnPropertyChanged(nameof(InstallationInfo64));
+ OnPropertyChanged(nameof(ServerPath));
+ OnPropertyChanged(nameof(IsNative));
+ OnPropertyChanged(nameof(ServerDisplayName));
+ }
+ }
+
+ public bool IsNative
+ {
+ get
+ {
+ if (_isNative)
+ {
+ return true;
+ }
+
+ if (InstallationInfo32 != null)
+ {
+ return InstallationInfo32.ServerInstallationType != ServerInstallationType.ManagedInProcess32;
+ }
+
+ if (InstallationInfo64 != null)
+ {
+ return InstallationInfo64.ServerInstallationType != ServerInstallationType.ManagedInProcess32;
+ }
+
+ return false;
+ }
+ set
+ {
+ _isNative = value;
+ OnPropertyChanged(nameof(IsNative));
+ }
+ }
+
+ public ShellExtensionRegistrationInfo RegistrationInfo32
+ {
+ get => _registrationInfo32;
+ private set
+ {
+ _registrationInfo32 = value;
+ OnPropertyChanged(nameof(RegistrationInfo32));
+ OnPropertyChanged(nameof(ShellAssociatedClassNames));
+ OnPropertyChanged(nameof(ServerDisplayName));
+ }
+ }
+
+ public ShellExtensionRegistrationInfo RegistrationInfo64
+ {
+ get => _registrationInfo64;
+ private set
+ {
+ _registrationInfo64 = value;
+ OnPropertyChanged(nameof(RegistrationInfo64));
+ OnPropertyChanged(nameof(ShellAssociatedClassNames));
+ OnPropertyChanged(nameof(ServerDisplayName));
+ }
+ }
+
+ public Guid ServerClassId { get; }
+
+ public string ServerDisplayName
+ {
+ get
+ {
+ return SharpShellServerInfo?.DisplayName ??
+ SharpShellServerInfo?.RegistrationName ??
+ SharpShellServerInfo?.ClassName ??
+ RegistrationInfo32?.Associations
+ .FirstOrDefault(info => !string.IsNullOrWhiteSpace(info.RegistrationName))
+ ?.RegistrationName ??
+ RegistrationInfo64?.Associations
+ .FirstOrDefault(info => !string.IsNullOrWhiteSpace(info.RegistrationName))
+ ?.RegistrationName ??
+ InstallationInfo32?.ManagedClassName ??
+ InstallationInfo64?.ManagedClassName ??
+ ServerClassId.ToString("B");
+ }
+ }
+
+ public string ServerPath
+ {
+ get => InstallationInfo32?.ServerPath ?? InstallationInfo64?.ServerPath;
+ }
+
+ public SharpShellServerInfo SharpShellServerInfo
+ {
+ get => _sharpShellServerInfo;
+ private set
+ {
+ _sharpShellServerInfo = value;
+ OnPropertyChanged(nameof(SharpShellServerInfo));
+ OnPropertyChanged(nameof(ServerDisplayName));
+ }
+ }
+
+ public string[] ShellAssociatedClassNames
+ {
+ get
+ {
+ if (RegistrationInfo32 != null || RegistrationInfo64 != null)
+ {
+ return (RegistrationInfo32?.Associations ?? new ShellExtensionRegisteredAssociationInfo[0])
+ .Concat(RegistrationInfo64?.Associations ?? new ShellExtensionRegisteredAssociationInfo[0])
+ .Select(info => info.AssociationClassName).Distinct().ToArray();
+ }
+
+ return (SharpShellServerInfo?.AssociationClassNamesX32 ?? new string[0])
+ .Concat(SharpShellServerInfo?.AssociationClassNamesX64 ?? new string[0])
+ .Distinct().ToArray();
+ }
+ }
+
+ public ShellExtensionType[] ShellExtensionTypes
+ {
+ get
+ {
+ var extensionTypes = new List();
+
+ if (SharpShellServerInfo?.ShellExtensionType != null)
+ {
+ extensionTypes.Add(SharpShellServerInfo.ShellExtensionType);
+ }
+
+ if (RegistrationInfo32 != null)
+ {
+ extensionTypes.AddRange(RegistrationInfo32.Associations.Select(info => info.ShellExtensionType));
+ }
+
+ if (RegistrationInfo64 != null)
+ {
+ extensionTypes.AddRange(RegistrationInfo64.Associations.Select(info => info.ShellExtensionType));
+ }
+
+ if (extensionTypes.Count == 0)
+ {
+ return new[] {ShellExtensionType.None};
+ }
+
+ return extensionTypes.Distinct().Where(type => type != ShellExtensionType.None).ToArray();
+ }
+ }
+
+ ///
+ public bool Equals(ShellExtensionEntry other)
+ {
+ if (ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ if (ReferenceEquals(this, other))
+ {
+ return true;
+ }
+
+ return ServerClassId.Equals(other.ServerClassId);
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public static IEnumerable GetRegisteredEntries()
+ {
+ var extensions32 = ServerRegistrationManager.EnumerateRegisteredExtensions(RegistrationScope.OS32Bit)
+ .Select(info =>
+ new Tuple(RegistrationScope.OS32Bit, info)
+ );
+
+ var extensions64 = ServerRegistrationManager.EnumerateRegisteredExtensions(RegistrationScope.OS64Bit)
+ .Select(info =>
+ new Tuple(RegistrationScope.OS64Bit, info)
+ );
+
+ var extensions = extensions32.Concat(extensions64).GroupBy(info => info.Item2.ServerClassId);
+
+ foreach (var extensionGroup in extensions)
+ {
+ var extension = new ShellExtensionEntry(extensionGroup.Key)
+ {
+ RegistrationInfo64 =
+ extensionGroup.FirstOrDefault(t => t.Item1 == RegistrationScope.OS64Bit)?.Item2,
+ RegistrationInfo32 = extensionGroup.FirstOrDefault(t => t.Item1 == RegistrationScope.OS32Bit)?.Item2
+ };
+
+ extension.UpdateManagedServerInfo();
+
+ yield return extension;
+ }
+ }
+
+ public static bool operator ==(ShellExtensionEntry left, ShellExtensionEntry right)
+ {
+ return Equals(left, right) || left?.Equals(right) == true;
+ }
+
+ public static bool operator !=(ShellExtensionEntry left, ShellExtensionEntry right)
+ {
+ return !(left == right);
+ }
+
+ ///
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj))
+ {
+ return false;
+ }
+
+ if (ReferenceEquals(this, obj))
+ {
+ return true;
+ }
+
+ return Equals(obj as ShellExtensionEntry);
+ }
+
+ ///
+ public override int GetHashCode()
+ {
+ return ServerClassId.GetHashCode();
+ }
+
+ public void UpdateInstallationInfo32()
+ {
+ var installation = ServerRegistrationManager.GetExtensionInstallationInfo(
+ ServerClassId,
+ RegistrationScope.OS32Bit
+ );
+
+ if (installation?.ServerInstallationType != ServerInstallationType.PartiallyInstalled)
+ {
+ InstallationInfo32 = installation;
+ }
+ else
+ {
+ InstallationInfo32 = null;
+ }
+ }
+
+ public void UpdateInstallationInfo64()
+ {
+ var installation = ServerRegistrationManager.GetExtensionInstallationInfo(
+ ServerClassId,
+ RegistrationScope.OS64Bit
+ );
+
+ if (installation?.ServerInstallationType != ServerInstallationType.PartiallyInstalled)
+ {
+ InstallationInfo64 = installation;
+ }
+ else
+ {
+ InstallationInfo64 = null;
+ }
+ }
+
+ public void UpdateManagedServerInfo()
+ {
+ if (SharpShellServerInfo != null || IsNative)
+ {
+ return;
+ }
+
+ UpdateInstallationInfo32();
+ UpdateInstallationInfo64();
+
+ try
+ {
+ if (InstallationInfo64?.ServerInstallationType == ServerInstallationType.ManagedInProcess32)
+ {
+ SharpShellServerInfo = InstallationInfo64.GetSharpShellServerInformation();
+ }
+ else if (InstallationInfo32?.ServerInstallationType == ServerInstallationType.ManagedInProcess32)
+ {
+ SharpShellServerInfo = InstallationInfo32.GetSharpShellServerInformation();
+ }
+ }
+ catch
+ {
+ IsNative = true;
+ }
+ }
+
+ public void UpdateRegistrationInfo32()
+ {
+ if (SharpShellServerInfo != null)
+ {
+ var registration = ServerRegistrationManager.GetExtensionRegistrationInfo(
+ SharpShellServerInfo,
+ RegistrationScope.OS32Bit
+ );
+
+ if (registration?.Associations.Any() == true)
+ {
+ RegistrationInfo32 = registration;
+ }
+ else
+ {
+ RegistrationInfo32 = null;
+ }
+ }
+ else
+ {
+ var registration = ServerRegistrationManager.GetExtensionRegistrationInfo(
+ ServerClassId,
+ RegistrationScope.OS32Bit
+ );
+
+ if (registration?.Associations.Any() == true)
+ {
+ RegistrationInfo32 = registration;
+ }
+ else
+ {
+ RegistrationInfo32 = null;
+ }
+ }
+ }
+
+ public void UpdateRegistrationInfo64()
+ {
+ if (SharpShellServerInfo != null)
+ {
+ var registration = ServerRegistrationManager.GetExtensionRegistrationInfo(
+ SharpShellServerInfo,
+ RegistrationScope.OS64Bit
+ );
+
+ if (registration?.Associations.Any() == true)
+ {
+ RegistrationInfo64 = registration;
+ }
+ else
+ {
+ RegistrationInfo64 = null;
+ }
+ }
+ else
+ {
+ var registration = ServerRegistrationManager.GetExtensionRegistrationInfo(
+ ServerClassId,
+ RegistrationScope.OS64Bit
+ );
+
+ if (registration?.Associations.Any() == true)
+ {
+ RegistrationInfo64 = registration;
+ }
+ else
+ {
+ RegistrationInfo64 = null;
+ }
+ }
+ }
+
+ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ try
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+ catch
+ {
+ // ignored
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/SharpShell/Tools/ServerManager/TestShell/TestShellForm.cs b/SharpShell/Tools/ServerManager/TestShell/TestShellForm.cs
index f3a5f7ef..0ca1a850 100644
--- a/SharpShell/Tools/ServerManager/TestShell/TestShellForm.cs
+++ b/SharpShell/Tools/ServerManager/TestShell/TestShellForm.cs
@@ -4,11 +4,9 @@
using System.Drawing;
using System.IO;
using System.Linq;
-using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Windows.Forms;
-using Apex.WinForms.Interop;
using Apex.WinForms.Shell;
using Microsoft.Win32;
using SharpShell;
@@ -41,19 +39,19 @@ public TestShellForm()
{
InitializeComponent();
- lazyBoldFont = new Lazy(() => new Font(Font, FontStyle.Bold));
+ _lazyBoldFont = new Lazy(() => new Font(Font, FontStyle.Bold));
- shellTreeView.OnShellItemAdded += new TreeViewEventHandler(shellTreeView_OnShellItemAdded);
- shellListView.OnShellItemAdded += new Apex.WinForms.Controls.ListViewItemEventHandler(shellListView_OnShellItemAdded);
+ shellTreeView.OnShellItemAdded += shellTreeView_OnShellItemAdded;
+ shellListView.OnShellItemAdded += shellListView_OnShellItemAdded;
// Create the ordered view menu items.
- orderedViewMenuItems.Add(largeIconsToolStripMenuItem);
- orderedViewMenuItems.Add(toolStripMenuItemSmallIcons);
- orderedViewMenuItems.Add(listToolStripMenuItem);
- orderedViewMenuItems.Add(detailsToolStripMenuItem);
- orderedViewMenuItems.Add(tileToolStripMenuItem);
+ _orderedViewMenuItems.Add(largeIconsToolStripMenuItem);
+ _orderedViewMenuItems.Add(toolStripMenuItemSmallIcons);
+ _orderedViewMenuItems.Add(listToolStripMenuItem);
+ _orderedViewMenuItems.Add(detailsToolStripMenuItem);
+ _orderedViewMenuItems.Add(tileToolStripMenuItem);
- shellListView.Columns.Add(new ColumnHeader {Text = "Name"});
+ shellListView.Columns.Add(new ColumnHeader {Text = @"Name"});
}
void shellTreeView_OnShellItemAdded(object sender, TreeViewEventArgs e)
@@ -71,27 +69,39 @@ void shellListView_OnShellItemAdded(object sender, Apex.WinForms.Controls.ListVi
// If the icon handler is associated with the the item, test it.
if (IsServerAssociatedWithShellItem(TestIconHandler, shellItem))
+ {
DoTestIconHandler(args.Item);
+ }
// If the info tip handler is associated with the item, test it.
if (IsServerAssociatedWithShellItem(TestInfoTipHandler, shellItem))
+ {
DoTestInfoTipHandler(args.Item);
+ }
// If the drop handler is associated with the item, test it.
if (IsServerAssociatedWithShellItem(TestDropHandler, shellItem))
+ {
DoTestDropHandler(args.Item);
+ }
// If the preview handler is associated with the item, test it.
if (IsServerAssociatedWithShellItem(TestPreviewHandler, shellItem))
+ {
DoTestPreviewHandler(args.Item);
+ }
// If a thumbnail handleris associated with the item, highlight it.
- if(IsServerAssociatedWithShellItem(TestThumbnailHandler, shellItem))
+ if (IsServerAssociatedWithShellItem(TestThumbnailHandler, shellItem))
+ {
HighlightItem(args.Item);
+ }
// If an icon overlay handler is associated with the item, highlight it.
- if(IsServerAssociatedWithShellItem(TestIconOverlayHandler, shellItem))
+ if (IsServerAssociatedWithShellItem(TestIconOverlayHandler, shellItem))
+ {
HighlightItem(args.Item);
+ }
}
private void shellTreeView1_MouseUp(object sender, MouseEventArgs e)
@@ -100,7 +110,7 @@ private void shellTreeView1_MouseUp(object sender, MouseEventArgs e)
{
if (shellTreeView.SelectedNode == null) return;
- // Get the point in screen coords.
+ // Get the point in screen coordination.
var screenPoint = shellTreeView.PointToScreen(new Point(e.X, e.Y));
// Get the shell item.
@@ -118,7 +128,7 @@ private void shellListView1_MouseUp(object sender, MouseEventArgs e)
// Get the highlighted items.
var items = shellListView.SelectedItems.OfType().Select(lvi => shellListView.GetShellItem(lvi)).ToArray();
- // Get the point in screen coords.
+ // Get the point in screen coordination.
var screenPoint = shellListView.PointToScreen(new Point(e.X, e.Y));
// Test it.
@@ -136,7 +146,9 @@ private void DoTestMenu(ShellItem[] items, int x, int y)
{
// If we don't have a context menu, we can bail now.
if (TestContextMenu == null)
+ {
return;
+ }
// Get the interfaces we need to test with.
var shellExtInitInterface = (IShellExtInit) TestContextMenu;
@@ -156,7 +168,7 @@ private void DoTestMenu(ShellItem[] items, int x, int y)
// Get the IUnknown COM interface address. Jesus .NET makes this easy.
var dataObjectInterfacePointer = Marshal.GetIUnknownForObject(dataObject);
- // Pass the data to the shell extension, attempt to initialise it.
+ // Pass the data to the shell extension, attempt to initialize it.
// We must provide the data object as well as the parent folder PIDL.
if (items.Any())
{
@@ -189,19 +201,19 @@ protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
- // Do we have a comamnd and a shell context menu we're testing?
+ // Do we have a command and a shell context menu we're testing?
if (m.Msg == WM_COMMAND && TestContextMenu != null)
{
- var loword = LowWord(m.WParam.ToInt32());
- var hiword = HighWord(m.WParam.ToInt32());
+ var lowWord = LowWord(m.WParam.ToInt32());
+ var highWord = HighWord(m.WParam.ToInt32());
- // If the hiword is 0 it's a menu command.
- if (hiword == 0)
+ // If the high is 0 it's a menu command.
+ if (highWord == 0)
{
// Create command info.
var commandInfo = new CMINVOKECOMMANDINFO();
commandInfo.cbSize = (uint) Marshal.SizeOf(commandInfo);
- commandInfo.verb = new IntPtr(loword);
+ commandInfo.verb = new IntPtr(lowWord);
// Get a pointer to the structure.
var commandInfoPointer = Marshal.AllocHGlobal(Marshal.SizeOf(commandInfo));
@@ -214,8 +226,7 @@ protected override void WndProc(ref Message m)
public static int HighWord(int number)
{
- return ((number & 0x80000000) == 0x80000000) ?
- (number >> 16) : ((number >> 16) & 0xffff);
+ return (number & 0x80000000) == 0x80000000 ? number >> 16 : (number >> 16) & 0xffff;
}
public static int LowWord(int number)
@@ -228,13 +239,20 @@ private void shellListView_SelectedIndexChanged(object sender, EventArgs e)
var shellItem = shellListView.SelectedItems.Count > 0 ? shellListView.GetShellItem(shellListView.SelectedItems[0]) : null;
if (shellItem != null)
- toolStripStatusLabelAttributes.Text = "Attributes: " + shellItem.Attributes.ToString();
+ {
+ toolStripStatusLabelAttributes.Text = @"Attributes: " + shellItem.Attributes;
+ }
propertyGridSelectedObject.SelectedObject = shellItem;
-
+
+ if (shellItem?.Path == null)
+ {
+ return;
+ }
+
if (IsServerAssociatedWithShellItem(TestPreviewHandler, shellItem))
{
- shellPreviewHost1.SetPreviewHandler(TestPreviewHandler.ServerClsid);
+ shellPreviewHost1.SetPreviewHandler(TestPreviewHandler.ServerClassId);
shellPreviewHost1.SetPreviewItem(shellItem.Path);
}
@@ -273,11 +291,10 @@ private void DoTestIconHandler(ListViewItem item)
{
var shellItem = shellListView.GetShellItem(item);
- IntPtr iconSmall, iconLarge;
- GetIconHandlerIcons(TestIconHandler, shellItem.Path, out iconSmall, out iconLarge);
+ GetIconHandlerIcons(TestIconHandler, shellItem.Path, out var iconSmall, out var iconLarge);
// We're testing the item, so make it bold.
- item.Font = lazyBoldFont.Value;
+ item.Font = _lazyBoldFont.Value;
// Add the icons.
var largeIcon = Icon.FromHandle(iconLarge);
@@ -291,6 +308,7 @@ private void DoTestIconHandler(ListViewItem item)
}
catch (Exception)
{
+ // ignored
}
}
@@ -309,28 +327,30 @@ private void GetIconHandlerIcons(SharpIconHandler iconHandler, string path, out
private void DoTestInfoTipHandler(ListViewItem item)
{
if (TestInfoTipHandler == null)
+ {
return;
+ }
// Get the shell item.
try
{
var shellItem = shellListView.GetShellItem(item);
- // Initialise the icon handler.
+ // Initialize the icon handler.
var persistFileInterface = (IPersistFile)TestInfoTipHandler;
persistFileInterface.Load(shellItem.Path, 0);
// Get the info tip.
var queryInfoInterface = (IQueryInfo)TestInfoTipHandler;
- string infoTip;
- queryInfoInterface.GetInfoTip(QITIPF.QITIPF_DEFAULT, out infoTip);
+ queryInfoInterface.GetInfoTip(QITIPF.QITIPF_DEFAULT, out var infoTip);
// Set the tooltip.
- item.Font = lazyBoldFont.Value;
+ item.Font = _lazyBoldFont.Value;
item.ToolTipText = infoTip;
}
catch (Exception)
{
+ // ignored
}
}
@@ -339,13 +359,15 @@ private void DoTestInfoTipHandler(ListViewItem item)
private void DoTestDropHandler(ListViewItem item)
{
if (TestDropHandler == null)
+ {
return;
+ }
- // Add the item to the set of test drop items.
- testDropItems.Add(item);
+ // Add the item to the set of test drop items.
+ _testDropItems.Add(item);
- // Highlight the item.
- HighlightItem(item);
+ // Highlight the item.
+ HighlightItem(item);
}
private void DoTestPreviewHandler(ListViewItem item)
@@ -364,10 +386,10 @@ private void DoTestPreviewHandler(ListViewItem item)
private void HighlightItem(ListViewItem listViewItem)
{
// Set the font to bold.
- listViewItem.Font = lazyBoldFont.Value;
+ listViewItem.Font = _lazyBoldFont.Value;
}
- private readonly List testDropItems = new List();
+ private readonly List _testDropItems = new List();
///
/// Determines whether a server is associated with a shell item.
@@ -384,18 +406,26 @@ private bool IsServerAssociatedWithShellItem(ISharpShellServer server, ShellItem
return false;
// Get the associations.
- var associationType = COMServerAssociationAttribute.GetAssociationType(server.GetType());
+ var associationType = COMServerAssociationAttribute.GetAssociationTypes(server.GetType()).FirstOrDefault();
var associations = COMServerAssociationAttribute.GetAssociations(server.GetType());
// TODO: This is potentially a very useful check - maybe it should be moved into the
// COMServerAssociationAttribute class so that it can be reused.
// We have a special case for icon overlays.
- if (server is SharpIconOverlayHandler && TestIconOverlayHandler != null && shellItem.Attributes.HasFlag(SFGAO.SFGAO_FILESYSTEM))
- if (((IShellIconOverlayIdentifier)TestIconOverlayHandler).IsMemberOf(shellItem.Path, FILE_ATTRIBUTE.FILE_ATTRIBUTE_NORMAL) == 0)
+ if (server is SharpIconOverlayHandler &&
+ TestIconOverlayHandler != null &&
+ shellItem.Attributes.HasFlag(SFGAO.SFGAO_FILESYSTEM))
+ {
+ if (((IShellIconOverlayIdentifier) TestIconOverlayHandler).IsMemberOf(shellItem.Path,
+ FILE_ATTRIBUTE.FILE_ATTRIBUTE_NORMAL) ==
+ 0)
+ {
return true;
+ }
+ }
- // Based on the assocation type, we can check the shell item.
+ // Based on the association type, we can check the shell item.
switch (associationType)
{
// This is checked for backwards compatibility.
@@ -407,10 +437,11 @@ private bool IsServerAssociatedWithShellItem(ISharpShellServer server, ShellItem
if (shellItem.Attributes.HasFlag(SFGAO.SFGAO_FILESYSTEM))
{
return
- associations.Any(
- a =>
- string.Compare(Path.GetExtension(shellItem.DisplayName), a,
- StringComparison.OrdinalIgnoreCase) == 0);
+ associations.Any(a => string.Equals(
+ Path.GetExtension(shellItem.DisplayName),
+ a,
+ StringComparison.OrdinalIgnoreCase
+ ));
}
break;
@@ -429,8 +460,6 @@ private bool IsServerAssociatedWithShellItem(ISharpShellServer server, ShellItem
// Do we match it?
return associations.Any(a => string.Compare(fileClass, FileExtensionClass.Get(classesRoot, a, false), StringComparison.InvariantCultureIgnoreCase) == 0);
}
-
-
}
break;
@@ -495,9 +524,9 @@ private void listToolStripMenuItem_Click(object sender, EventArgs e)
///
/// The view menu items, in order.
///
- private List orderedViewMenuItems = new List();
+ private readonly List _orderedViewMenuItems = new List();
- private readonly Lazy lazyBoldFont;
+ private readonly Lazy _lazyBoldFont;
private const uint WM_CONTEXTMENU = 0x007B;
private const uint WM_COMMAND = 0x0111;
@@ -530,7 +559,7 @@ internal static extern bool TrackPopupMenu(IntPtr hMenu,
///
/// The test context menu.
///
- public SharpContextMenu TestContextMenu { get { return TestServer as SharpContextMenu; } }
+ public SharpContextMenu TestContextMenu { get => TestServer as SharpContextMenu; }
///
/// Gets or sets the test icon handler.
@@ -538,7 +567,7 @@ internal static extern bool TrackPopupMenu(IntPtr hMenu,
///
/// The test icon handler.
///
- public SharpIconHandler TestIconHandler { get { return TestServer as SharpIconHandler; } }
+ public SharpIconHandler TestIconHandler { get => TestServer as SharpIconHandler; }
///
/// Gets the test thumbnail handler.
@@ -546,7 +575,7 @@ internal static extern bool TrackPopupMenu(IntPtr hMenu,
///
/// The test thumbnail handler.
///
- public SharpThumbnailHandler TestThumbnailHandler { get { return TestServer as SharpThumbnailHandler; } }
+ public SharpThumbnailHandler TestThumbnailHandler { get => TestServer as SharpThumbnailHandler; }
///
/// Gets or sets the test info tip handler.
@@ -554,12 +583,12 @@ internal static extern bool TrackPopupMenu(IntPtr hMenu,
///
/// The test info tip handler.
///
- public SharpInfoTipHandler TestInfoTipHandler { get { return TestServer as SharpInfoTipHandler; } }
+ public SharpInfoTipHandler TestInfoTipHandler { get => TestServer as SharpInfoTipHandler; }
///
/// Gets the test drop handler.
///
- public SharpDropHandler TestDropHandler { get { return TestServer as SharpDropHandler; } }
+ public SharpDropHandler TestDropHandler { get => TestServer as SharpDropHandler; }
///
/// Gets the test preview handler.
@@ -567,36 +596,39 @@ internal static extern bool TrackPopupMenu(IntPtr hMenu,
///
/// The test preview handler.
///
- public SharpPreviewHandler TestPreviewHandler { get { return TestServer as SharpPreviewHandler; } }
+ public SharpPreviewHandler TestPreviewHandler { get => TestServer as SharpPreviewHandler; }
///
/// Gets the test icon overlay handler.
///
- public SharpIconOverlayHandler TestIconOverlayHandler { get { return TestServer as SharpIconOverlayHandler; } }
+ public SharpIconOverlayHandler TestIconOverlayHandler { get => TestServer as SharpIconOverlayHandler; }
private void toolStripSplitButtonChangeYourView_ButtonClick(object sender, EventArgs e)
{
// Update it.
- currentViewIndex++;
- if (currentViewIndex >= orderedViewMenuItems.Count)
- currentViewIndex = 0;
+ _currentViewIndex++;
+
+ if (_currentViewIndex >= _orderedViewMenuItems.Count)
+ {
+ _currentViewIndex = 0;
+ }
- SetViewIndex(currentViewIndex);
- orderedViewMenuItems[currentViewIndex].PerformClick();
+ SetViewIndex(_currentViewIndex);
+ _orderedViewMenuItems[_currentViewIndex].PerformClick();
}
private void SetViewIndex(int index)
{
- currentViewIndex = index;
+ _currentViewIndex = index;
// Get the menu item to change to.
- var newItem = orderedViewMenuItems[currentViewIndex];
+ var newItem = _orderedViewMenuItems[_currentViewIndex];
// Set the icon.
toolStripSplitButtonChangeYourView.Image = newItem.Image;
}
- private int currentViewIndex = 0;
+ private int _currentViewIndex;
private void shellListView_ItemDrag(object sender, ItemDragEventArgs e)
{
@@ -606,7 +638,7 @@ private void shellListView_ItemDrag(object sender, ItemDragEventArgs e)
//shellListView.DoDragDrop(e.Item, DragDropEffects.All);
}
- private List dragItems = new List();
+ private List _dragItems = new List();
private void shellListView_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
{
@@ -647,7 +679,7 @@ private void toolStripButtonShowProperties_Click(object sender, EventArgs e)
const int SW_SHOW = 5;
- var shell_ex = new SHELLEXECUTEINFO
+ var shellExecuteInfo = new SHELLEXECUTEINFO
{
cbSize = Marshal.SizeOf(new SHELLEXECUTEINFO()),
lpFile = path,
@@ -656,7 +688,7 @@ private void toolStripButtonShowProperties_Click(object sender, EventArgs e)
lpVerb = "Properties"
};
- Shell32.ShellExecuteEx(ref shell_ex);
+ Shell32.ShellExecuteEx(ref shellExecuteInfo);
}
private void toolStripButtonShellOpenDialog_Click(object sender, EventArgs e)
diff --git a/SharpShell/Tools/ServerManager/Views/ServerDetailsView.Designer.cs b/SharpShell/Tools/ServerManager/Views/ServerDetailsView.Designer.cs
new file mode 100644
index 00000000..214f3492
--- /dev/null
+++ b/SharpShell/Tools/ServerManager/Views/ServerDetailsView.Designer.cs
@@ -0,0 +1,537 @@
+namespace ServerManager.Views
+{
+ partial class ServerDetailsView
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.label5 = new System.Windows.Forms.Label();
+ this.textBox32BitServerInstallation = new System.Windows.Forms.TextBox();
+ this.textBox64BitServerInstallation = new System.Windows.Forms.TextBox();
+ this.label7 = new System.Windows.Forms.Label();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.textBoxAssociations = new System.Windows.Forms.TextBox();
+ this.label8 = new System.Windows.Forms.Label();
+ this.textBoxServerPath = new System.Windows.Forms.TextBox();
+ this.label6 = new System.Windows.Forms.Label();
+ this.textBoxServerClassId = new System.Windows.Forms.TextBox();
+ this.textBoxExntensionTypes = new System.Windows.Forms.TextBox();
+ this.textBoxServerName = new System.Windows.Forms.TextBox();
+ this.label3 = new System.Windows.Forms.Label();
+ this.label2 = new System.Windows.Forms.Label();
+ this.label1 = new System.Windows.Forms.Label();
+ this.groupBox2 = new System.Windows.Forms.GroupBox();
+ this.groupBoxRegistration = new System.Windows.Forms.GroupBox();
+ this.textBox32BitServerRegistration = new System.Windows.Forms.TextBox();
+ this.label9 = new System.Windows.Forms.Label();
+ this.textBox64BitServerRegistration = new System.Windows.Forms.TextBox();
+ this.label10 = new System.Windows.Forms.Label();
+ this.groupBox3 = new System.Windows.Forms.GroupBox();
+ this.label12 = new System.Windows.Forms.Label();
+ this.label13 = new System.Windows.Forms.Label();
+ this.textBoxManagedName = new System.Windows.Forms.TextBox();
+ this.textBoxManagedVersion = new System.Windows.Forms.TextBox();
+ this.textBoxManagedRuntime = new System.Windows.Forms.TextBox();
+ this.label14 = new System.Windows.Forms.Label();
+ this.textBoxManagedClassName = new System.Windows.Forms.TextBox();
+ this.label16 = new System.Windows.Forms.Label();
+ this.textBoxManagedSecurity = new System.Windows.Forms.TextBox();
+ this.label4 = new System.Windows.Forms.Label();
+ this.groupBox4 = new System.Windows.Forms.GroupBox();
+ this.textBoxSharpShellVersion = new System.Windows.Forms.TextBox();
+ this.textBoxSharpShellServerType = new System.Windows.Forms.TextBox();
+ this.label20 = new System.Windows.Forms.Label();
+ this.label21 = new System.Windows.Forms.Label();
+ this.groupBox1.SuspendLayout();
+ this.groupBox2.SuspendLayout();
+ this.groupBoxRegistration.SuspendLayout();
+ this.groupBox3.SuspendLayout();
+ this.groupBox4.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // label5
+ //
+ this.label5.AutoSize = true;
+ this.label5.Location = new System.Drawing.Point(18, 33);
+ this.label5.Name = "label5";
+ this.label5.Size = new System.Drawing.Size(68, 13);
+ this.label5.TabIndex = 0;
+ this.label5.Text = "32 Bit Server";
+ //
+ // textBox32BitServerInstallation
+ //
+ this.textBox32BitServerInstallation.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBox32BitServerInstallation.Location = new System.Drawing.Point(120, 30);
+ this.textBox32BitServerInstallation.Multiline = true;
+ this.textBox32BitServerInstallation.Name = "textBox32BitServerInstallation";
+ this.textBox32BitServerInstallation.ReadOnly = true;
+ this.textBox32BitServerInstallation.Size = new System.Drawing.Size(250, 46);
+ this.textBox32BitServerInstallation.TabIndex = 1;
+ //
+ // textBox64BitServerInstallation
+ //
+ this.textBox64BitServerInstallation.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBox64BitServerInstallation.Location = new System.Drawing.Point(120, 82);
+ this.textBox64BitServerInstallation.Multiline = true;
+ this.textBox64BitServerInstallation.Name = "textBox64BitServerInstallation";
+ this.textBox64BitServerInstallation.ReadOnly = true;
+ this.textBox64BitServerInstallation.Size = new System.Drawing.Size(250, 46);
+ this.textBox64BitServerInstallation.TabIndex = 3;
+ //
+ // label7
+ //
+ this.label7.AutoSize = true;
+ this.label7.Location = new System.Drawing.Point(18, 85);
+ this.label7.Name = "label7";
+ this.label7.Size = new System.Drawing.Size(68, 13);
+ this.label7.TabIndex = 2;
+ this.label7.Text = "64 Bit Server";
+ //
+ // groupBox1
+ //
+ this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.groupBox1.Controls.Add(this.textBoxAssociations);
+ this.groupBox1.Controls.Add(this.label8);
+ this.groupBox1.Controls.Add(this.textBoxServerPath);
+ this.groupBox1.Controls.Add(this.label6);
+ this.groupBox1.Controls.Add(this.textBoxServerClassId);
+ this.groupBox1.Controls.Add(this.textBoxExntensionTypes);
+ this.groupBox1.Controls.Add(this.textBoxServerName);
+ this.groupBox1.Controls.Add(this.label3);
+ this.groupBox1.Controls.Add(this.label2);
+ this.groupBox1.Controls.Add(this.label1);
+ this.groupBox1.Location = new System.Drawing.Point(3, 3);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(376, 240);
+ this.groupBox1.TabIndex = 0;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "Shell Extension";
+ //
+ // textBoxAssociations
+ //
+ this.textBoxAssociations.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxAssociations.Location = new System.Drawing.Point(120, 187);
+ this.textBoxAssociations.Multiline = true;
+ this.textBoxAssociations.Name = "textBoxAssociations";
+ this.textBoxAssociations.ReadOnly = true;
+ this.textBoxAssociations.Size = new System.Drawing.Size(250, 46);
+ this.textBoxAssociations.TabIndex = 11;
+ //
+ // label8
+ //
+ this.label8.AutoSize = true;
+ this.label8.Location = new System.Drawing.Point(18, 190);
+ this.label8.Name = "label8";
+ this.label8.Size = new System.Drawing.Size(66, 13);
+ this.label8.TabIndex = 10;
+ this.label8.Text = "Associations";
+ //
+ // textBoxServerPath
+ //
+ this.textBoxServerPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxServerPath.Location = new System.Drawing.Point(120, 83);
+ this.textBoxServerPath.Multiline = true;
+ this.textBoxServerPath.Name = "textBoxServerPath";
+ this.textBoxServerPath.ReadOnly = true;
+ this.textBoxServerPath.Size = new System.Drawing.Size(250, 46);
+ this.textBoxServerPath.TabIndex = 9;
+ //
+ // label6
+ //
+ this.label6.AutoSize = true;
+ this.label6.Location = new System.Drawing.Point(18, 86);
+ this.label6.Name = "label6";
+ this.label6.Size = new System.Drawing.Size(29, 13);
+ this.label6.TabIndex = 8;
+ this.label6.Text = "Path";
+ //
+ // textBoxServerClassId
+ //
+ this.textBoxServerClassId.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxServerClassId.Location = new System.Drawing.Point(120, 57);
+ this.textBoxServerClassId.Name = "textBoxServerClassId";
+ this.textBoxServerClassId.ReadOnly = true;
+ this.textBoxServerClassId.Size = new System.Drawing.Size(250, 20);
+ this.textBoxServerClassId.TabIndex = 5;
+ //
+ // textBoxExntensionTypes
+ //
+ this.textBoxExntensionTypes.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxExntensionTypes.Location = new System.Drawing.Point(120, 135);
+ this.textBoxExntensionTypes.Multiline = true;
+ this.textBoxExntensionTypes.Name = "textBoxExntensionTypes";
+ this.textBoxExntensionTypes.ReadOnly = true;
+ this.textBoxExntensionTypes.Size = new System.Drawing.Size(250, 46);
+ this.textBoxExntensionTypes.TabIndex = 3;
+ //
+ // textBoxServerName
+ //
+ this.textBoxServerName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxServerName.Location = new System.Drawing.Point(120, 31);
+ this.textBoxServerName.Name = "textBoxServerName";
+ this.textBoxServerName.ReadOnly = true;
+ this.textBoxServerName.Size = new System.Drawing.Size(250, 20);
+ this.textBoxServerName.TabIndex = 1;
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(18, 60);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(44, 13);
+ this.label3.TabIndex = 4;
+ this.label3.Text = "Class Id";
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(18, 138);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(85, 13);
+ this.label2.TabIndex = 2;
+ this.label2.Text = "Extension Types";
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(18, 34);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(35, 13);
+ this.label1.TabIndex = 0;
+ this.label1.Text = "Name";
+ //
+ // groupBox2
+ //
+ this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.groupBox2.Controls.Add(this.textBox32BitServerInstallation);
+ this.groupBox2.Controls.Add(this.label5);
+ this.groupBox2.Controls.Add(this.textBox64BitServerInstallation);
+ this.groupBox2.Controls.Add(this.label7);
+ this.groupBox2.Location = new System.Drawing.Point(3, 509);
+ this.groupBox2.Name = "groupBox2";
+ this.groupBox2.Size = new System.Drawing.Size(376, 138);
+ this.groupBox2.TabIndex = 1;
+ this.groupBox2.TabStop = false;
+ this.groupBox2.Text = "Installation";
+ //
+ // groupBoxRegistration
+ //
+ this.groupBoxRegistration.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.groupBoxRegistration.Controls.Add(this.textBox32BitServerRegistration);
+ this.groupBoxRegistration.Controls.Add(this.label9);
+ this.groupBoxRegistration.Controls.Add(this.textBox64BitServerRegistration);
+ this.groupBoxRegistration.Controls.Add(this.label10);
+ this.groupBoxRegistration.Location = new System.Drawing.Point(3, 653);
+ this.groupBoxRegistration.Name = "groupBoxRegistration";
+ this.groupBoxRegistration.Size = new System.Drawing.Size(376, 87);
+ this.groupBoxRegistration.TabIndex = 2;
+ this.groupBoxRegistration.TabStop = false;
+ this.groupBoxRegistration.Text = "Registration";
+ //
+ // textBox32BitServerRegistration
+ //
+ this.textBox32BitServerRegistration.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBox32BitServerRegistration.Location = new System.Drawing.Point(120, 30);
+ this.textBox32BitServerRegistration.Name = "textBox32BitServerRegistration";
+ this.textBox32BitServerRegistration.ReadOnly = true;
+ this.textBox32BitServerRegistration.Size = new System.Drawing.Size(250, 20);
+ this.textBox32BitServerRegistration.TabIndex = 1;
+ //
+ // label9
+ //
+ this.label9.AutoSize = true;
+ this.label9.Location = new System.Drawing.Point(18, 33);
+ this.label9.Name = "label9";
+ this.label9.Size = new System.Drawing.Size(68, 13);
+ this.label9.TabIndex = 0;
+ this.label9.Text = "32 Bit Server";
+ //
+ // textBox64BitServerRegistration
+ //
+ this.textBox64BitServerRegistration.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBox64BitServerRegistration.Location = new System.Drawing.Point(120, 56);
+ this.textBox64BitServerRegistration.Name = "textBox64BitServerRegistration";
+ this.textBox64BitServerRegistration.ReadOnly = true;
+ this.textBox64BitServerRegistration.Size = new System.Drawing.Size(250, 20);
+ this.textBox64BitServerRegistration.TabIndex = 3;
+ //
+ // label10
+ //
+ this.label10.AutoSize = true;
+ this.label10.Location = new System.Drawing.Point(18, 59);
+ this.label10.Name = "label10";
+ this.label10.Size = new System.Drawing.Size(68, 13);
+ this.label10.TabIndex = 2;
+ this.label10.Text = "64 Bit Server";
+ //
+ // groupBox3
+ //
+ this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.groupBox3.Controls.Add(this.textBoxManagedSecurity);
+ this.groupBox3.Controls.Add(this.label4);
+ this.groupBox3.Controls.Add(this.textBoxManagedClassName);
+ this.groupBox3.Controls.Add(this.label16);
+ this.groupBox3.Controls.Add(this.textBoxManagedRuntime);
+ this.groupBox3.Controls.Add(this.label14);
+ this.groupBox3.Controls.Add(this.textBoxManagedVersion);
+ this.groupBox3.Controls.Add(this.textBoxManagedName);
+ this.groupBox3.Controls.Add(this.label12);
+ this.groupBox3.Controls.Add(this.label13);
+ this.groupBox3.Location = new System.Drawing.Point(3, 249);
+ this.groupBox3.Name = "groupBox3";
+ this.groupBox3.Size = new System.Drawing.Size(376, 161);
+ this.groupBox3.TabIndex = 4;
+ this.groupBox3.TabStop = false;
+ this.groupBox3.Text = "Managed Server";
+ //
+ // label12
+ //
+ this.label12.AutoSize = true;
+ this.label12.Location = new System.Drawing.Point(18, 33);
+ this.label12.Name = "label12";
+ this.label12.Size = new System.Drawing.Size(35, 13);
+ this.label12.TabIndex = 0;
+ this.label12.Text = "Name";
+ //
+ // label13
+ //
+ this.label13.AutoSize = true;
+ this.label13.Location = new System.Drawing.Point(18, 59);
+ this.label13.Name = "label13";
+ this.label13.Size = new System.Drawing.Size(42, 13);
+ this.label13.TabIndex = 2;
+ this.label13.Text = "Version";
+ //
+ // textBoxManagedDisplayName
+ //
+ this.textBoxManagedName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxManagedName.Location = new System.Drawing.Point(120, 30);
+ this.textBoxManagedName.Name = "textBoxManagedName";
+ this.textBoxManagedName.ReadOnly = true;
+ this.textBoxManagedName.Size = new System.Drawing.Size(250, 20);
+ this.textBoxManagedName.TabIndex = 14;
+ //
+ // textBoxManagedVersion
+ //
+ this.textBoxManagedVersion.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxManagedVersion.Location = new System.Drawing.Point(120, 56);
+ this.textBoxManagedVersion.Name = "textBoxManagedVersion";
+ this.textBoxManagedVersion.ReadOnly = true;
+ this.textBoxManagedVersion.Size = new System.Drawing.Size(250, 20);
+ this.textBoxManagedVersion.TabIndex = 15;
+ //
+ // textBoxManagedRuntime
+ //
+ this.textBoxManagedRuntime.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxManagedRuntime.Location = new System.Drawing.Point(120, 82);
+ this.textBoxManagedRuntime.Name = "textBoxManagedRuntime";
+ this.textBoxManagedRuntime.ReadOnly = true;
+ this.textBoxManagedRuntime.Size = new System.Drawing.Size(250, 20);
+ this.textBoxManagedRuntime.TabIndex = 17;
+ //
+ // label14
+ //
+ this.label14.AutoSize = true;
+ this.label14.Location = new System.Drawing.Point(18, 85);
+ this.label14.Name = "label14";
+ this.label14.Size = new System.Drawing.Size(46, 13);
+ this.label14.TabIndex = 16;
+ this.label14.Text = "Runtime";
+ //
+ // textBoxManagedClassName
+ //
+ this.textBoxManagedClassName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxManagedClassName.Location = new System.Drawing.Point(120, 108);
+ this.textBoxManagedClassName.Name = "textBoxManagedClassName";
+ this.textBoxManagedClassName.ReadOnly = true;
+ this.textBoxManagedClassName.Size = new System.Drawing.Size(250, 20);
+ this.textBoxManagedClassName.TabIndex = 21;
+ //
+ // label16
+ //
+ this.label16.AutoSize = true;
+ this.label16.Location = new System.Drawing.Point(18, 111);
+ this.label16.Name = "label16";
+ this.label16.Size = new System.Drawing.Size(63, 13);
+ this.label16.TabIndex = 20;
+ this.label16.Text = "Class Name";
+ //
+ // textBoxManagedSecurity
+ //
+ this.textBoxManagedSecurity.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxManagedSecurity.Location = new System.Drawing.Point(120, 134);
+ this.textBoxManagedSecurity.Name = "textBoxManagedSecurity";
+ this.textBoxManagedSecurity.ReadOnly = true;
+ this.textBoxManagedSecurity.Size = new System.Drawing.Size(250, 20);
+ this.textBoxManagedSecurity.TabIndex = 9;
+ //
+ // label4
+ //
+ this.label4.AutoSize = true;
+ this.label4.Location = new System.Drawing.Point(18, 137);
+ this.label4.Name = "label4";
+ this.label4.Size = new System.Drawing.Size(45, 13);
+ this.label4.TabIndex = 8;
+ this.label4.Text = "Security";
+ //
+ // groupBox4
+ //
+ this.groupBox4.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.groupBox4.Controls.Add(this.textBoxSharpShellVersion);
+ this.groupBox4.Controls.Add(this.textBoxSharpShellServerType);
+ this.groupBox4.Controls.Add(this.label20);
+ this.groupBox4.Controls.Add(this.label21);
+ this.groupBox4.Location = new System.Drawing.Point(3, 416);
+ this.groupBox4.Name = "groupBox4";
+ this.groupBox4.Size = new System.Drawing.Size(376, 87);
+ this.groupBox4.TabIndex = 22;
+ this.groupBox4.TabStop = false;
+ this.groupBox4.Text = "Sharp Shell Server";
+ //
+ // textBoxSharpShellVersion
+ //
+ this.textBoxSharpShellVersion.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxSharpShellVersion.Location = new System.Drawing.Point(120, 56);
+ this.textBoxSharpShellVersion.Name = "textBoxSharpShellVersion";
+ this.textBoxSharpShellVersion.ReadOnly = true;
+ this.textBoxSharpShellVersion.Size = new System.Drawing.Size(250, 20);
+ this.textBoxSharpShellVersion.TabIndex = 15;
+ //
+ // textBoxSharpShellServerType
+ //
+ this.textBoxSharpShellServerType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBoxSharpShellServerType.Location = new System.Drawing.Point(120, 30);
+ this.textBoxSharpShellServerType.Name = "textBoxSharpShellServerType";
+ this.textBoxSharpShellServerType.ReadOnly = true;
+ this.textBoxSharpShellServerType.Size = new System.Drawing.Size(250, 20);
+ this.textBoxSharpShellServerType.TabIndex = 14;
+ //
+ // label20
+ //
+ this.label20.AutoSize = true;
+ this.label20.Location = new System.Drawing.Point(18, 33);
+ this.label20.Name = "label20";
+ this.label20.Size = new System.Drawing.Size(65, 13);
+ this.label20.TabIndex = 0;
+ this.label20.Text = "Server Type";
+ //
+ // label21
+ //
+ this.label21.AutoSize = true;
+ this.label21.Location = new System.Drawing.Point(18, 59);
+ this.label21.Name = "label21";
+ this.label21.Size = new System.Drawing.Size(96, 13);
+ this.label21.TabIndex = 2;
+ this.label21.Text = "SharpShell Version";
+ //
+ // ServerDetailsView
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.AutoScroll = true;
+ this.Controls.Add(this.groupBox4);
+ this.Controls.Add(this.groupBox3);
+ this.Controls.Add(this.groupBoxRegistration);
+ this.Controls.Add(this.groupBox2);
+ this.Controls.Add(this.groupBox1);
+ this.Name = "ServerDetailsView";
+ this.Size = new System.Drawing.Size(382, 748);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.groupBox2.ResumeLayout(false);
+ this.groupBox2.PerformLayout();
+ this.groupBoxRegistration.ResumeLayout(false);
+ this.groupBoxRegistration.PerformLayout();
+ this.groupBox3.ResumeLayout(false);
+ this.groupBox3.PerformLayout();
+ this.groupBox4.ResumeLayout(false);
+ this.groupBox4.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label label5;
+ private System.Windows.Forms.TextBox textBox32BitServerInstallation;
+ private System.Windows.Forms.TextBox textBox64BitServerInstallation;
+ private System.Windows.Forms.Label label7;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.TextBox textBoxServerClassId;
+ private System.Windows.Forms.TextBox textBoxExntensionTypes;
+ private System.Windows.Forms.TextBox textBoxServerName;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.GroupBox groupBox2;
+ private System.Windows.Forms.TextBox textBoxServerPath;
+ private System.Windows.Forms.Label label6;
+ private System.Windows.Forms.TextBox textBoxAssociations;
+ private System.Windows.Forms.Label label8;
+ private System.Windows.Forms.GroupBox groupBoxRegistration;
+ private System.Windows.Forms.TextBox textBox32BitServerRegistration;
+ private System.Windows.Forms.Label label9;
+ private System.Windows.Forms.TextBox textBox64BitServerRegistration;
+ private System.Windows.Forms.Label label10;
+ private System.Windows.Forms.GroupBox groupBox3;
+ private System.Windows.Forms.Label label12;
+ private System.Windows.Forms.Label label13;
+ private System.Windows.Forms.TextBox textBoxManagedRuntime;
+ private System.Windows.Forms.Label label14;
+ private System.Windows.Forms.TextBox textBoxManagedVersion;
+ private System.Windows.Forms.TextBox textBoxManagedName;
+ private System.Windows.Forms.TextBox textBoxManagedClassName;
+ private System.Windows.Forms.Label label16;
+ private System.Windows.Forms.TextBox textBoxManagedSecurity;
+ private System.Windows.Forms.Label label4;
+ private System.Windows.Forms.GroupBox groupBox4;
+ private System.Windows.Forms.TextBox textBoxSharpShellVersion;
+ private System.Windows.Forms.TextBox textBoxSharpShellServerType;
+ private System.Windows.Forms.Label label20;
+ private System.Windows.Forms.Label label21;
+ }
+}
diff --git a/SharpShell/Tools/ServerManager/Views/ServerDetailsView.cs b/SharpShell/Tools/ServerManager/Views/ServerDetailsView.cs
new file mode 100644
index 00000000..fcf4de69
--- /dev/null
+++ b/SharpShell/Tools/ServerManager/Views/ServerDetailsView.cs
@@ -0,0 +1,151 @@
+using System.ComponentModel;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace ServerManager.Views
+{
+ internal partial class ServerDetailsView : UserControl
+ {
+
+ public ServerDetailsView()
+ {
+ InitializeComponent();
+ }
+ private ShellExtensionEntry _extensionEntry;
+
+ public ShellExtensionEntry ExtensionEntry
+ {
+ get => _extensionEntry;
+ set
+ {
+ if (!ReferenceEquals(_extensionEntry, value))
+ {
+ if (_extensionEntry != null)
+ {
+ _extensionEntry.PropertyChanged -= ExtensionEntryOnPropertyChanged;
+ }
+
+ _extensionEntry = value;
+
+ if (_extensionEntry != null)
+ {
+ _extensionEntry.PropertyChanged += ExtensionEntryOnPropertyChanged;
+ }
+ }
+
+ UpdateUI();
+ }
+ }
+
+ private void ExtensionEntryOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
+ {
+ UpdateUI();
+ }
+
+ private void UpdateUI()
+ {
+ // Setting default values for text boxes
+ textBoxServerName.Text = @"[N/A]";
+ textBoxServerClassId.Text = @"[N/A]";
+ textBoxServerPath.Text = @"[N/A]";
+ textBoxExntensionTypes.Text = @"[N/A]";
+ textBoxAssociations.Text = @"[N/A]";
+
+ textBoxManagedName.Text = @"[N/A]";
+ textBoxManagedVersion.Text = @"[N/A]";
+ textBoxManagedRuntime.Text = @"[N/A]";
+ textBoxManagedClassName.Text = @"[N/A]";
+ textBoxManagedSecurity.Text = @"[N/A]";
+
+ textBoxSharpShellServerType.Text = @"[N/A]";
+ textBoxSharpShellVersion.Text = @"[N/A]";
+
+ textBox32BitServerInstallation.Text = @"[Not Installed]";
+ textBox64BitServerInstallation.Text = @"[Not Installed]";
+
+ textBox32BitServerRegistration.Text = @"[Not Registered]";
+ textBox64BitServerRegistration.Text = @"[Not Registered]";
+
+ if (ExtensionEntry != null)
+ {
+ // General information
+ textBoxServerName.Text = ExtensionEntry.ServerDisplayName;
+ textBoxServerClassId.Text = ExtensionEntry.ServerClassId.ToString("B");
+ textBoxServerPath.Text = ExtensionEntry.ServerPath;
+ textBoxAssociations.Text = string.Join(", ", ExtensionEntry.ShellAssociatedClassNames);
+ textBoxExntensionTypes.Text = string.Join(", ", ExtensionEntry.ShellExtensionTypes.Select(type => type.ToString()));
+
+ // Managed information
+ if (ExtensionEntry.SharpShellServerInfo != null)
+ {
+ textBoxManagedName.Text = ExtensionEntry.SharpShellServerInfo?.AssemblyInfo.FullName;
+ textBoxManagedVersion.Text = ExtensionEntry.SharpShellServerInfo.AssemblyInfo.Version;
+ textBoxManagedRuntime.Text = ExtensionEntry.SharpShellServerInfo.AssemblyInfo.RuntimeVersion;
+ textBoxManagedClassName.Text = ExtensionEntry.SharpShellServerInfo.ClassFullName;
+ textBoxManagedSecurity.Text = ExtensionEntry.SharpShellServerInfo.AssemblyInfo.IsSigned
+ ? "Signed"
+ : "Unsigned";
+
+ textBoxSharpShellServerType.Text = ExtensionEntry.SharpShellServerInfo.ServerType.ToString();
+ if (ExtensionEntry.SharpShellServerInfo.SharpShellAssemblyInfo != null)
+ {
+ textBoxSharpShellVersion.Text =
+ ExtensionEntry.SharpShellServerInfo.SharpShellAssemblyInfo.Version;
+ }
+ }
+
+ // Do we have 32 bit registration info?
+ if (ExtensionEntry.InstallationInfo32 != null)
+ {
+ // Do we have a codebase?
+ if (!string.IsNullOrEmpty(ExtensionEntry.InstallationInfo32?.ManagedAssembly?.AssemblyPath))
+ {
+ textBox32BitServerInstallation.Text = ExtensionEntry.InstallationInfo32.ManagedAssembly.AssemblyPath;
+ }
+ else if (!string.IsNullOrEmpty(ExtensionEntry.InstallationInfo32?.ManagedAssembly?.FullName))
+ {
+ textBox32BitServerInstallation.Text = ExtensionEntry.InstallationInfo32.ManagedAssembly.FullName + @" (GAC)";
+ }
+ else if (!string.IsNullOrEmpty(ExtensionEntry.InstallationInfo32?.ServerPath))
+ {
+ textBox32BitServerInstallation.Text = ExtensionEntry.InstallationInfo32.ServerPath + @" (Native)";
+ }
+ }
+
+ // Do we have 64 bit registration info?
+ if (ExtensionEntry.InstallationInfo64 != null)
+ {
+ // Do we have a codebase?
+ if (!string.IsNullOrEmpty(ExtensionEntry.InstallationInfo64?.ManagedAssembly?.AssemblyPath))
+ {
+ textBox64BitServerInstallation.Text = ExtensionEntry.InstallationInfo64.ManagedAssembly?.AssemblyPath;
+ }
+ else if (!string.IsNullOrEmpty(ExtensionEntry.InstallationInfo64?.ManagedAssembly?.FullName))
+ {
+ textBox64BitServerInstallation.Text = ExtensionEntry.InstallationInfo64.ManagedAssembly?.FullName + @" (GAC)";
+ }
+ else if (!string.IsNullOrEmpty(ExtensionEntry.InstallationInfo64?.ServerPath))
+ {
+ textBox64BitServerInstallation.Text = ExtensionEntry.InstallationInfo64.ServerPath + @" (Native)";
+ }
+ }
+
+ // Set the registration info.
+ if (ExtensionEntry.RegistrationInfo32?.Associations.Any() == true)
+ {
+ textBox32BitServerRegistration.Text = ExtensionEntry.RegistrationInfo32.IsApproved
+ ? @"Registered and Approved"
+ : @"Registered";
+ }
+
+ // Set the registration info.
+ if (ExtensionEntry.RegistrationInfo64?.Associations.Any() == true)
+ {
+ textBox64BitServerRegistration.Text = ExtensionEntry.RegistrationInfo64.IsApproved
+ ? @"Registered and Approved"
+ : @"Registered";
+ }
+ }
+ }
+ }
+}
diff --git a/SharpShell/Tools/ServerManager/ServerDetails/ServerDetailsView.resx b/SharpShell/Tools/ServerManager/Views/ServerDetailsView.resx
similarity index 100%
rename from SharpShell/Tools/ServerManager/ServerDetails/ServerDetailsView.resx
rename to SharpShell/Tools/ServerManager/Views/ServerDetailsView.resx
diff --git a/SharpShell/Tools/ServerManager/Views/ServerListViewItem.cs b/SharpShell/Tools/ServerManager/Views/ServerListViewItem.cs
new file mode 100644
index 00000000..466e031f
--- /dev/null
+++ b/SharpShell/Tools/ServerManager/Views/ServerListViewItem.cs
@@ -0,0 +1,121 @@
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using SharpShell;
+using SharpShell.ServerRegistration;
+
+namespace ServerManager.Views
+{
+ internal class ServerListViewItem : ListViewItem
+ {
+ private ShellExtensionEntry _extensionEntry;
+
+ public ServerListViewItem(ShellExtensionEntry extensionEntry)
+ {
+ ExtensionEntry = extensionEntry;
+ }
+
+ public ServerListViewItem()
+ {
+ }
+
+ public ShellExtensionEntry ExtensionEntry
+ {
+ get => _extensionEntry;
+ set
+ {
+ if (!ReferenceEquals(_extensionEntry, value))
+ {
+ if (_extensionEntry != null)
+ {
+ _extensionEntry.PropertyChanged -= ExtensionEntryOnPropertyChanged;
+ }
+
+ _extensionEntry = value;
+
+ if (_extensionEntry != null)
+ {
+ _extensionEntry.PropertyChanged += ExtensionEntryOnPropertyChanged;
+ }
+ }
+
+ UpdateUI();
+ }
+ }
+
+ private void ExtensionEntryOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
+ {
+ UpdateUI();
+ }
+
+ private void UpdateUI()
+ {
+ SubItems.Clear();
+
+ if (ExtensionEntry != null)
+ {
+ Text = ExtensionEntry.ServerDisplayName;
+ SubItems.Add(string.Join(", ", ExtensionEntry.ShellExtensionTypes.Select(type => type.ToString())));
+ SubItems.Add(ExtensionEntry.ServerClassId.ToString("B"));
+
+ if (ExtensionEntry.ShellExtensionTypes.Contains(ShellExtensionType.ShellContextMenu))
+ {
+ ImageIndex = 0;
+ }
+ else if (ExtensionEntry.ShellExtensionTypes.Contains(ShellExtensionType.ShellIconHandler))
+ {
+ ImageIndex = 1;
+ }
+ else if (ExtensionEntry.ShellExtensionTypes.Contains(ShellExtensionType.ShellPropertySheet))
+ {
+ ImageIndex = 2;
+ }
+ else if (ExtensionEntry.ShellExtensionTypes.Contains(ShellExtensionType.ShellInfoTipHandler))
+ {
+ ImageIndex = 3;
+ }
+ else if (ExtensionEntry.SharpShellServerInfo?.ServerType == ServerType.ShellIconOverlayHandler)
+ {
+ ImageIndex = 4;
+ }
+ else
+ {
+ ImageIndex = 0;
+ }
+
+ if (ExtensionEntry.SharpShellServerInfo != null)
+ {
+ BackColor = Color.FromArgb(221, 242, 255);
+ }
+ else
+ {
+ BackColor = Color.White;
+ }
+
+ if (ExtensionEntry.InstallationInfo32 == null &&
+ ExtensionEntry.InstallationInfo64 == null &&
+ ExtensionEntry.RegistrationInfo32 == null &&
+ ExtensionEntry.RegistrationInfo64 == null)
+ {
+ ForeColor = Color.FromArgb(217, 0, 0);
+ }
+ else if (ExtensionEntry.InstallationInfo32 == null && ExtensionEntry.InstallationInfo64 == null ||
+ ExtensionEntry.RegistrationInfo32 == null && ExtensionEntry.RegistrationInfo64 == null)
+ {
+ ForeColor = Color.FromArgb(116, 91, 0);
+ }
+ else
+ {
+ ForeColor = Color.Black;
+ }
+ }
+ else
+ {
+ Text = @"[N/A]";
+ SubItems.Add(@"[N/A]");
+ SubItems.Add(@"[N/A]");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/SharpShell/Tools/ServerManager/app.config b/SharpShell/Tools/ServerManager/app.config
new file mode 100644
index 00000000..2a0024f7
--- /dev/null
+++ b/SharpShell/Tools/ServerManager/app.config
@@ -0,0 +1,3 @@
+
+
+
diff --git a/SharpShell/Tools/ServerRegistrationManager/Application.cs b/SharpShell/Tools/ServerRegistrationManager/Application.cs
index 8ab725ec..e218a172 100644
--- a/SharpShell/Tools/ServerRegistrationManager/Application.cs
+++ b/SharpShell/Tools/ServerRegistrationManager/Application.cs
@@ -3,6 +3,7 @@
using System.Linq;
using ServerRegistrationManager.Actions;
using ServerRegistrationManager.OutputService;
+using SharpShell;
using SharpShell.Diagnostics;
using SharpShell.Helpers;
using SharpShell.ServerRegistration;
@@ -47,7 +48,7 @@ public void Run(string[] args)
}
// Get the architecture.
- var registrationType = Environment.Is64BitOperatingSystem ? RegistrationType.OS64Bit : RegistrationType.OS32Bit;
+ var registrationType = Environment.Is64BitOperatingSystem ? RegistrationScope.OS64Bit : RegistrationScope.OS32Bit;
// Get the verb, target and parameters.
var verb = args[0];
@@ -57,18 +58,27 @@ public void Run(string[] args)
//Allow user to override registrationType with -os32 or -os64
if (parameters.Any(p => p.Equals(ParameterOS32, StringComparison.InvariantCultureIgnoreCase)))
{
- registrationType = RegistrationType.OS32Bit;
+ registrationType = RegistrationScope.OS32Bit;
}
else if (parameters.Any(p => p.Equals(ParameterOS64, StringComparison.InvariantCultureIgnoreCase)))
{
- registrationType = RegistrationType.OS64Bit;
+ registrationType = RegistrationScope.OS64Bit;
}
+ var isExperimental = parameters.Any(p => p.Equals(ParameterExperimental, StringComparison.InvariantCultureIgnoreCase));
+ var codebase = parameters.Any(p => p.Equals(ParameterCodebase, StringComparison.InvariantCultureIgnoreCase));
+
// Based on the verb, perform the action.
if (verb == VerbInstall)
- InstallServer(target, registrationType, parameters.Any(p => p == ParameterCodebase));
+ if (isExperimental)
+ InstallServer(target, registrationType, codebase);
+ else
+ InstallServerViaRegAsm(target, registrationType, codebase);
else if (verb == VerbUninstall)
- UninstallServer(target, registrationType);
+ if (isExperimental)
+ UninstallServer(target, registrationType);
+ else
+ UninstallServerViaRegAsm(target, registrationType);
else if (verb == VerbConfig)
ConfigAction.Execute(outputService, parameters);
else if (verb == VerbEnableEventLog)
@@ -81,29 +91,85 @@ public void Run(string[] args)
/// Installs a SharpShell server at the specified path.
///
/// The path to the SharpShell server.
- /// Type of the registration.
+ /// Type of the registration.
/// if set to true install from codebase rather than GAC.
- private void InstallServer(string path, RegistrationType registrationType, bool codeBase)
+ private void InstallServer(string path, RegistrationScope registrationScope, bool codeBase)
{
// Validate the path.
- if (File.Exists(path) == false)
+ if (string.IsNullOrWhiteSpace(path) || File.Exists(path) == false)
{
outputService.WriteError("File '" + path + "' does not exist.", true);
return;
}
- var regasm = new RegAsm();
- var success = registrationType == RegistrationType.OS32Bit ? regasm.Register32(path, codeBase) : regasm.Register64(path, codeBase);
+ bool success = true;
+ try
+ {
+ // Load any servers from the assembly.
+ var servers = SharpShellServerInfo.FromExternalAssemblyFile(path);
+ foreach (var server in servers)
+ {
+ try
+ {
+ SharpShell.ServerRegistration.ServerRegistrationManager.InstallServer(server, registrationScope, codeBase);
+ SharpShell.ServerRegistration.ServerRegistrationManager.RegisterAndApproveServer(server, registrationScope);
+ }
+ catch (Exception e)
+ {
+ success = false;
+ outputService.WriteError(e.ToString());
+ outputService.WriteError($"Failed to install and register a server. [{server.DisplayName}]", true);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ success = false;
+ outputService.WriteError(e.ToString());
+ }
+
if (success)
{
outputService.WriteSuccess($" {path} installed and registered.", true);
- outputService.WriteMessage(regasm.StandardOutput);
}
else
{
outputService.WriteError($" {path} failed to register.", true);
- outputService.WriteError(regasm.StandardError);
+ }
+ }
+
+ ///
+ /// Installs a SharpShell server at the specified path via RegAsm.
+ ///
+ /// The path to the SharpShell server.
+ /// Type of the registration.
+ /// if set to true install from codebase rather than GAC.
+ private void InstallServerViaRegAsm(string path, RegistrationScope registrationScope, bool codeBase)
+ {
+ // Validate the path.
+ if (string.IsNullOrWhiteSpace(path) || File.Exists(path) == false)
+ {
+ outputService.WriteError("File '" + path + "' does not exist.", true);
+ return;
+ }
+
+ var regAsm = new RegAsm();
+
+ var success =
+ registrationScope == RegistrationScope.OS32Bit
+ ? regAsm.Register32(path, codeBase)
+ : regAsm.Register64(path, codeBase);
+
+ if (success)
+ {
+ outputService.WriteSuccess($" {path} installed and registered.", true);
+ outputService.WriteMessage(regAsm.StandardOutput);
+ }
+ else
+ {
+ outputService.WriteError($" {path} failed to register.", true);
+ outputService.WriteError(regAsm.StandardError);
}
}
@@ -111,21 +177,83 @@ private void InstallServer(string path, RegistrationType registrationType, bool
/// Uninstalls a SharpShell server located at 'path'.
///
/// The path to the SharpShell server.
- /// Type of the registration.
- private void UninstallServer(string path, RegistrationType registrationType)
+ /// Type of the registration.
+ private void UninstallServer(string path, RegistrationScope registrationScope)
{
- var regasm = new RegAsm();
- var success = registrationType == RegistrationType.OS32Bit ? regasm.Unregister32(path) : regasm.Unregister64(path);
+ // Validate the path.
+ if (string.IsNullOrWhiteSpace(path) || File.Exists(path) == false)
+ {
+ outputService.WriteError("File '" + path + "' does not exist.", true);
+ return;
+ }
+
+ bool success = true;
+ try
+ {
+ // Load any servers from the assembly.
+ var servers = SharpShellServerInfo.FromExternalAssemblyFile(path);
+
+ foreach (var server in servers)
+ {
+ try
+ {
+ SharpShell.ServerRegistration.ServerRegistrationManager.UninstallServer(server, registrationScope);
+ SharpShell.ServerRegistration.ServerRegistrationManager.UnregisterAndUnApproveServer(server, registrationScope);
+ }
+ catch (Exception e)
+ {
+ success = false;
+ outputService.WriteError(e.ToString());
+ outputService.WriteError($"Failed to uninstall and unregister a server. [{server.DisplayName}]", true);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ success = false;
+ outputService.WriteError(e.ToString());
+ }
if (success)
{
outputService.WriteSuccess($" {path} uninstalled.", true);
- outputService.WriteMessage(regasm.StandardOutput);
}
else
{
outputService.WriteError($" {path} failed to uninstall.", true);
- outputService.WriteError(regasm.StandardError);
+ }
+ }
+
+ ///
+ /// Uninstalls a SharpShell server located at 'path' vis RegAsm.
+ ///
+ /// The path to the SharpShell server.
+ /// Type of the registration.
+ private void UninstallServerViaRegAsm(string path, RegistrationScope registrationScope)
+ {
+ // Validate the path.
+ if (string.IsNullOrWhiteSpace(path) || File.Exists(path) == false)
+ {
+ outputService.WriteError("File '" + path + "' does not exist.", true);
+ return;
+ }
+
+ var regAsm = new RegAsm();
+
+ var success =
+ registrationScope == RegistrationScope.OS32Bit
+ ? regAsm.Unregister32(path)
+ : regAsm.Unregister64(path);
+
+ if (success)
+ {
+ outputService.WriteSuccess($" {path} uninstalled.", true);
+ outputService.WriteMessage(regAsm.StandardOutput);
+ }
+ else
+ {
+ outputService.WriteError($" {path} failed to uninstall.", true);
+ outputService.WriteError(regAsm.StandardError);
}
}
@@ -151,5 +279,7 @@ private void ShowWelcome()
private const string ParameterOS32 = @"-os32";
private const string ParameterOS64 = @"-os64";
+
+ private const string ParameterExperimental = @"-experimental";
}
}
diff --git a/SharpShell/Tools/ServerRegistrationManager/ServerRegistrationManager.csproj b/SharpShell/Tools/ServerRegistrationManager/ServerRegistrationManager.csproj
index 276ab6e0..f55c5a51 100644
--- a/SharpShell/Tools/ServerRegistrationManager/ServerRegistrationManager.csproj
+++ b/SharpShell/Tools/ServerRegistrationManager/ServerRegistrationManager.csproj
@@ -29,6 +29,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
AnyCPU
@@ -38,6 +39,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Tools/ShellExtensionManager/ShellExtensionManager.csproj b/SharpShell/Tools/ShellExtensionManager/ShellExtensionManager.csproj
index 75b1bdc5..b4cd1108 100644
--- a/SharpShell/Tools/ShellExtensionManager/ShellExtensionManager.csproj
+++ b/SharpShell/Tools/ShellExtensionManager/ShellExtensionManager.csproj
@@ -35,6 +35,7 @@
DEBUG;TRACE
prompt
4
+ 7.3
x86
@@ -44,6 +45,7 @@
TRACE
prompt
4
+ 7.3
true
diff --git a/SharpShell/Tools/ShellExtensionManager/ShellExtensions/ExtensionViewModel.cs b/SharpShell/Tools/ShellExtensionManager/ShellExtensions/ExtensionViewModel.cs
index fa902ca6..5f1cb7ab 100644
--- a/SharpShell/Tools/ShellExtensionManager/ShellExtensions/ExtensionViewModel.cs
+++ b/SharpShell/Tools/ShellExtensionManager/ShellExtensions/ExtensionViewModel.cs
@@ -49,14 +49,14 @@ public ShellExtensionType ShellExtensionType
///
/// The ClassRegistrations observable collection.
///
- private readonly ObservableCollection ClassRegistrationsProperty =
- new ObservableCollection();
+ private readonly ObservableCollection ClassRegistrationsProperty =
+ new ObservableCollection();
///
/// Gets the ClassRegistrations observable collection.
///
/// The ClassRegistrations observable collection.
- public ObservableCollection ClassRegistrations
+ public ObservableCollection ClassRegistrations
{
get { return ClassRegistrationsProperty; }
}
diff --git a/SharpShell/Tools/ShellExtensionManager/ShellExtensions/ShellExtensionsViewModel.cs b/SharpShell/Tools/ShellExtensionManager/ShellExtensions/ShellExtensionsViewModel.cs
index e1934637..29391de5 100644
--- a/SharpShell/Tools/ShellExtensionManager/ShellExtensions/ShellExtensionsViewModel.cs
+++ b/SharpShell/Tools/ShellExtensionManager/ShellExtensions/ShellExtensionsViewModel.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Text;
+using System.Collections.ObjectModel;
using Apex.MVVM;
using SharpShell.ServerRegistration;
@@ -26,15 +22,23 @@ public ShellExtensionsViewModel()
private void DoRefreshExtensionsCommand(object parameter)
{
// Get all servers.
- var servers = ServerRegistrationManager.EnumerateExtensions(RegistrationType.OS64Bit, ShellExtensionType.IconHandler);
+ var servers = ServerRegistrationManager.EnumerateRegisteredExtensions(RegistrationScope.OS64Bit);
foreach (var server in servers)
{
- var extensionViewModel = new ExtensionViewModel();
- extensionViewModel.DisplayName = server.DisplayName;
- extensionViewModel.ShellExtensionType = server.ShellExtensionType;
- foreach (var classReg in server.ClassRegistrations)
- extensionViewModel.ClassRegistrations.Add(classReg);
- RefreshExtensionsCommand.ReportProgress(() => Extensions.Add(extensionViewModel));
+ var installation =
+ ServerRegistrationManager.GetExtensionInstallationInfo(server.ServerClassId,
+ RegistrationScope.OS64Bit);
+ var sharpServer = installation?.GetSharpShellServerInformation();
+
+ if (sharpServer != null)
+ {
+ var extensionViewModel = new ExtensionViewModel();
+ extensionViewModel.DisplayName = sharpServer.DisplayName;
+ extensionViewModel.ShellExtensionType = sharpServer.ShellExtensionType;
+ foreach (var classReg in server.Associations)
+ extensionViewModel.ClassRegistrations.Add(classReg);
+ RefreshExtensionsCommand.ReportProgress(() => Extensions.Add(extensionViewModel));
+ }
}
}
diff --git a/SharpShell/build.ps1 b/SharpShell/build.ps1
index 19f9384b..bda70770 100644
--- a/SharpShell/build.ps1
+++ b/SharpShell/build.ps1
@@ -1,7 +1,25 @@
+$agentPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\msbuild.exe"
+$devPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe"
+$proPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe"
+$communityPath = "${env:ProgramFiles(x86)}Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe"
+
+$msbuild = ""
+
+If (Test-Path $agentPath) {
+ $msbuild = $agentPath
+} ElseIf (Test-Path $devPath) {
+ $msbuild = $devPath
+} ElseIf (Test-Path $proPath) {
+ $msbuild = $proPath
+} ElseIf (Test-Path $communityPath) {
+ $msbuild = $communityPath
+} Else {
+ throw "Unable to find msbuild"
+}
+
# Run msbuild on the solution, in release mode.
-$msbuild ="${env:ProgramFiles(x86)}\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"
-$args = "SharpShell.sln /t:Rebuild /p:Configuration=Release"
+$args = "/p:Configuration=Release /t:Clean,Build SharpShell.sln"
# Run the command.
Write-Host "Running: ""$msbuild"" $args"
-& "$msbuild" /p:Configuration=Release /t:Clean,Build SharpShell.sln
\ No newline at end of file
+& "$msbuild" /p:Configuration=Release /t:Clean,Build SharpShell.sln