From c9b1a85282413cde666d1329298e9dce7ca4dfb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C4=8Dera?= Date: Sun, 22 Sep 2019 16:35:40 +0100 Subject: [PATCH 1/3] Add assembly search strategy --- ILSpy/ILSpy.csproj | 1 + ILSpy/Search/AssemblySearchStrategy.cs | 49 ++++++++++++++++++++++++++ ILSpy/Search/SearchPane.cs | 9 ++++- ILSpy/Search/SearchResult.cs | 9 +++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 ILSpy/Search/AssemblySearchStrategy.cs diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 072b2c3ea..d4edc73a3 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -168,6 +168,7 @@ Resources.resx + diff --git a/ILSpy/Search/AssemblySearchStrategy.cs b/ILSpy/Search/AssemblySearchStrategy.cs new file mode 100644 index 000000000..fc27fa905 --- /dev/null +++ b/ILSpy/Search/AssemblySearchStrategy.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +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 + { + public AssemblySearchStrategy(IProducerConsumerCollection resultQueue, string term) + : this(resultQueue, new[] { term }) + { + } + + public AssemblySearchStrategy(IProducerConsumerCollection resultQueue, string[] terms) + : base(resultQueue, terms) + { + } + + public override void Search(PEFile module, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + if (IsMatch(module.FullName)) + OnFoundResult(module); + } + + 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); + } + } +} diff --git a/ILSpy/Search/SearchPane.cs b/ILSpy/Search/SearchPane.cs index f911fd3a6..e4139836f 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,9 @@ 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(resultQueue, searchTerm[0].Substring(2)); } switch (searchMode) @@ -369,6 +373,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); } return null; @@ -400,6 +406,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 From b342dd6b117b8b406123f43d39fbdc398d0ee357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C4=8Dera?= Date: Mon, 23 Sep 2019 13:15:58 +0100 Subject: [PATCH 2/3] Assembly search kind, default to short name --- .../Metadata/MetadataExtensions.cs | 11 +++- ILSpy/Search/AssemblySearchStrategy.cs | 60 +++++++++++++++++-- ILSpy/Search/SearchPane.cs | 25 +++++++- 3 files changed, 89 insertions(+), 7 deletions(-) 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/Search/AssemblySearchStrategy.cs b/ILSpy/Search/AssemblySearchStrategy.cs index fc27fa905..6adaebfb1 100644 --- a/ILSpy/Search/AssemblySearchStrategy.cs +++ b/ILSpy/Search/AssemblySearchStrategy.cs @@ -3,6 +3,7 @@ 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; @@ -16,23 +17,62 @@ namespace ICSharpCode.ILSpy.Search { class AssemblySearchStrategy : AbstractSearchStrategy { - public AssemblySearchStrategy(IProducerConsumerCollection resultQueue, string term) - : this(resultQueue, new[] { term }) + readonly AssemblySearchKind searchKind; + + public AssemblySearchStrategy(string term, IProducerConsumerCollection resultQueue, AssemblySearchKind searchKind) + : this(resultQueue, new[] { term }, searchKind) { } - public AssemblySearchStrategy(IProducerConsumerCollection resultQueue, string[] terms) + 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 (IsMatch(module.FullName)) + string name = GetNameToMatch(module); + if (IsMatch(name)) OnFoundResult(module); } + string GetNameToMatch(PEFile module) + { + switch (searchKind) { + case AssemblySearchKind.FullName: + return module.FullName; + case AssemblySearchKind.Name: + return module.Name; + case AssemblySearchKind.FileName: + return module.FileName; + } + + if (!module.IsAssembly) + return null; + + var metadata = module.Metadata; + var definition = module.Metadata.GetAssemblyDefinition(); + + switch (searchKind) { + 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 { @@ -46,4 +86,16 @@ namespace ICSharpCode.ILSpy.Search OnFoundResult(result); } } + + enum AssemblySearchKind + { + Name, + FullName, + FileName, + Culture, + Version, + PublicKey, + HashAlgorithm, + Flags + } } diff --git a/ILSpy/Search/SearchPane.cs b/ILSpy/Search/SearchPane.cs index e4139836f..1b0aa24ac 100644 --- a/ILSpy/Search/SearchPane.cs +++ b/ILSpy/Search/SearchPane.cs @@ -348,7 +348,28 @@ namespace ICSharpCode.ILSpy return new ResourceSearchStrategy(apiVisibility, resultQueue, searchTerm[0].Substring(2)); if (searchTerm[0].StartsWith("a:", StringComparison.Ordinal)) - return new AssemblySearchStrategy(resultQueue, searchTerm[0].Substring(2)); + return new AssemblySearchStrategy(searchTerm[0].Substring(2), resultQueue, AssemblySearchKind.Name); + + if (searchTerm[0].StartsWith("afn:", StringComparison.Ordinal)) + return new AssemblySearchStrategy(searchTerm[0].Substring(4), resultQueue, AssemblySearchKind.FullName); + + if (searchTerm[0].StartsWith("af:", StringComparison.Ordinal)) + return new AssemblySearchStrategy(searchTerm[0].Substring(3), resultQueue, AssemblySearchKind.FileName); + + if (searchTerm[0].StartsWith("ac:", StringComparison.Ordinal)) + return new AssemblySearchStrategy(searchTerm[0].Substring(3), resultQueue, AssemblySearchKind.Culture); + + if (searchTerm[0].StartsWith("av:", StringComparison.Ordinal)) + return new AssemblySearchStrategy(searchTerm[0].Substring(3), resultQueue, AssemblySearchKind.Version); + + if (searchTerm[0].StartsWith("apk:", StringComparison.Ordinal)) + return new AssemblySearchStrategy(searchTerm[0].Substring(4), resultQueue, AssemblySearchKind.PublicKey); + + if (searchTerm[0].StartsWith("aha:", StringComparison.Ordinal)) + return new AssemblySearchStrategy(searchTerm[0].Substring(4), resultQueue, AssemblySearchKind.HashAlgorithm); + + if (searchTerm[0].StartsWith("afl:", StringComparison.Ordinal)) + return new AssemblySearchStrategy(searchTerm[0].Substring(4), resultQueue, AssemblySearchKind.Flags); } switch (searchMode) @@ -374,7 +395,7 @@ namespace ICSharpCode.ILSpy case SearchMode.Resource: return new ResourceSearchStrategy(apiVisibility, resultQueue, searchTerm); case SearchMode.Assembly: - return new AssemblySearchStrategy(resultQueue, searchTerm); + return new AssemblySearchStrategy(resultQueue, searchTerm, AssemblySearchKind.Name); } return null; From 5d4a4b81daa359020314899d650c096c36ecd847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C4=8Dera?= Date: Wed, 25 Sep 2019 11:46:55 +0100 Subject: [PATCH 3/3] Assembly search option limited to NameOrFileName, FullName and FilePath --- ILSpy/Search/AssemblySearchStrategy.cs | 22 ++++++++++++++++------ ILSpy/Search/SearchPane.cs | 25 +++++-------------------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/ILSpy/Search/AssemblySearchStrategy.cs b/ILSpy/Search/AssemblySearchStrategy.cs index 6adaebfb1..30859b3a2 100644 --- a/ILSpy/Search/AssemblySearchStrategy.cs +++ b/ILSpy/Search/AssemblySearchStrategy.cs @@ -33,19 +33,28 @@ namespace ICSharpCode.ILSpy.Search public override void Search(PEFile module, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - string name = GetNameToMatch(module); + + 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) + string GetNameToMatch(PEFile module, AssemblySearchKind kind) { - switch (searchKind) { + switch (kind) { case AssemblySearchKind.FullName: return module.FullName; case AssemblySearchKind.Name: return module.Name; - case AssemblySearchKind.FileName: + case AssemblySearchKind.FilePath: return module.FileName; } @@ -55,7 +64,7 @@ namespace ICSharpCode.ILSpy.Search var metadata = module.Metadata; var definition = module.Metadata.GetAssemblyDefinition(); - switch (searchKind) { + switch (kind) { case AssemblySearchKind.Culture: if (definition.Culture.IsNil) return "neutral"; @@ -89,9 +98,10 @@ namespace ICSharpCode.ILSpy.Search enum AssemblySearchKind { + NameOrFileName, Name, FullName, - FileName, + FilePath, Culture, Version, PublicKey, diff --git a/ILSpy/Search/SearchPane.cs b/ILSpy/Search/SearchPane.cs index 1b0aa24ac..bf2eda16c 100644 --- a/ILSpy/Search/SearchPane.cs +++ b/ILSpy/Search/SearchPane.cs @@ -348,28 +348,13 @@ namespace ICSharpCode.ILSpy 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.Name); - - if (searchTerm[0].StartsWith("afn:", StringComparison.Ordinal)) - return new AssemblySearchStrategy(searchTerm[0].Substring(4), resultQueue, AssemblySearchKind.FullName); + 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.FileName); - - if (searchTerm[0].StartsWith("ac:", StringComparison.Ordinal)) - return new AssemblySearchStrategy(searchTerm[0].Substring(3), resultQueue, AssemblySearchKind.Culture); - - if (searchTerm[0].StartsWith("av:", StringComparison.Ordinal)) - return new AssemblySearchStrategy(searchTerm[0].Substring(3), resultQueue, AssemblySearchKind.Version); - - if (searchTerm[0].StartsWith("apk:", StringComparison.Ordinal)) - return new AssemblySearchStrategy(searchTerm[0].Substring(4), resultQueue, AssemblySearchKind.PublicKey); - - if (searchTerm[0].StartsWith("aha:", StringComparison.Ordinal)) - return new AssemblySearchStrategy(searchTerm[0].Substring(4), resultQueue, AssemblySearchKind.HashAlgorithm); + return new AssemblySearchStrategy(searchTerm[0].Substring(3), resultQueue, AssemblySearchKind.FilePath); - if (searchTerm[0].StartsWith("afl:", StringComparison.Ordinal)) - return new AssemblySearchStrategy(searchTerm[0].Substring(4), resultQueue, AssemblySearchKind.Flags); + if (searchTerm[0].StartsWith("an:", StringComparison.Ordinal)) + return new AssemblySearchStrategy(searchTerm[0].Substring(3), resultQueue, AssemblySearchKind.FullName); } switch (searchMode) @@ -395,7 +380,7 @@ namespace ICSharpCode.ILSpy case SearchMode.Resource: return new ResourceSearchStrategy(apiVisibility, resultQueue, searchTerm); case SearchMode.Assembly: - return new AssemblySearchStrategy(resultQueue, searchTerm, AssemblySearchKind.Name); + return new AssemblySearchStrategy(resultQueue, searchTerm, AssemblySearchKind.NameOrFileName); } return null;