diff --git a/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs b/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs
index 561c25704..7d9d2ca5b 100644
--- a/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs
+++ b/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs
@@ -49,7 +49,7 @@ namespace ICSharpCode.Decompiler.Metadata
return publicKeyTokenBytes.TakeLast(8).Reverse().ToHexString(8);
}
- public static string GetFullAssemblyName(this MetadataReader reader)
+ public static string GetPublicKeyToken(this MetadataReader reader)
{
if (!reader.IsAssembly)
return string.Empty;
@@ -59,6 +59,15 @@ namespace ICSharpCode.Decompiler.Metadata
// AssemblyFlags.PublicKey does not apply to assembly definitions
publicKey = CalculatePublicKeyToken(asm.PublicKey, reader);
}
+ return publicKey;
+ }
+
+ public static string GetFullAssemblyName(this MetadataReader reader)
+ {
+ if (!reader.IsAssembly)
+ return string.Empty;
+ var asm = reader.GetAssemblyDefinition();
+ string publicKey = reader.GetPublicKeyToken();
return $"{reader.GetString(asm.Name)}, " +
$"Version={asm.Version}, " +
$"Culture={(asm.Culture.IsNil ? "neutral" : reader.GetString(asm.Culture))}, " +
diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj
index 530547711..31e80a05d 100644
--- a/ILSpy/ILSpy.csproj
+++ b/ILSpy/ILSpy.csproj
@@ -172,6 +172,7 @@
Resources.resx
+
diff --git a/ILSpy/Search/AssemblySearchStrategy.cs b/ILSpy/Search/AssemblySearchStrategy.cs
new file mode 100644
index 000000000..30859b3a2
--- /dev/null
+++ b/ILSpy/Search/AssemblySearchStrategy.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Reflection.Metadata;
+using System.Threading;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using ICSharpCode.Decompiler.Metadata;
+using ICSharpCode.Decompiler.TypeSystem;
+using ICSharpCode.Decompiler.Util;
+using ICSharpCode.ILSpy.TreeNodes;
+using ICSharpCode.TreeView;
+
+namespace ICSharpCode.ILSpy.Search
+{
+ class AssemblySearchStrategy : AbstractSearchStrategy
+ {
+ readonly AssemblySearchKind searchKind;
+
+ public AssemblySearchStrategy(string term, IProducerConsumerCollection resultQueue, AssemblySearchKind searchKind)
+ : this(resultQueue, new[] { term }, searchKind)
+ {
+ }
+
+ public AssemblySearchStrategy(IProducerConsumerCollection resultQueue, string[] terms, AssemblySearchKind searchKind)
+ : base(resultQueue, terms)
+ {
+ this.searchKind = searchKind;
+ }
+
+ public override void Search(PEFile module, CancellationToken cancellationToken)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (searchKind == AssemblySearchKind.NameOrFileName) {
+ string localName = GetNameToMatch(module, AssemblySearchKind.Name);
+ string fileName = Path.GetFileName(GetNameToMatch(module, AssemblySearchKind.FilePath));
+ if (IsMatch(localName) || IsMatch(fileName))
+ OnFoundResult(module);
+ return;
+ }
+
+ string name = GetNameToMatch(module, searchKind);
+ if (IsMatch(name))
+ OnFoundResult(module);
+ }
+
+ string GetNameToMatch(PEFile module, AssemblySearchKind kind)
+ {
+ switch (kind) {
+ case AssemblySearchKind.FullName:
+ return module.FullName;
+ case AssemblySearchKind.Name:
+ return module.Name;
+ case AssemblySearchKind.FilePath:
+ return module.FileName;
+ }
+
+ if (!module.IsAssembly)
+ return null;
+
+ var metadata = module.Metadata;
+ var definition = module.Metadata.GetAssemblyDefinition();
+
+ switch (kind) {
+ case AssemblySearchKind.Culture:
+ if (definition.Culture.IsNil)
+ return "neutral";
+ return metadata.GetString(definition.Culture);
+ case AssemblySearchKind.Version:
+ return definition.Version.ToString();
+ case AssemblySearchKind.PublicKey:
+ return module.Metadata.GetPublicKeyToken();
+ case AssemblySearchKind.HashAlgorithm:
+ return definition.HashAlgorithm.ToString();
+ case AssemblySearchKind.Flags:
+ return definition.Flags.ToString();
+ }
+
+ return null;
+ }
+
+ void OnFoundResult(PEFile module)
+ {
+ var result = new AssemblySearchResult {
+ Module = module,
+ Fitness = 1.0f / module.Name.Length,
+ Name = module.Name,
+ Location = module.FileName,
+ Assembly = module.FullName,
+ ToolTip = module.FileName,
+ };
+ OnFoundResult(result);
+ }
+ }
+
+ enum AssemblySearchKind
+ {
+ NameOrFileName,
+ Name,
+ FullName,
+ FilePath,
+ Culture,
+ Version,
+ PublicKey,
+ HashAlgorithm,
+ Flags
+ }
+}
diff --git a/ILSpy/Search/SearchPane.cs b/ILSpy/Search/SearchPane.cs
index f1394239e..f2bbf7760 100644
--- a/ILSpy/Search/SearchPane.cs
+++ b/ILSpy/Search/SearchPane.cs
@@ -76,6 +76,7 @@ namespace ICSharpCode.ILSpy
searchModeComboBox.Items.Add(new { Image = Images.Literal, Name = "Constant" });
searchModeComboBox.Items.Add(new { Image = Images.Library, Name = "Metadata Token" });
searchModeComboBox.Items.Add(new { Image = Images.Resource, Name = "Resource" });
+ searchModeComboBox.Items.Add(new { Image = Images.Assembly, Name = "Assembly" });
ContextMenuProvider.Add(listBox);
MainWindow.Instance.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged;
@@ -345,6 +346,15 @@ namespace ICSharpCode.ILSpy
if (searchTerm[0].StartsWith("r:", StringComparison.Ordinal))
return new ResourceSearchStrategy(apiVisibility, resultQueue, searchTerm[0].Substring(2));
+
+ if (searchTerm[0].StartsWith("a:", StringComparison.Ordinal))
+ return new AssemblySearchStrategy(searchTerm[0].Substring(2), resultQueue, AssemblySearchKind.NameOrFileName);
+
+ if (searchTerm[0].StartsWith("af:", StringComparison.Ordinal))
+ return new AssemblySearchStrategy(searchTerm[0].Substring(3), resultQueue, AssemblySearchKind.FilePath);
+
+ if (searchTerm[0].StartsWith("an:", StringComparison.Ordinal))
+ return new AssemblySearchStrategy(searchTerm[0].Substring(3), resultQueue, AssemblySearchKind.FullName);
}
switch (searchMode)
@@ -369,6 +379,8 @@ namespace ICSharpCode.ILSpy
return new MetadataTokenSearchStrategy(language, apiVisibility, resultQueue, searchTerm);
case SearchMode.Resource:
return new ResourceSearchStrategy(apiVisibility, resultQueue, searchTerm);
+ case SearchMode.Assembly:
+ return new AssemblySearchStrategy(resultQueue, searchTerm, AssemblySearchKind.NameOrFileName);
}
return null;
@@ -400,6 +412,7 @@ namespace ICSharpCode.ILSpy
Event,
Literal,
Token,
- Resource
+ Resource,
+ Assembly
}
}
\ No newline at end of file
diff --git a/ILSpy/Search/SearchResult.cs b/ILSpy/Search/SearchResult.cs
index eb78c0bef..d632129f2 100644
--- a/ILSpy/Search/SearchResult.cs
+++ b/ILSpy/Search/SearchResult.cs
@@ -94,4 +94,13 @@ namespace ICSharpCode.ILSpy
public Resource Resource { get; set; }
public override object Reference => ValueTuple.Create(Resource, Name);
}
+
+ public class AssemblySearchResult : SearchResult
+ {
+ public PEFile Module { get; set; }
+ public override object Reference => Module;
+
+ public override ImageSource Image => Images.Assembly;
+ public override ImageSource LocationImage => Images.Library;
+ }
}
\ No newline at end of file