mirror of
https://github.com/dnSpy/dnSpy.git
synced 2025-01-07 03:16:51 +08:00
Rename files, classes, remove Core from .NET Core
This commit is contained in:
parent
e6221ed187
commit
45716aff73
@ -50,7 +50,7 @@
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)Build\ConvertToNetstandardReferences\ConvertToNetstandardReferences.tasks" Condition=" '$(IsDotNet)' == 'true' " />
|
||||
|
||||
<!-- .NET Core 3.0 SDK doesn't currently support COMReference: https://github.com/dnSpy/dnSpy/issues/1053 -->
|
||||
<!-- .NET 5.0 SDK doesn't currently support COMReference: https://github.com/dnSpy/dnSpy/issues/1053 -->
|
||||
<PropertyGroup>
|
||||
<HasCOMReference>false</HasCOMReference>
|
||||
<HasCOMReference Condition=" '$(MSBuildRuntimeType)' != 'Core' ">true</HasCOMReference>
|
||||
|
@ -28,12 +28,12 @@ using dnSpy.Debugger.DotNet.CorDebug.Impl.Attach;
|
||||
using dnSpy.Debugger.DotNet.CorDebug.Utilities;
|
||||
|
||||
namespace dnSpy.Debugger.DotNet.CorDebug.Dialogs.AttachToProcess {
|
||||
[ExportAttachProgramOptionsProviderFactory(PredefinedAttachProgramOptionsProviderNames.DotNetCore)]
|
||||
sealed class DotNetCoreAttachProgramOptionsProviderFactory : AttachProgramOptionsProviderFactory {
|
||||
public override AttachProgramOptionsProvider? Create(bool allFactories) => new DotNetCoreAttachProgramOptionsProvider();
|
||||
[ExportAttachProgramOptionsProviderFactory(PredefinedAttachProgramOptionsProviderNames.DotNet)]
|
||||
sealed class DotNetAttachProgramOptionsProviderFactory : AttachProgramOptionsProviderFactory {
|
||||
public override AttachProgramOptionsProvider? Create(bool allFactories) => new DotNetAttachProgramOptionsProvider();
|
||||
}
|
||||
|
||||
sealed class DotNetCoreAttachProgramOptionsProvider : AttachProgramOptionsProvider {
|
||||
sealed class DotNetAttachProgramOptionsProvider : AttachProgramOptionsProvider {
|
||||
public override IEnumerable<AttachProgramOptions> Create(AttachProgramOptionsProviderContext context) {
|
||||
foreach (var process in DebuggableProcesses.GetProcesses(context.ProcessIds, context.IsValidProcess, context.CancellationToken)) {
|
||||
foreach (var info in TryGetCoreCLRInfos(process)) {
|
||||
@ -43,34 +43,34 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Dialogs.AttachToProcess {
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<DotNetCoreAttachProgramOptions> TryGetCoreCLRInfos(Process process) {
|
||||
IEnumerable<DotNetAttachProgramOptions> TryGetCoreCLRInfos(Process process) {
|
||||
// We can only debug processes with the same bitness
|
||||
int bitness = IntPtr.Size * 8;
|
||||
var dbgShimFilename = DotNetCoreHelpers.GetDebugShimFilename(bitness);
|
||||
var dbgShimFilename = DotNetHelpers.GetDebugShimFilename(bitness);
|
||||
foreach (var ccInfo in CoreCLRHelper.GetCoreCLRInfos(process.Id, null, dbgShimFilename))
|
||||
yield return new DotNetCoreAttachProgramOptions(process.Id, ccInfo.CoreCLRTypeInfo.Version, ccInfo.CoreCLRTypeInfo.CoreCLRFilename);
|
||||
yield return new DotNetAttachProgramOptions(process.Id, ccInfo.CoreCLRTypeInfo.Version, ccInfo.CoreCLRTypeInfo.CoreCLRFilename);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class DotNetCoreAttachProgramOptions : AttachProgramOptions {
|
||||
sealed class DotNetAttachProgramOptions : AttachProgramOptions {
|
||||
public override int ProcessId { get; }
|
||||
public override RuntimeId RuntimeId { get; }
|
||||
public override string RuntimeName { get; }
|
||||
public override Guid RuntimeGuid => PredefinedDbgRuntimeGuids.DotNetCore_Guid;
|
||||
public override Guid RuntimeGuid => PredefinedDbgRuntimeGuids.DotNet_Guid;
|
||||
public override Guid RuntimeKindGuid => PredefinedDbgRuntimeKindGuids.DotNet_Guid;
|
||||
|
||||
readonly string? clrModuleVersion;
|
||||
readonly string? coreCLRFilename;
|
||||
|
||||
public DotNetCoreAttachProgramOptions(int pid, string? clrModuleVersion, string? coreCLRFilename) {
|
||||
public DotNetAttachProgramOptions(int pid, string? clrModuleVersion, string? coreCLRFilename) {
|
||||
ProcessId = pid;
|
||||
RuntimeId = new DotNetCoreRuntimeId(clrModuleVersion);
|
||||
RuntimeId = new DotNetRuntimeId(clrModuleVersion);
|
||||
RuntimeName = "CoreCLR " + clrModuleVersion;
|
||||
this.clrModuleVersion = clrModuleVersion;
|
||||
this.coreCLRFilename = coreCLRFilename;
|
||||
}
|
||||
|
||||
public override AttachToProgramOptions GetOptions() => new DotNetCoreAttachToProgramOptions {
|
||||
public override AttachToProgramOptions GetOptions() => new DotNetAttachToProgramOptions {
|
||||
ProcessId = ProcessId,
|
||||
ClrModuleVersion = clrModuleVersion,
|
||||
CoreCLRFilename = coreCLRFilename,
|
@ -0,0 +1,172 @@
|
||||
/*
|
||||
Copyright (C) 2014-2019 de4dot@gmail.com
|
||||
|
||||
This file is part of dnSpy
|
||||
|
||||
dnSpy is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
dnSpy is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with dnSpy. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Windows.Input;
|
||||
using dnSpy.Contracts.Debugger;
|
||||
using dnSpy.Contracts.Debugger.DotNet.CorDebug;
|
||||
using dnSpy.Contracts.Debugger.StartDebugging.Dialog;
|
||||
using dnSpy.Contracts.MVVM;
|
||||
using dnSpy.Debugger.DotNet.CorDebug.Properties;
|
||||
|
||||
namespace dnSpy.Debugger.DotNet.CorDebug.Dialogs.DebugProgram {
|
||||
abstract class DotNetCommonStartDebuggingOptionsPage : StartDebuggingOptionsPage, IDataErrorInfo {
|
||||
public override object? UIObject => this;
|
||||
|
||||
public string Filename {
|
||||
get => filename;
|
||||
set {
|
||||
if (filename != value) {
|
||||
filename = value;
|
||||
OnPropertyChanged(nameof(Filename));
|
||||
UpdateIsValid();
|
||||
var path = GetPath(filename);
|
||||
if (!(path is null))
|
||||
WorkingDirectory = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
string filename = string.Empty;
|
||||
|
||||
public string CommandLine {
|
||||
get => commandLine;
|
||||
set {
|
||||
if (commandLine != value) {
|
||||
commandLine = value;
|
||||
OnPropertyChanged(nameof(CommandLine));
|
||||
UpdateIsValid();
|
||||
}
|
||||
}
|
||||
}
|
||||
string commandLine = string.Empty;
|
||||
|
||||
public string WorkingDirectory {
|
||||
get => workingDirectory;
|
||||
set {
|
||||
if (workingDirectory != value) {
|
||||
workingDirectory = value;
|
||||
OnPropertyChanged(nameof(WorkingDirectory));
|
||||
UpdateIsValid();
|
||||
}
|
||||
}
|
||||
}
|
||||
string workingDirectory = string.Empty;
|
||||
|
||||
public ICommand PickFilenameCommand => new RelayCommand(a => PickNewFilename());
|
||||
public ICommand PickWorkingDirectoryCommand => new RelayCommand(a => PickNewWorkingDirectory());
|
||||
|
||||
public EnumListVM BreakProcessKindVM => breakProcessKindVM;
|
||||
readonly EnumListVM breakProcessKindVM = new EnumListVM(BreakProcessKindsUtils.BreakProcessKindList);
|
||||
|
||||
public string BreakKind {
|
||||
get => (string)BreakProcessKindVM.SelectedItem!;
|
||||
set => BreakProcessKindVM.SelectedItem = value;
|
||||
}
|
||||
|
||||
public override bool IsValid => isValid;
|
||||
bool isValid;
|
||||
|
||||
protected void UpdateIsValid() {
|
||||
var newIsValid = CalculateIsValid();
|
||||
if (newIsValid == isValid)
|
||||
return;
|
||||
isValid = newIsValid;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
|
||||
protected abstract bool CalculateIsValid();
|
||||
|
||||
protected readonly IPickFilename pickFilename;
|
||||
readonly IPickDirectory pickDirectory;
|
||||
|
||||
protected DotNetCommonStartDebuggingOptionsPage(IPickFilename pickFilename, IPickDirectory pickDirectory) {
|
||||
this.pickFilename = pickFilename ?? throw new ArgumentNullException(nameof(pickFilename));
|
||||
this.pickDirectory = pickDirectory ?? throw new ArgumentNullException(nameof(pickDirectory));
|
||||
}
|
||||
|
||||
static string? GetPath(string file) {
|
||||
try {
|
||||
return Path.GetDirectoryName(file);
|
||||
}
|
||||
catch {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static void Initialize(string filename, CorDebugStartDebuggingOptions options) {
|
||||
options.Filename = filename;
|
||||
options.WorkingDirectory = GetPath(options.Filename);
|
||||
}
|
||||
|
||||
protected abstract void PickNewFilename();
|
||||
|
||||
void PickNewWorkingDirectory() {
|
||||
var newDir = pickDirectory.GetDirectory(WorkingDirectory);
|
||||
if (newDir is null)
|
||||
return;
|
||||
|
||||
WorkingDirectory = newDir;
|
||||
}
|
||||
|
||||
static string FilterBreakKind(string? breakKind) {
|
||||
foreach (var info in BreakProcessKindsUtils.BreakProcessKindList) {
|
||||
if (StringComparer.Ordinal.Equals(breakKind, (string)info.Value))
|
||||
return breakKind!;
|
||||
}
|
||||
return PredefinedBreakKinds.DontBreak;
|
||||
}
|
||||
|
||||
protected void Initialize(CorDebugStartDebuggingOptions options) {
|
||||
Filename = options.Filename ?? string.Empty;
|
||||
CommandLine = options.CommandLine ?? string.Empty;
|
||||
// Must be init'd after Filename since it also overwrites this property
|
||||
WorkingDirectory = options.WorkingDirectory ?? string.Empty;
|
||||
BreakKind = FilterBreakKind(options.BreakKind);
|
||||
}
|
||||
|
||||
protected T InitializeDefault<T>(T options, string breakKind) where T : CorDebugStartDebuggingOptions {
|
||||
options.BreakKind = FilterBreakKind(breakKind);
|
||||
return options;
|
||||
}
|
||||
|
||||
protected T GetOptions<T>(T options) where T : CorDebugStartDebuggingOptions {
|
||||
options.Filename = Filename;
|
||||
options.CommandLine = CommandLine;
|
||||
options.WorkingDirectory = WorkingDirectory;
|
||||
options.BreakKind = FilterBreakKind(BreakKind);
|
||||
return options;
|
||||
}
|
||||
|
||||
string IDataErrorInfo.Error => throw new NotImplementedException();
|
||||
string IDataErrorInfo.this[string columnName] => Verify(columnName);
|
||||
|
||||
protected static string VerifyFilename(string filename) {
|
||||
if (!File.Exists(filename)) {
|
||||
if (string.IsNullOrWhiteSpace(filename))
|
||||
return dnSpy_Debugger_DotNet_CorDebug_Resources.Error_MissingFilename;
|
||||
return dnSpy_Debugger_DotNet_CorDebug_Resources.Error_FileDoesNotExist;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
protected abstract string Verify(string columnName);
|
||||
}
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2014-2019 de4dot@gmail.com
|
||||
|
||||
This file is part of dnSpy
|
||||
|
||||
dnSpy is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
dnSpy is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with dnSpy. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows.Input;
|
||||
using dnSpy.Contracts.Debugger;
|
||||
using dnSpy.Contracts.Debugger.DotNet.CorDebug;
|
||||
using dnSpy.Contracts.Debugger.StartDebugging;
|
||||
using dnSpy.Contracts.Debugger.StartDebugging.Dialog;
|
||||
using dnSpy.Contracts.MVVM;
|
||||
using dnSpy.Debugger.DotNet.CorDebug.Utilities;
|
||||
|
||||
namespace dnSpy.Debugger.DotNet.CorDebug.Dialogs.DebugProgram {
|
||||
sealed class DotNetCoreStartDebuggingOptionsPage : DotNetStartDebuggingOptionsPage {
|
||||
public override Guid Guid => new Guid("6DA15E33-27DA-498B-8AF1-552399485002");
|
||||
public override double DisplayOrder => PredefinedStartDebuggingOptionsPageDisplayOrders.DotNetCore;
|
||||
// Shouldn't be localized
|
||||
public override string DisplayName => ".NET Core";
|
||||
|
||||
public bool UseHost {
|
||||
get => useHost;
|
||||
set {
|
||||
if (useHost != value) {
|
||||
useHost = value;
|
||||
OnPropertyChanged(nameof(UseHost));
|
||||
OnPropertyChanged(nameof(HostFilename));
|
||||
UpdateIsValid();
|
||||
}
|
||||
}
|
||||
}
|
||||
bool useHost;
|
||||
|
||||
public string HostFilename {
|
||||
get => hostFilename;
|
||||
set {
|
||||
if (hostFilename != value) {
|
||||
hostFilename = value;
|
||||
OnPropertyChanged(nameof(HostFilename));
|
||||
UpdateIsValid();
|
||||
}
|
||||
}
|
||||
}
|
||||
string hostFilename = string.Empty;
|
||||
|
||||
public string HostArguments {
|
||||
get => hostArguments;
|
||||
set {
|
||||
if (hostArguments != value) {
|
||||
hostArguments = value;
|
||||
OnPropertyChanged(nameof(HostArguments));
|
||||
UpdateIsValid();
|
||||
}
|
||||
}
|
||||
}
|
||||
string hostArguments = string.Empty;
|
||||
|
||||
public ICommand PickHostFilenameCommand => new RelayCommand(a => PickNewHostFilename(), a => CanPickNewHostFilename);
|
||||
|
||||
public DotNetCoreStartDebuggingOptionsPage(IPickFilename pickFilename, IPickDirectory pickDirectory)
|
||||
: base(pickFilename, pickDirectory) {
|
||||
}
|
||||
|
||||
bool CanPickNewHostFilename => UseHost;
|
||||
|
||||
void PickNewHostFilename() {
|
||||
var newFilename = pickFilename.GetFilename(HostFilename, "exe", PickFilenameConstants.ExecutableFilter);
|
||||
if (newFilename is null)
|
||||
return;
|
||||
|
||||
HostFilename = newFilename;
|
||||
}
|
||||
|
||||
protected override void PickNewFilename() {
|
||||
var newFilename = pickFilename.GetFilename(Filename, "dll", PickFilenameConstants.DotNetAssemblyOrModuleFilter);
|
||||
if (newFilename is null)
|
||||
return;
|
||||
|
||||
Filename = newFilename;
|
||||
}
|
||||
|
||||
public override void InitializePreviousOptions(StartDebuggingOptions options) {
|
||||
var dncOptions = options as DotNetCoreStartDebuggingOptions;
|
||||
if (dncOptions is null)
|
||||
return;
|
||||
Initialize(dncOptions);
|
||||
}
|
||||
|
||||
public override void InitializeDefaultOptions(string filename, string breakKind, StartDebuggingOptions? options) =>
|
||||
Initialize(GetDefaultOptions(filename, breakKind, options));
|
||||
|
||||
DotNetCoreStartDebuggingOptions GetDefaultOptions(string filename, string breakKind, StartDebuggingOptions? options) {
|
||||
bool isExe = PortableExecutableFileHelpers.IsExecutable(filename);
|
||||
if (isExe) {
|
||||
var dncOptions = CreateOptions(breakKind);
|
||||
Initialize(filename, dncOptions);
|
||||
dncOptions.UseHost = !DotNetCoreGenericDebugEngineGuidProvider.IsDotNetCoreAppHostFilename(filename);
|
||||
return dncOptions;
|
||||
}
|
||||
else {
|
||||
// If it's a DLL, use the old EXE options if available
|
||||
if (options is DotNetCoreStartDebuggingOptions dncOptions)
|
||||
return dncOptions;
|
||||
return CreateOptions(breakKind);
|
||||
}
|
||||
}
|
||||
|
||||
DotNetCoreStartDebuggingOptions CreateOptions(string breakKind) =>
|
||||
InitializeDefault(new DotNetCoreStartDebuggingOptions { HostArguments = "exec" }, breakKind);
|
||||
|
||||
void Initialize(DotNetCoreStartDebuggingOptions options) {
|
||||
base.Initialize(options);
|
||||
UseHost = options.UseHost;
|
||||
HostFilename = options.Host ?? string.Empty;
|
||||
HostArguments = options.HostArguments ?? string.Empty;
|
||||
}
|
||||
|
||||
public override StartDebuggingOptionsInfo GetOptions() {
|
||||
var options = GetOptions(new DotNetCoreStartDebuggingOptions {
|
||||
UseHost = UseHost,
|
||||
Host = HostFilename,
|
||||
HostArguments = HostArguments,
|
||||
});
|
||||
var flags = StartDebuggingOptionsInfoFlags.None;
|
||||
if (File.Exists(options.Filename)) {
|
||||
var extension = Path.GetExtension(options.Filename);
|
||||
if (!StringComparer.OrdinalIgnoreCase.Equals(extension, ".exe") && !StringComparer.OrdinalIgnoreCase.Equals(extension, ".dll"))
|
||||
flags |= StartDebuggingOptionsInfoFlags.WrongExtension;
|
||||
}
|
||||
return new StartDebuggingOptionsInfo(options, options.Filename, flags);
|
||||
}
|
||||
|
||||
public override bool SupportsDebugEngine(Guid engineGuid, out double order) {
|
||||
if (engineGuid == PredefinedGenericDebugEngineGuids.DotNetCore) {
|
||||
order = PredefinedGenericDebugEngineOrders.DotNetCore;
|
||||
return true;
|
||||
}
|
||||
|
||||
order = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool CalculateIsValid() =>
|
||||
string.IsNullOrEmpty(Verify(nameof(HostFilename))) &&
|
||||
string.IsNullOrEmpty(Verify(nameof(Filename)));
|
||||
|
||||
protected override string Verify(string columnName) {
|
||||
if (columnName == nameof(HostFilename)) {
|
||||
if (UseHost && !string.IsNullOrWhiteSpace(HostFilename))
|
||||
return VerifyFilename(HostFilename);
|
||||
}
|
||||
else if (columnName == nameof(Filename))
|
||||
return VerifyFilename(Filename);
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ using dnSpy.Contracts.MVVM;
|
||||
using dnSpy.Debugger.DotNet.CorDebug.Utilities;
|
||||
|
||||
namespace dnSpy.Debugger.DotNet.CorDebug.Dialogs.DebugProgram {
|
||||
sealed class DotNetFrameworkStartDebuggingOptionsPage : DotNetStartDebuggingOptionsPage {
|
||||
sealed class DotNetFrameworkStartDebuggingOptionsPage : DotNetCommonStartDebuggingOptionsPage {
|
||||
// This guid is also used by DebugProgramVM
|
||||
public override Guid Guid => new Guid("3FB8FCB5-AECE-443A-ABDE-601F2C23F1C1");
|
||||
public override double DisplayOrder => PredefinedStartDebuggingOptionsPageDisplayOrders.DotNetFramework;
|
||||
|
@ -24,25 +24,25 @@ using dnSpy.Contracts.Debugger.StartDebugging;
|
||||
using dnSpy.Debugger.DotNet.CorDebug.Impl;
|
||||
|
||||
namespace dnSpy.Debugger.DotNet.CorDebug.Dialogs.DebugProgram {
|
||||
[ExportGenericDebugEngineGuidProvider(PredefinedGenericDebugEngineGuidProviderOrders.DotNetCore)]
|
||||
sealed class DotNetCoreGenericDebugEngineGuidProvider : GenericDebugEngineGuidProvider {
|
||||
[ExportGenericDebugEngineGuidProvider(PredefinedGenericDebugEngineGuidProviderOrders.DotNet)]
|
||||
sealed class DotNetGenericDebugEngineGuidProvider : GenericDebugEngineGuidProvider {
|
||||
public override Guid? GetEngineGuid(string filename) {
|
||||
if (!IsDotNetCoreAppHostFilename(filename))
|
||||
if (!IsDotNetAppHostFilename(filename))
|
||||
return null;
|
||||
return PredefinedGenericDebugEngineGuids.DotNetCore;
|
||||
return PredefinedGenericDebugEngineGuids.DotNet;
|
||||
}
|
||||
|
||||
internal static bool IsDotNetCoreAppHostFilename(string filename) {
|
||||
internal static bool IsDotNetAppHostFilename(string filename) {
|
||||
if (!File.Exists(filename))
|
||||
return false;
|
||||
return
|
||||
AppHostUtils.IsDotNetCoreBundleV1(filename) ||
|
||||
AppHostUtils.IsDotNetCoreBundleV2_or_AppHost(filename) ||
|
||||
IsKnownDotNetCoreAppHost(filename) ||
|
||||
AppHostUtils.IsDotNetCoreAppHostV1(filename, out _);
|
||||
AppHostUtils.IsDotNetBundleV1(filename) ||
|
||||
AppHostUtils.IsDotNetBundleV2_or_AppHost(filename) ||
|
||||
IsKnownDotNetAppHost(filename) ||
|
||||
AppHostUtils.IsDotNetAppHostV1(filename, out _);
|
||||
}
|
||||
|
||||
static bool IsKnownDotNetCoreAppHost(string filename) {
|
||||
static bool IsKnownDotNetAppHost(string filename) {
|
||||
if (AppHostUtils.TryGetAppHostEmbeddedDotNetDllPath(filename, out var couldBeAppHost, out _))
|
||||
return true;
|
||||
Debug.Assert(!couldBeAppHost, $"Looks like an unsupported apphost, update {nameof(AppHostInfoData)} table");
|
@ -18,155 +18,157 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Windows.Input;
|
||||
using dnSpy.Contracts.Debugger;
|
||||
using dnSpy.Contracts.Debugger.DotNet.CorDebug;
|
||||
using dnSpy.Contracts.Debugger.StartDebugging;
|
||||
using dnSpy.Contracts.Debugger.StartDebugging.Dialog;
|
||||
using dnSpy.Contracts.MVVM;
|
||||
using dnSpy.Debugger.DotNet.CorDebug.Properties;
|
||||
using dnSpy.Debugger.DotNet.CorDebug.Utilities;
|
||||
|
||||
namespace dnSpy.Debugger.DotNet.CorDebug.Dialogs.DebugProgram {
|
||||
abstract class DotNetStartDebuggingOptionsPage : StartDebuggingOptionsPage, IDataErrorInfo {
|
||||
public override object? UIObject => this;
|
||||
sealed class DotNetStartDebuggingOptionsPage : DotNetCommonStartDebuggingOptionsPage {
|
||||
public override Guid Guid => new Guid("6DA15E33-27DA-498B-8AF1-552399485002");
|
||||
public override double DisplayOrder => PredefinedStartDebuggingOptionsPageDisplayOrders.DotNet;
|
||||
// Shouldn't be localized
|
||||
public override string DisplayName => ".NET";
|
||||
|
||||
public string Filename {
|
||||
get => filename;
|
||||
public bool UseHost {
|
||||
get => useHost;
|
||||
set {
|
||||
if (filename != value) {
|
||||
filename = value;
|
||||
OnPropertyChanged(nameof(Filename));
|
||||
UpdateIsValid();
|
||||
var path = GetPath(filename);
|
||||
if (!(path is null))
|
||||
WorkingDirectory = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
string filename = string.Empty;
|
||||
|
||||
public string CommandLine {
|
||||
get => commandLine;
|
||||
set {
|
||||
if (commandLine != value) {
|
||||
commandLine = value;
|
||||
OnPropertyChanged(nameof(CommandLine));
|
||||
if (useHost != value) {
|
||||
useHost = value;
|
||||
OnPropertyChanged(nameof(UseHost));
|
||||
OnPropertyChanged(nameof(HostFilename));
|
||||
UpdateIsValid();
|
||||
}
|
||||
}
|
||||
}
|
||||
string commandLine = string.Empty;
|
||||
bool useHost;
|
||||
|
||||
public string WorkingDirectory {
|
||||
get => workingDirectory;
|
||||
public string HostFilename {
|
||||
get => hostFilename;
|
||||
set {
|
||||
if (workingDirectory != value) {
|
||||
workingDirectory = value;
|
||||
OnPropertyChanged(nameof(WorkingDirectory));
|
||||
if (hostFilename != value) {
|
||||
hostFilename = value;
|
||||
OnPropertyChanged(nameof(HostFilename));
|
||||
UpdateIsValid();
|
||||
}
|
||||
}
|
||||
}
|
||||
string workingDirectory = string.Empty;
|
||||
string hostFilename = string.Empty;
|
||||
|
||||
public ICommand PickFilenameCommand => new RelayCommand(a => PickNewFilename());
|
||||
public ICommand PickWorkingDirectoryCommand => new RelayCommand(a => PickNewWorkingDirectory());
|
||||
|
||||
public EnumListVM BreakProcessKindVM => breakProcessKindVM;
|
||||
readonly EnumListVM breakProcessKindVM = new EnumListVM(BreakProcessKindsUtils.BreakProcessKindList);
|
||||
|
||||
public string BreakKind {
|
||||
get => (string)BreakProcessKindVM.SelectedItem!;
|
||||
set => BreakProcessKindVM.SelectedItem = value;
|
||||
}
|
||||
|
||||
public override bool IsValid => isValid;
|
||||
bool isValid;
|
||||
|
||||
protected void UpdateIsValid() {
|
||||
var newIsValid = CalculateIsValid();
|
||||
if (newIsValid == isValid)
|
||||
return;
|
||||
isValid = newIsValid;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
|
||||
protected abstract bool CalculateIsValid();
|
||||
|
||||
protected readonly IPickFilename pickFilename;
|
||||
readonly IPickDirectory pickDirectory;
|
||||
|
||||
protected DotNetStartDebuggingOptionsPage(IPickFilename pickFilename, IPickDirectory pickDirectory) {
|
||||
this.pickFilename = pickFilename ?? throw new ArgumentNullException(nameof(pickFilename));
|
||||
this.pickDirectory = pickDirectory ?? throw new ArgumentNullException(nameof(pickDirectory));
|
||||
}
|
||||
|
||||
static string? GetPath(string file) {
|
||||
try {
|
||||
return Path.GetDirectoryName(file);
|
||||
public string HostArguments {
|
||||
get => hostArguments;
|
||||
set {
|
||||
if (hostArguments != value) {
|
||||
hostArguments = value;
|
||||
OnPropertyChanged(nameof(HostArguments));
|
||||
UpdateIsValid();
|
||||
}
|
||||
}
|
||||
catch {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
string hostArguments = string.Empty;
|
||||
|
||||
public ICommand PickHostFilenameCommand => new RelayCommand(a => PickNewHostFilename(), a => CanPickNewHostFilename);
|
||||
|
||||
public DotNetStartDebuggingOptionsPage(IPickFilename pickFilename, IPickDirectory pickDirectory)
|
||||
: base(pickFilename, pickDirectory) {
|
||||
}
|
||||
|
||||
protected static void Initialize(string filename, CorDebugStartDebuggingOptions options) {
|
||||
options.Filename = filename;
|
||||
options.WorkingDirectory = GetPath(options.Filename);
|
||||
}
|
||||
bool CanPickNewHostFilename => UseHost;
|
||||
|
||||
protected abstract void PickNewFilename();
|
||||
|
||||
void PickNewWorkingDirectory() {
|
||||
var newDir = pickDirectory.GetDirectory(WorkingDirectory);
|
||||
if (newDir is null)
|
||||
void PickNewHostFilename() {
|
||||
var newFilename = pickFilename.GetFilename(HostFilename, "exe", PickFilenameConstants.ExecutableFilter);
|
||||
if (newFilename is null)
|
||||
return;
|
||||
|
||||
WorkingDirectory = newDir;
|
||||
HostFilename = newFilename;
|
||||
}
|
||||
|
||||
static string FilterBreakKind(string? breakKind) {
|
||||
foreach (var info in BreakProcessKindsUtils.BreakProcessKindList) {
|
||||
if (StringComparer.Ordinal.Equals(breakKind, (string)info.Value))
|
||||
return breakKind!;
|
||||
protected override void PickNewFilename() {
|
||||
var newFilename = pickFilename.GetFilename(Filename, "dll", PickFilenameConstants.DotNetAssemblyOrModuleFilter);
|
||||
if (newFilename is null)
|
||||
return;
|
||||
|
||||
Filename = newFilename;
|
||||
}
|
||||
|
||||
public override void InitializePreviousOptions(StartDebuggingOptions options) {
|
||||
var dncOptions = options as DotNetStartDebuggingOptions;
|
||||
if (dncOptions is null)
|
||||
return;
|
||||
Initialize(dncOptions);
|
||||
}
|
||||
|
||||
public override void InitializeDefaultOptions(string filename, string breakKind, StartDebuggingOptions? options) =>
|
||||
Initialize(GetDefaultOptions(filename, breakKind, options));
|
||||
|
||||
DotNetStartDebuggingOptions GetDefaultOptions(string filename, string breakKind, StartDebuggingOptions? options) {
|
||||
bool isExe = PortableExecutableFileHelpers.IsExecutable(filename);
|
||||
if (isExe) {
|
||||
var dncOptions = CreateOptions(breakKind);
|
||||
Initialize(filename, dncOptions);
|
||||
dncOptions.UseHost = !DotNetGenericDebugEngineGuidProvider.IsDotNetAppHostFilename(filename);
|
||||
return dncOptions;
|
||||
}
|
||||
return PredefinedBreakKinds.DontBreak;
|
||||
}
|
||||
|
||||
protected void Initialize(CorDebugStartDebuggingOptions options) {
|
||||
Filename = options.Filename ?? string.Empty;
|
||||
CommandLine = options.CommandLine ?? string.Empty;
|
||||
// Must be init'd after Filename since it also overwrites this property
|
||||
WorkingDirectory = options.WorkingDirectory ?? string.Empty;
|
||||
BreakKind = FilterBreakKind(options.BreakKind);
|
||||
}
|
||||
|
||||
protected T InitializeDefault<T>(T options, string breakKind) where T : CorDebugStartDebuggingOptions {
|
||||
options.BreakKind = FilterBreakKind(breakKind);
|
||||
return options;
|
||||
}
|
||||
|
||||
protected T GetOptions<T>(T options) where T : CorDebugStartDebuggingOptions {
|
||||
options.Filename = Filename;
|
||||
options.CommandLine = CommandLine;
|
||||
options.WorkingDirectory = WorkingDirectory;
|
||||
options.BreakKind = FilterBreakKind(BreakKind);
|
||||
return options;
|
||||
}
|
||||
|
||||
string IDataErrorInfo.Error => throw new NotImplementedException();
|
||||
string IDataErrorInfo.this[string columnName] => Verify(columnName);
|
||||
|
||||
protected static string VerifyFilename(string filename) {
|
||||
if (!File.Exists(filename)) {
|
||||
if (string.IsNullOrWhiteSpace(filename))
|
||||
return dnSpy_Debugger_DotNet_CorDebug_Resources.Error_MissingFilename;
|
||||
return dnSpy_Debugger_DotNet_CorDebug_Resources.Error_FileDoesNotExist;
|
||||
else {
|
||||
// If it's a DLL, use the old EXE options if available
|
||||
if (options is DotNetStartDebuggingOptions dncOptions)
|
||||
return dncOptions;
|
||||
return CreateOptions(breakKind);
|
||||
}
|
||||
}
|
||||
|
||||
DotNetStartDebuggingOptions CreateOptions(string breakKind) =>
|
||||
InitializeDefault(new DotNetStartDebuggingOptions { HostArguments = "exec" }, breakKind);
|
||||
|
||||
void Initialize(DotNetStartDebuggingOptions options) {
|
||||
base.Initialize(options);
|
||||
UseHost = options.UseHost;
|
||||
HostFilename = options.Host ?? string.Empty;
|
||||
HostArguments = options.HostArguments ?? string.Empty;
|
||||
}
|
||||
|
||||
public override StartDebuggingOptionsInfo GetOptions() {
|
||||
var options = GetOptions(new DotNetStartDebuggingOptions {
|
||||
UseHost = UseHost,
|
||||
Host = HostFilename,
|
||||
HostArguments = HostArguments,
|
||||
});
|
||||
var flags = StartDebuggingOptionsInfoFlags.None;
|
||||
if (File.Exists(options.Filename)) {
|
||||
var extension = Path.GetExtension(options.Filename);
|
||||
if (!StringComparer.OrdinalIgnoreCase.Equals(extension, ".exe") && !StringComparer.OrdinalIgnoreCase.Equals(extension, ".dll"))
|
||||
flags |= StartDebuggingOptionsInfoFlags.WrongExtension;
|
||||
}
|
||||
return new StartDebuggingOptionsInfo(options, options.Filename, flags);
|
||||
}
|
||||
|
||||
public override bool SupportsDebugEngine(Guid engineGuid, out double order) {
|
||||
if (engineGuid == PredefinedGenericDebugEngineGuids.DotNet) {
|
||||
order = PredefinedGenericDebugEngineOrders.DotNet;
|
||||
return true;
|
||||
}
|
||||
|
||||
order = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool CalculateIsValid() =>
|
||||
string.IsNullOrEmpty(Verify(nameof(HostFilename))) &&
|
||||
string.IsNullOrEmpty(Verify(nameof(Filename)));
|
||||
|
||||
protected override string Verify(string columnName) {
|
||||
if (columnName == nameof(HostFilename)) {
|
||||
if (UseHost && !string.IsNullOrWhiteSpace(HostFilename))
|
||||
return VerifyFilename(HostFilename);
|
||||
}
|
||||
else if (columnName == nameof(Filename))
|
||||
return VerifyFilename(Filename);
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
protected abstract string Verify(string columnName);
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Dialogs.DebugProgram {
|
||||
|
||||
public override IEnumerable<StartDebuggingOptionsPage> Create(StartDebuggingOptionsPageContext context) {
|
||||
yield return new DotNetFrameworkStartDebuggingOptionsPage(pickFilename, pickDirectory);
|
||||
yield return new DotNetCoreStartDebuggingOptionsPage(pickFilename, pickDirectory);
|
||||
yield return new DotNetStartDebuggingOptionsPage(pickFilename, pickDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
static readonly byte[] AppHostExeSignature = Encoding.UTF8.GetBytes("c3ab8ff13720e8ad9047dd39466b3c89" + "\0");
|
||||
|
||||
// .NET Core 2.x, older .NET Core 3.0 previews
|
||||
internal static bool IsDotNetCoreAppHostV1(string filename, [NotNullWhen(true)] out string? dllFilename) {
|
||||
internal static bool IsDotNetAppHostV1(string filename, [NotNullWhen(true)] out string? dllFilename) {
|
||||
// We detect the apphost.exe like so:
|
||||
// - must have an exe extension
|
||||
// - must be a PE file and an EXE (DLL bit cleared)
|
||||
@ -78,7 +78,7 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
}
|
||||
|
||||
// Older .NET Core 3.0 previews
|
||||
internal static bool IsDotNetCoreBundleV1(string filename) {
|
||||
internal static bool IsDotNetBundleV1(string filename) {
|
||||
try {
|
||||
using (var stream = File.OpenRead(filename)) {
|
||||
if (stream.Length < bundleSig.Length)
|
||||
@ -101,7 +101,7 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
static readonly byte[] bundleSig = new byte[] { 0x0E, 0x2E, 0x4E, 0x65, 0x74, 0x43, 0x6F, 0x72, 0x65, 0x42, 0x75, 0x6E, 0x64, 0x6C, 0x65 };
|
||||
|
||||
// .NET Core 3.0
|
||||
internal static bool IsDotNetCoreBundleV2_or_AppHost(string filename) {
|
||||
internal static bool IsDotNetBundleV2_or_AppHost(string filename) {
|
||||
try {
|
||||
var data = ReadBytes(filename, 512 * 1024);
|
||||
return GetOffset(data, apphostSigV2) >= 0;
|
||||
|
@ -22,7 +22,7 @@ using dnSpy.Contracts.Debugger;
|
||||
|
||||
namespace dnSpy.Debugger.DotNet.CorDebug.Impl.Attach {
|
||||
/// <summary>
|
||||
/// Debugging options base class shared by .NET Framework code and .NET Core code
|
||||
/// Debugging options base class shared by .NET Framework code and .NET code
|
||||
/// </summary>
|
||||
abstract class CorDebugAttachToProgramOptions : AttachToProgramOptions {
|
||||
/// <summary>
|
||||
|
@ -22,9 +22,9 @@ using dnSpy.Contracts.Debugger;
|
||||
|
||||
namespace dnSpy.Debugger.DotNet.CorDebug.Impl.Attach {
|
||||
/// <summary>
|
||||
/// .NET Core attach to process options
|
||||
/// .NET attach to process options
|
||||
/// </summary>
|
||||
sealed class DotNetCoreAttachToProgramOptions : CorDebugAttachToProgramOptions {
|
||||
sealed class DotNetAttachToProgramOptions : CorDebugAttachToProgramOptions {
|
||||
/// <summary>
|
||||
/// A string returned by <c>dbgshim.dll</c>'s <c>CreateVersionStringFromModule</c> function
|
||||
/// or null to use the first found CoreCLR in the process.
|
||||
@ -40,14 +40,14 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl.Attach {
|
||||
/// Clones this instance
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override DebugProgramOptions Clone() => CopyTo(new DotNetCoreAttachToProgramOptions());
|
||||
public override DebugProgramOptions Clone() => CopyTo(new DotNetAttachToProgramOptions());
|
||||
|
||||
/// <summary>
|
||||
/// Copies this instance to <paramref name="other"/> and returns it
|
||||
/// </summary>
|
||||
/// <param name="other">Destination</param>
|
||||
/// <returns></returns>
|
||||
public DotNetCoreAttachToProgramOptions CopyTo(DotNetCoreAttachToProgramOptions other) {
|
||||
public DotNetAttachToProgramOptions CopyTo(DotNetAttachToProgramOptions other) {
|
||||
if (other is null)
|
||||
throw new ArgumentNullException(nameof(other));
|
||||
base.CopyTo(other);
|
@ -299,7 +299,7 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
frame = thread.ActiveFrame;
|
||||
if (frame?.Function is null) {
|
||||
// Ignore the first frame(s) that have a null function. This rarely happens (eg. it
|
||||
// happens when debugging dnSpy built for .NET Core x86)
|
||||
// happens when debugging dnSpy built for .NET x86)
|
||||
frame = thread.AllFrames.FirstOrDefault(a => !(a.Function is null));
|
||||
}
|
||||
}
|
||||
@ -666,8 +666,8 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
// We can only debug processes with the same bitness, so check IntPtr.Size.
|
||||
if (IntPtr.Size == 4 && debuggerSettings.AntiIsDebuggerPresent && options is DotNetFrameworkStartDebuggingOptions)
|
||||
disableMDA = true;
|
||||
// .NET Core doesn't support MDAs
|
||||
if (options is DotNetCoreStartDebuggingOptions)
|
||||
// .NET doesn't support MDAs
|
||||
if (options is DotNetStartDebuggingOptions)
|
||||
disableMDA = false;
|
||||
if (disableMDA) {
|
||||
// https://docs.microsoft.com/en-us/dotnet/framework/debug-trace-profile/diagnosing-errors-with-managed-debugging-assistants
|
||||
@ -676,7 +676,7 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
if (debuggerSettings.SuppressJITOptimization_SystemModules) {
|
||||
if (options is DotNetFrameworkStartDebuggingOptions)
|
||||
env.Add("COMPlus_ZapDisable", "1");
|
||||
else if (options is DotNetCoreStartDebuggingOptions)
|
||||
else if (options is DotNetStartDebuggingOptions)
|
||||
env.Add("COMPlus_ReadyToRun", "0");
|
||||
else
|
||||
Debug.Fail("Unreachable code");
|
||||
@ -771,8 +771,8 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
string errMsg;
|
||||
if (ex is ErrorException errEx)
|
||||
errMsg = errEx.Message;
|
||||
else if (CorDebugRuntimeKind == CorDebugRuntimeKind.DotNetCore && ex is ArgumentException) {
|
||||
// .NET Core throws ArgumentException if it can't attach to it (.NET Framework throws a COM exception with the correct error message)
|
||||
else if (CorDebugRuntimeKind == CorDebugRuntimeKind.DotNet && ex is ArgumentException) {
|
||||
// .NET throws ArgumentException if it can't attach to it (.NET Framework throws a COM exception with the correct error message)
|
||||
errMsg = string.Format(dnSpy_Debugger_DotNet_CorDebug_Resources.Error_CouldNotStartDebugger2,
|
||||
string.Format(dnSpy_Debugger_DotNet_CorDebug_Resources.Error_ProcessIsAlreadyBeingDebugged, options.ProcessId.ToString()));
|
||||
}
|
||||
@ -857,7 +857,7 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
get {
|
||||
debuggerThread.VerifyAccess();
|
||||
// If it's null, we haven't connected yet (most likely due to timeout, eg. trying to debug
|
||||
// a .NET Framework program with the .NET Core engine)
|
||||
// a .NET Framework program with the .NET engine)
|
||||
return !(dnDebugger is null);
|
||||
}
|
||||
}
|
||||
|
@ -38,14 +38,14 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
case DotNetFrameworkStartDebuggingOptions _:
|
||||
return new DotNetFrameworkDbgEngineImpl(dbgEngineImplDependencies.Value, dbgManager, DbgStartKind.Start);
|
||||
|
||||
case DotNetCoreStartDebuggingOptions _:
|
||||
return new DotNetCoreDbgEngineImpl(dbgEngineImplDependencies.Value, dbgManager, DbgStartKind.Start);
|
||||
case DotNetStartDebuggingOptions _:
|
||||
return new DotNetDbgEngineImpl(dbgEngineImplDependencies.Value, dbgManager, DbgStartKind.Start);
|
||||
|
||||
case DotNetFrameworkAttachToProgramOptions _:
|
||||
return new DotNetFrameworkDbgEngineImpl(dbgEngineImplDependencies.Value, dbgManager, DbgStartKind.Attach);
|
||||
|
||||
case DotNetCoreAttachToProgramOptions _:
|
||||
return new DotNetCoreDbgEngineImpl(dbgEngineImplDependencies.Value, dbgManager, DbgStartKind.Attach);
|
||||
case DotNetAttachToProgramOptions _:
|
||||
return new DotNetDbgEngineImpl(dbgEngineImplDependencies.Value, dbgManager, DbgStartKind.Attach);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -31,8 +31,8 @@ using dnSpy.Debugger.DotNet.CorDebug.Properties;
|
||||
using dnSpy.Debugger.DotNet.CorDebug.Utilities;
|
||||
|
||||
namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
sealed class DotNetCoreDbgEngineImpl : DbgEngineImpl {
|
||||
protected override CorDebugRuntimeKind CorDebugRuntimeKind => CorDebugRuntimeKind.DotNetCore;
|
||||
sealed class DotNetDbgEngineImpl : DbgEngineImpl {
|
||||
protected override CorDebugRuntimeKind CorDebugRuntimeKind => CorDebugRuntimeKind.DotNet;
|
||||
public override string[] Debugging => debugging;
|
||||
static readonly string[] debugging = new[] { "CoreCLR" };
|
||||
|
||||
@ -46,26 +46,26 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
|
||||
int Bitness => IntPtr.Size * 8;
|
||||
|
||||
public DotNetCoreDbgEngineImpl(DbgEngineImplDependencies deps, DbgManager dbgManager, DbgStartKind startKind)
|
||||
public DotNetDbgEngineImpl(DbgEngineImplDependencies deps, DbgManager dbgManager, DbgStartKind startKind)
|
||||
: base(deps, dbgManager, startKind) {
|
||||
}
|
||||
|
||||
string GetDbgShimAndVerify() {
|
||||
var dbgShimFilename = DotNetCoreHelpers.GetDebugShimFilename(Bitness);
|
||||
var dbgShimFilename = DotNetHelpers.GetDebugShimFilename(Bitness);
|
||||
if (!File.Exists(dbgShimFilename))
|
||||
throw new Exception("Couldn't find dbgshim.dll: " + dbgShimFilename);
|
||||
return dbgShimFilename;
|
||||
}
|
||||
|
||||
protected override CLRTypeDebugInfo CreateDebugInfo(CorDebugStartDebuggingOptions options) {
|
||||
var dncOptions = (DotNetCoreStartDebuggingOptions)options;
|
||||
var dncOptions = (DotNetStartDebuggingOptions)options;
|
||||
string? hostFilename;
|
||||
if (!dncOptions.UseHost)
|
||||
hostFilename = null;
|
||||
else if (string.IsNullOrWhiteSpace(dncOptions.Host)) {
|
||||
hostFilename = DotNetCoreHelpers.GetPathToDotNetExeHost(Bitness);
|
||||
hostFilename = DotNetHelpers.GetPathToDotNetExeHost(Bitness);
|
||||
if (!File.Exists(hostFilename))
|
||||
throw new Exception(string.Format(dnSpy_Debugger_DotNet_CorDebug_Resources.Error_CouldNotFindDotNetCoreHost, DotNetCoreHelpers.DotNetExeName));
|
||||
throw new Exception(string.Format(dnSpy_Debugger_DotNet_CorDebug_Resources.Error_CouldNotFindDotNetCoreHost, DotNetHelpers.DotNetExeName));
|
||||
}
|
||||
else
|
||||
hostFilename = dncOptions.Host;
|
||||
@ -74,22 +74,22 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
}
|
||||
|
||||
protected override CLRTypeAttachInfo CreateAttachInfo(CorDebugAttachToProgramOptions options) {
|
||||
var dncOptions = (DotNetCoreAttachToProgramOptions)options;
|
||||
var dncOptions = (DotNetAttachToProgramOptions)options;
|
||||
return new CoreCLRTypeAttachInfo(dncOptions.ClrModuleVersion, GetDbgShimAndVerify(), dncOptions.CoreCLRFilename);
|
||||
}
|
||||
|
||||
protected override void OnDebugProcess(DnDebugger dnDebugger) =>
|
||||
runtimeInfo = new DbgEngineRuntimeInfo(PredefinedDbgRuntimeGuids.DotNetCore_Guid, PredefinedDbgRuntimeKindGuids.DotNet_Guid, "CoreCLR", new DotNetCoreRuntimeId(dnDebugger.OtherVersion), runtimeTags);
|
||||
runtimeInfo = new DbgEngineRuntimeInfo(PredefinedDbgRuntimeGuids.DotNet_Guid, PredefinedDbgRuntimeKindGuids.DotNet_Guid, "CoreCLR", new DotNetRuntimeId(dnDebugger.OtherVersion), runtimeTags);
|
||||
static readonly ReadOnlyCollection<string> runtimeTags = new ReadOnlyCollection<string>(new[] {
|
||||
PredefinedDotNetDbgRuntimeTags.DotNetBase,
|
||||
PredefinedDotNetDbgRuntimeTags.DotNet,
|
||||
PredefinedDotNetDbgRuntimeTags.DotNetCore,
|
||||
});
|
||||
}
|
||||
|
||||
sealed class DotNetCoreRuntimeId : RuntimeId {
|
||||
sealed class DotNetRuntimeId : RuntimeId {
|
||||
readonly string? version;
|
||||
public DotNetCoreRuntimeId(string? version) => this.version = version;
|
||||
public override bool Equals(object? obj) => obj is DotNetCoreRuntimeId other && StringComparer.Ordinal.Equals(version ?? string.Empty, other.version ?? string.Empty);
|
||||
public DotNetRuntimeId(string? version) => this.version = version;
|
||||
public override bool Equals(object? obj) => obj is DotNetRuntimeId other && StringComparer.Ordinal.Equals(version ?? string.Empty, other.version ?? string.Empty);
|
||||
public override int GetHashCode() => StringComparer.Ordinal.GetHashCode(version ?? string.Empty);
|
||||
}
|
||||
}
|
@ -25,14 +25,14 @@ using dnSpy.Contracts.Debugger.StartDebugging;
|
||||
using dnSpy.Debugger.DotNet.CorDebug.Utilities;
|
||||
|
||||
namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
[ExportDbgProcessStarter(PredefinedDbgProcessStarterOrders.DotNetCore)]
|
||||
sealed class DotNetCoreDbgProcessStarter : DbgProcessStarter {
|
||||
string? GetPathToDotNetExeHost() => DotNetCoreHelpers.GetPathToDotNetExeHost(IntPtr.Size * 8);
|
||||
[ExportDbgProcessStarter(PredefinedDbgProcessStarterOrders.DotNet)]
|
||||
sealed class DotNetDbgProcessStarter : DbgProcessStarter {
|
||||
string? GetPathToDotNetExeHost() => DotNetHelpers.GetPathToDotNetExeHost(IntPtr.Size * 8);
|
||||
|
||||
public override bool IsSupported(string filename, out ProcessStarterResult result) {
|
||||
result = ProcessStarterResult.None;
|
||||
|
||||
if (!DotNetCoreHelpers.IsDotNetCoreExecutable(filename) || GetPathToDotNetExeHost() is null)
|
||||
if (!DotNetHelpers.IsDotNetExecutable(filename) || GetPathToDotNetExeHost() is null)
|
||||
return false;
|
||||
|
||||
var extension = Path.GetExtension(filename);
|
@ -54,7 +54,7 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl {
|
||||
protected override void OnDebugProcess(DnDebugger dnDebugger) =>
|
||||
runtimeInfo = new DbgEngineRuntimeInfo(PredefinedDbgRuntimeGuids.DotNetFramework_Guid, PredefinedDbgRuntimeKindGuids.DotNet_Guid, "CLR " + dnDebugger.DebuggeeVersion, new DotNetFrameworkRuntimeId(dnDebugger.DebuggeeVersion), runtimeTags);
|
||||
static readonly ReadOnlyCollection<string> runtimeTags = new ReadOnlyCollection<string>(new[] {
|
||||
PredefinedDotNetDbgRuntimeTags.DotNet,
|
||||
PredefinedDotNetDbgRuntimeTags.DotNetBase,
|
||||
PredefinedDotNetDbgRuntimeTags.DotNetFramework,
|
||||
});
|
||||
}
|
||||
|
@ -31,11 +31,11 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Impl.Evaluation {
|
||||
}
|
||||
}
|
||||
|
||||
[ExportDbgEngineObjectIdFactory(PredefinedDbgRuntimeGuids.DotNetCore)]
|
||||
sealed class DbgDotNetCoreEngineObjectIdFactoryImpl : DbgDotNetEngineObjectIdFactory {
|
||||
[ExportDbgEngineObjectIdFactory(PredefinedDbgRuntimeGuids.DotNet)]
|
||||
sealed class DbgDotNetEngineObjectIdFactoryImpl : DbgDotNetEngineObjectIdFactory {
|
||||
[ImportingConstructor]
|
||||
DbgDotNetCoreEngineObjectIdFactoryImpl(DbgDotNetLanguageService dbgDotNetLanguageService)
|
||||
: base(PredefinedDbgRuntimeGuids.DotNetCore_Guid, dbgDotNetLanguageService) {
|
||||
DbgDotNetEngineObjectIdFactoryImpl(DbgDotNetLanguageService dbgDotNetLanguageService)
|
||||
: base(PredefinedDbgRuntimeGuids.DotNet_Guid, dbgDotNetLanguageService) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace dnSpy.Debugger.DotNet.CorDebug {
|
||||
}
|
||||
|
||||
public ExtensionInfo ExtensionInfo => new ExtensionInfo {
|
||||
ShortDescription = string.Format(dnSpy_Debugger_DotNet_CorDebug_Resources.Plugin_ShortDescription, ".NET Framework, .NET Core"),
|
||||
ShortDescription = string.Format(dnSpy_Debugger_DotNet_CorDebug_Resources.Plugin_ShortDescription, ".NET Framework, .NET"),
|
||||
};
|
||||
|
||||
public void OnEvent(ExtensionEvent @event, object? obj) { }
|
||||
|
@ -51,7 +51,7 @@
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="{x:Type dbgprog:DotNetCoreStartDebuggingOptionsPage}">
|
||||
<DataTemplate DataType="{x:Type dbgprog:DotNetStartDebuggingOptionsPage}">
|
||||
<Grid Grid.Row="0" Margin="0 0 0 0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
|
@ -27,7 +27,7 @@ using dnSpy.Debugger.Shared;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace dnSpy.Debugger.DotNet.CorDebug.Utilities {
|
||||
static class DotNetCoreHelpers {
|
||||
static class DotNetHelpers {
|
||||
public static readonly string DotNetExeName = FileUtilities.GetNativeExeFilename("dotnet");
|
||||
|
||||
public static string? GetPathToDotNetExeHost(int bitness) {
|
||||
@ -36,7 +36,7 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Utilities {
|
||||
var pathEnvVar = Environment.GetEnvironmentVariable("PATH");
|
||||
if (pathEnvVar is null)
|
||||
return null;
|
||||
foreach (var tmp in GetDotNetCoreBaseDirCandidates()) {
|
||||
foreach (var tmp in GetDotNetBaseDirCandidates()) {
|
||||
var path = tmp.Trim();
|
||||
if (!Directory.Exists(path))
|
||||
continue;
|
||||
@ -62,8 +62,8 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Utilities {
|
||||
return null;
|
||||
}
|
||||
|
||||
// NOTE: This same method exists in DotNetCorePathProvider (dnSpy project). Update both methods if this one gets updated.
|
||||
static IEnumerable<string> GetDotNetCoreBaseDirCandidates() {
|
||||
// NOTE: This same method exists in DotNetPathProvider (dnSpy project). Update both methods if this one gets updated.
|
||||
static IEnumerable<string> GetDotNetBaseDirCandidates() {
|
||||
// Microsoft tools don't check the PATH env var, only the default locations (eg. ProgramFiles)
|
||||
var envVars = new string[] {
|
||||
"PATH",
|
||||
@ -115,7 +115,7 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Utilities {
|
||||
case 64: return Path.Combine(basePath, "x64", filename);
|
||||
default: throw new ArgumentOutOfRangeException(nameof(bitness));
|
||||
}
|
||||
#elif NETCOREAPP
|
||||
#elif NET
|
||||
var filename = FileUtilities.GetNativeDllFilename("dbgshim");
|
||||
return Path.Combine(Path.GetDirectoryName(typeof(void).Assembly.Location)!, filename);
|
||||
#else
|
||||
@ -123,7 +123,7 @@ namespace dnSpy.Debugger.DotNet.CorDebug.Utilities {
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool IsDotNetCoreExecutable(string filename) {
|
||||
public static bool IsDotNetExecutable(string filename) {
|
||||
if (!File.Exists(filename))
|
||||
return false;
|
||||
if (!PortableExecutableFileHelpers.IsExecutable(filename))
|
@ -47,18 +47,18 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<NetCoreDebugFilesX86 Include="..\netcorefiles\x86\**" />
|
||||
<NetCoreDebugFilesX64 Include="..\netcorefiles\x64\**" />
|
||||
<DotNetDebugFilesX86 Include="..\netcorefiles\x86\**" />
|
||||
<DotNetDebugFilesX64 Include="..\netcorefiles\x64\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CopyNetCoreDebugFiles_AfterBuild" AfterTargets="AfterBuild" Condition=" '$(IsDotNetFramework)' == 'true' ">
|
||||
<Copy SourceFiles="@(NetCoreDebugFilesX86)" DestinationFolder="$(TargetDir)debug\core\x86" />
|
||||
<Copy SourceFiles="@(NetCoreDebugFilesX64)" DestinationFolder="$(TargetDir)debug\core\x64" />
|
||||
<Target Name="CopyDotNetDebugFiles_AfterBuild" AfterTargets="AfterBuild" Condition=" '$(IsDotNetFramework)' == 'true' ">
|
||||
<Copy SourceFiles="@(DotNetDebugFilesX86)" DestinationFolder="$(TargetDir)debug\core\x86" />
|
||||
<Copy SourceFiles="@(DotNetDebugFilesX64)" DestinationFolder="$(TargetDir)debug\core\x64" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyNetCoreDebugFiles_Publish" AfterTargets="Publish" Condition=" '$(IsDotNetFramework)' == 'true' ">
|
||||
<Copy SourceFiles="@(NetCoreDebugFilesX86)" DestinationFolder="$(PublishDir)debug\core\x86" />
|
||||
<Copy SourceFiles="@(NetCoreDebugFilesX64)" DestinationFolder="$(PublishDir)debug\core\x64" />
|
||||
<Target Name="CopyDotNetDebugFiles_Publish" AfterTargets="Publish" Condition=" '$(IsDotNetFramework)' == 'true' ">
|
||||
<Copy SourceFiles="@(DotNetDebugFilesX86)" DestinationFolder="$(PublishDir)debug\core\x86" />
|
||||
<Copy SourceFiles="@(DotNetDebugFilesX64)" DestinationFolder="$(PublishDir)debug\core\x64" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -206,7 +206,7 @@ namespace dndbg.DotNet {
|
||||
continue;
|
||||
|
||||
if ("mscorlib".Equals(asmRef.Name, StringComparison.OrdinalIgnoreCase)) {
|
||||
if ((pktMscorlibDesktop.Equals(asmRef.PublicKeyOrToken) || pktMscorlibDotNetCore.Equals(asmRef.PublicKeyOrToken)) &&
|
||||
if ((pktMscorlibDotNetFramework.Equals(asmRef.PublicKeyOrToken) || pktMscorlibDotNet.Equals(asmRef.PublicKeyOrToken)) &&
|
||||
asmRef.Version != mscorlibWinMDVersion) {
|
||||
if (bestMscorlib is null || asmRef.Version > bestMscorlib.Version)
|
||||
bestMscorlib = asmRef;
|
||||
@ -221,8 +221,8 @@ namespace dndbg.DotNet {
|
||||
return bestNonMscorlib;
|
||||
}
|
||||
static readonly Version mscorlibWinMDVersion = new Version(0xFF, 0xFF, 0xFF, 0xFF);
|
||||
static readonly PublicKeyToken pktMscorlibDesktop = new PublicKeyToken("b77a5c561934e089");
|
||||
static readonly PublicKeyToken pktMscorlibDotNetCore = new PublicKeyToken("7cec85d7bea7798e");
|
||||
static readonly PublicKeyToken pktMscorlibDotNetFramework = new PublicKeyToken("b77a5c561934e089");
|
||||
static readonly PublicKeyToken pktMscorlibDotNet = new PublicKeyToken("7cec85d7bea7798e");
|
||||
|
||||
/// <summary>
|
||||
/// Should be called after caller has added it to its assembly
|
||||
|
@ -244,7 +244,7 @@ namespace dndbg.Engine {
|
||||
if (res == NativeMethods.WAIT_TIMEOUT) {
|
||||
if (keepWaiting())
|
||||
continue;
|
||||
throw new TimeoutException("Waiting for CoreCLR timed out. Debug 32-bit .NET Core apps with 32-bit dnSpy (dnSpy-x86.exe), and 64-bit .NET Core apps with 64-bit dnSpy (dnSpy.exe).");
|
||||
throw new TimeoutException("Waiting for CoreCLR timed out. Debug 32-bit .NET apps with 32-bit dnSpy (dnSpy-x86.exe), and 64-bit .NET apps with 64-bit dnSpy (dnSpy.exe).");
|
||||
}
|
||||
Debug.Fail($"Unknown result from WaitForMultipleObjects: 0x{res:X8}");
|
||||
throw new Exception("Error waiting for startup event");
|
||||
@ -252,7 +252,7 @@ namespace dndbg.Engine {
|
||||
|
||||
hr = dbgShimState.EnumerateCLRs!(pi.dwProcessId, out pHandleArray, out pStringArray, out dwArrayLength);
|
||||
if (hr < 0 || dwArrayLength == 0) {
|
||||
// CoreCLR doesn't give us a good error code if we try to debug a .NET Core app
|
||||
// CoreCLR doesn't give us a good error code if we try to debug a .NET app
|
||||
// with an incompatible bitness:
|
||||
// x86 tries to debug x64: hr == 0x8007012B (ERROR_PARTIAL_COPY)
|
||||
// x64 tries to debug x86: hr == 0x00000000 && dwArrayLength == 0x00000000
|
||||
|
@ -168,7 +168,7 @@ namespace dndbg.Engine {
|
||||
public string DebuggeeVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Other version, used by .NET Core
|
||||
/// Other version, used by .NET
|
||||
/// </summary>
|
||||
public string OtherVersion { get; }
|
||||
|
||||
@ -1536,7 +1536,7 @@ namespace dndbg.Engine {
|
||||
public int TryBreakProcesses() => TryBreakProcesses(true);
|
||||
|
||||
int TryBreakProcesses(bool callProcessStopped) {
|
||||
// At least with .NET Core, we'll get a DebuggerError (hr=0x80004005 (unspecified error))
|
||||
// At least with .NET, we'll get a DebuggerError (hr=0x80004005 (unspecified error))
|
||||
// if we try to break the process before the CreateProcess event.
|
||||
if (ProcessStateInternal == DebuggerProcessState.Starting)
|
||||
return -1;
|
||||
|
@ -360,10 +360,10 @@ namespace dnSpy.Debugger.DotNet.Metadata {
|
||||
|
||||
// We do not compare the version number. The runtime can redirect an assembly
|
||||
// reference from a requested version to any other version.
|
||||
// The public key token is also ignored. Only .NET Framwork checks it (.NET Core
|
||||
// The public key token is also ignored. Only .NET Framwork checks it (.NET
|
||||
// and Unity ignore it). We could add a new option to ignore the PKT but it would
|
||||
// require too many changes to the code (they access singleton comparers) and isn't
|
||||
// worth it. It's also being replaced by .NET Core. It's not common for two
|
||||
// worth it. It's also being replaced by .NET. It's not common for two
|
||||
// assemblies loaded in the same process to have the same assembly name but a
|
||||
// different public key token.
|
||||
const DmdAssemblyNameFlags flagsMask = DmdAssemblyNameFlags.ContentType_Mask;
|
||||
|
@ -1368,7 +1368,7 @@ namespace dnSpy.Debugger.DotNet.Metadata {
|
||||
/// true if this is a by-ref like value type
|
||||
/// </summary>
|
||||
public bool IsByRefLike =>
|
||||
//TODO: .NET Core adds this attribute to by ref like types, but .NET Framework does not, eg.
|
||||
//TODO: .NET adds this attribute to by ref like types, but .NET Framework does not, eg.
|
||||
// ArgIterator, RuntimeArgumentHandle, TypedReference
|
||||
CustomAttributesHelper.IsDefined(this, "System.Runtime.CompilerServices.IsByRefLikeAttribute", inherit: false);
|
||||
|
||||
|
@ -287,7 +287,7 @@ namespace dnSpy.Debugger.DotNet.Metadata.Impl {
|
||||
}
|
||||
}
|
||||
else if (CanResolveToCorLib(name)) {
|
||||
// .NET Core hack. We don't resolve assemblies, but some attributes used by the
|
||||
// .NET hack. We don't resolve assemblies, but some attributes used by the
|
||||
// debugger reference types in an assembly that just forwards the type to the corlib.
|
||||
// This assembly isn't normally loaded at runtime.
|
||||
// We could resolve assemblies but then it's possible that we'll resolve the wrong
|
||||
|
@ -146,11 +146,11 @@ namespace dnSpy.Debugger.DotNet.Mono.Impl {
|
||||
funcEvalFactory = new FuncEvalFactory(debuggerThread.GetDebugMessageDispatcher());
|
||||
}
|
||||
static readonly ReadOnlyCollection<string> monoRuntimeTags = new ReadOnlyCollection<string>(new[] {
|
||||
PredefinedDotNetDbgRuntimeTags.DotNet,
|
||||
PredefinedDotNetDbgRuntimeTags.DotNetBase,
|
||||
PredefinedDotNetDbgRuntimeTags.DotNetMono,
|
||||
});
|
||||
static readonly ReadOnlyCollection<string> unityRuntimeTags = new ReadOnlyCollection<string>(new[] {
|
||||
PredefinedDotNetDbgRuntimeTags.DotNet,
|
||||
PredefinedDotNetDbgRuntimeTags.DotNetBase,
|
||||
PredefinedDotNetDbgRuntimeTags.DotNetUnity,
|
||||
});
|
||||
|
||||
|
@ -235,7 +235,7 @@ namespace dnSpy.Debugger.DotNet.Mono.Impl.Evaluation {
|
||||
if (!(fieldValues[0] is PrimitiveValue pvFlags && fieldValues[1] is PrimitiveValue pvHi &&
|
||||
fieldValues[2] is PrimitiveValue pvLo && fieldValues[3] is PrimitiveValue pvMid))
|
||||
return default;
|
||||
// Mono using .NET Core source code
|
||||
// Mono using .NET source code
|
||||
if (pvFlags.Value is int && pvHi.Value is int && pvLo.Value is int && pvMid.Value is int)
|
||||
return ((int)pvFlags.Value, (int)pvHi.Value, (int)pvLo.Value, (int)pvMid.Value);
|
||||
// Unity and older Mono
|
||||
@ -250,7 +250,7 @@ namespace dnSpy.Debugger.DotNet.Mono.Impl.Evaluation {
|
||||
if (fields.Length != values.Length)
|
||||
return default;
|
||||
if (fields.Length == 1) {
|
||||
// Newer Mono using .NET Core source code
|
||||
// Newer Mono using .NET source code
|
||||
|
||||
if (fields[0].Name != KnownMemberNames.DateTime_DateData_FieldName1 && fields[0].Name != KnownMemberNames.DateTime_DateData_FieldName2)
|
||||
return default;
|
||||
|
@ -24,7 +24,7 @@ using dnlib.PE;
|
||||
using dnSpy.Contracts.Debugger.StartDebugging;
|
||||
|
||||
namespace dnSpy.Debugger.DotNet.Dialogs.DebugProgram {
|
||||
[ExportGenericDebugEngineGuidProvider(PredefinedGenericDebugEngineGuidProviderOrders.DotNet)]
|
||||
[ExportGenericDebugEngineGuidProvider(PredefinedGenericDebugEngineGuidProviderOrders.DotNetAny)]
|
||||
sealed class DotNetGenericDebugEngineGuidProvider : GenericDebugEngineGuidProvider {
|
||||
public override Guid? GetEngineGuid(string filename) {
|
||||
if (!File.Exists(filename))
|
||||
@ -59,7 +59,7 @@ namespace dnSpy.Debugger.DotNet.Dialogs.DebugProgram {
|
||||
if (values.Length >= 2 && values.Length <= 3) {
|
||||
var framework = values[0].Trim();
|
||||
if (framework == ".NETCoreApp")
|
||||
return PredefinedGenericDebugEngineGuids.DotNetCore;
|
||||
return PredefinedGenericDebugEngineGuids.DotNet;
|
||||
}
|
||||
|
||||
return defaultGuid;
|
||||
|
@ -57,9 +57,9 @@ namespace dnSpy.Debugger.DotNet.Metadata {
|
||||
|
||||
// System.Threading.Thread
|
||||
public const string Thread_ManagedThreadId_FieldName1 = "m_ManagedThreadId";
|
||||
public const string Thread_ManagedThreadId_FieldName2 = "_managedThreadId";// .NET Core since early 2019
|
||||
public const string Thread_ManagedThreadId_FieldName2 = "_managedThreadId";// .NET since early 2019
|
||||
public const string Thread_Name_FieldName1 = "m_Name";
|
||||
public const string Thread_Name_FieldName2 = "_name";// .NET Core since early 2019
|
||||
public const string Thread_Name_FieldName2 = "_name";// .NET since early 2019
|
||||
|
||||
// System.Nullable<T>
|
||||
public const string Nullable_HasValue_FieldName = "hasValue";
|
||||
@ -74,7 +74,7 @@ namespace dnSpy.Debugger.DotNet.Metadata {
|
||||
|
||||
// System.DateTime
|
||||
public const string DateTime_DateData_FieldName1 = "dateData";// .NET Framework, Mono
|
||||
public const string DateTime_DateData_FieldName2 = "_dateData";// .NET Core
|
||||
public const string DateTime_DateData_FieldName2 = "_dateData";// .NET
|
||||
public const string DateTime_Ticks_FieldName_Mono = "ticks";
|
||||
public const string DateTime_Kind_FieldName_Mono = "kind";
|
||||
|
||||
|
@ -29,7 +29,7 @@ To debug Unity games, you need this repo too: https://github.com/dnSpy/dnSpy-Uni
|
||||
|
||||
# Debugger
|
||||
|
||||
- Debug .NET Framework, .NET Core and Unity game assemblies, no source code required
|
||||
- Debug .NET Framework, .NET and Unity game assemblies, no source code required
|
||||
- Set breakpoints and step into any assembly
|
||||
- Locals, watch, autos windows
|
||||
- Variables windows support saving variables (eg. decrypted byte arrays) to disk or view them in the hex editor (memory window)
|
||||
|
30
build.ps1
30
build.ps1
@ -1,8 +1,8 @@
|
||||
param([string]$buildtfm = 'all', [switch]$NoMsbuild)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$net_tfm = 'net48'
|
||||
$netcore_tfm = 'net5.0-windows'
|
||||
$netframework_tfm = 'net48'
|
||||
$net_tfm = 'net5.0-windows'
|
||||
$configuration = 'Release'
|
||||
$net_baseoutput = "dnSpy\dnSpy\bin\$configuration"
|
||||
$apphostpatcher_dir = "Build\AppHostPatcher"
|
||||
@ -14,14 +14,14 @@ $apphostpatcher_dir = "Build\AppHostPatcher"
|
||||
function Build-NetFramework {
|
||||
Write-Host 'Building .NET Framework x86 and x64 binaries'
|
||||
|
||||
$outdir = "$net_baseoutput\$net_tfm"
|
||||
$outdir = "$net_baseoutput\$netframework_tfm"
|
||||
|
||||
if ($NoMsbuild) {
|
||||
dotnet build -v:m -c $configuration -f $net_tfm
|
||||
dotnet build -v:m -c $configuration -f $netframework_tfm
|
||||
if ($LASTEXITCODE) { exit $LASTEXITCODE }
|
||||
}
|
||||
else {
|
||||
msbuild -v:m -m -restore -t:Build -p:Configuration=$configuration -p:TargetFramework=$net_tfm
|
||||
msbuild -v:m -m -restore -t:Build -p:Configuration=$configuration -p:TargetFramework=$netframework_tfm
|
||||
if ($LASTEXITCODE) { exit $LASTEXITCODE }
|
||||
}
|
||||
|
||||
@ -36,21 +36,21 @@ function Build-NetFramework {
|
||||
}
|
||||
}
|
||||
|
||||
function Build-NetCore {
|
||||
function Build-Net {
|
||||
param([string]$arch)
|
||||
|
||||
Write-Host "Building .NET Core $arch binaries"
|
||||
Write-Host "Building .NET $arch binaries"
|
||||
|
||||
$rid = "win-$arch"
|
||||
$outdir = "$net_baseoutput\$netcore_tfm\$rid"
|
||||
$outdir = "$net_baseoutput\$net_tfm\$rid"
|
||||
$publishDir = "$outdir\publish"
|
||||
|
||||
if ($NoMsbuild) {
|
||||
dotnet publish -v:m -c $configuration -f $netcore_tfm -r $rid --self-contained
|
||||
dotnet publish -v:m -c $configuration -f $net_tfm -r $rid --self-contained
|
||||
if ($LASTEXITCODE) { exit $LASTEXITCODE }
|
||||
}
|
||||
else {
|
||||
msbuild -v:m -m -restore -t:Publish -p:Configuration=$configuration -p:TargetFramework=$netcore_tfm -p:RuntimeIdentifier=$rid -p:SelfContained=True
|
||||
msbuild -v:m -m -restore -t:Publish -p:Configuration=$configuration -p:TargetFramework=$net_tfm -p:RuntimeIdentifier=$rid -p:SelfContained=True
|
||||
if ($LASTEXITCODE) { exit $LASTEXITCODE }
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ function Build-NetCore {
|
||||
Rename-Item $publishDir\$tmpbin bin
|
||||
foreach ($exe in 'dnSpy.exe', 'dnSpy.Console.exe') {
|
||||
Move-Item $publishDir\bin\$exe $publishDir
|
||||
& $apphostpatcher_dir\bin\$configuration\$net_tfm\AppHostPatcher.exe $publishDir\$exe -d bin
|
||||
& $apphostpatcher_dir\bin\$configuration\$netframework_tfm\AppHostPatcher.exe $publishDir\$exe -d bin
|
||||
if ($LASTEXITCODE) { exit $LASTEXITCODE }
|
||||
}
|
||||
}
|
||||
@ -73,11 +73,11 @@ $buildCoreX64 = $buildtfm -eq 'all' -or $buildtfm -eq 'core-x64'
|
||||
|
||||
if ($buildCoreX86 -or $buildCoreX64) {
|
||||
if ($NoMsbuild) {
|
||||
dotnet build -v:m -c $configuration -f $net_tfm $apphostpatcher_dir\AppHostPatcher.csproj
|
||||
dotnet build -v:m -c $configuration -f $netframework_tfm $apphostpatcher_dir\AppHostPatcher.csproj
|
||||
if ($LASTEXITCODE) { exit $LASTEXITCODE }
|
||||
}
|
||||
else {
|
||||
msbuild -v:m -m -restore -t:Build -p:Configuration=$configuration -p:TargetFramework=$net_tfm $apphostpatcher_dir\AppHostPatcher.csproj
|
||||
msbuild -v:m -m -restore -t:Build -p:Configuration=$configuration -p:TargetFramework=$netframework_tfm $apphostpatcher_dir\AppHostPatcher.csproj
|
||||
if ($LASTEXITCODE) { exit $LASTEXITCODE }
|
||||
}
|
||||
}
|
||||
@ -87,9 +87,9 @@ if ($buildNet) {
|
||||
}
|
||||
|
||||
if ($buildCoreX86) {
|
||||
Build-NetCore x86
|
||||
Build-Net x86
|
||||
}
|
||||
|
||||
if ($buildCoreX64) {
|
||||
Build-NetCore x64
|
||||
Build-Net x64
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ namespace dnSpy.Roslyn.Compiler {
|
||||
Unknown,
|
||||
DotNetFramework2,
|
||||
DotNetFramework4,
|
||||
DotNetCore,
|
||||
DotNet,
|
||||
Unity2,
|
||||
Unity4,
|
||||
}
|
||||
@ -52,7 +52,7 @@ namespace dnSpy.Roslyn.Compiler {
|
||||
return FrameworkKind.Unknown;
|
||||
}
|
||||
if (info.framework == ".NETCoreApp")
|
||||
return FrameworkKind.DotNetCore;
|
||||
return FrameworkKind.DotNet;
|
||||
|
||||
return FrameworkKind.Unknown;
|
||||
}
|
||||
@ -67,7 +67,7 @@ namespace dnSpy.Roslyn.Compiler {
|
||||
switch (corlib.Name) {
|
||||
case "System.Runtime":
|
||||
if (corlib.Version >= new Version(4, 1, 0, 0))
|
||||
return FrameworkKind.DotNetCore;
|
||||
return FrameworkKind.DotNet;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ namespace dnSpy.Roslyn.Debugger.ValueNodes {
|
||||
DmdWellKnownType.System_Linq_SystemCore_EnumerableDebugView_T :
|
||||
DmdWellKnownType.System_Linq_SystemCore_EnumerableDebugView;
|
||||
var debugViewType = appDomain.GetWellKnownType(wellKnownType, isOptional: true);
|
||||
// If this fails, System.Core (.NET Framework) / System.Linq (.NET Core) hasn't been loaded yet
|
||||
// If this fails, System.Core (.NET Framework) / System.Linq (.NET) hasn't been loaded yet
|
||||
// or the type doesn't exist in the assembly (Unity)
|
||||
if (debugViewType is null)
|
||||
return null;
|
||||
|
@ -145,7 +145,7 @@ namespace dnSpy.Roslyn.Debugger.ValueNodes {
|
||||
}
|
||||
|
||||
ClrVersion GetClrVersion(DbgRuntime runtime) {
|
||||
if (runtime.Guid == PredefinedDbgRuntimeGuids.DotNetCore_Guid)
|
||||
if (runtime.Guid == PredefinedDbgRuntimeGuids.DotNet_Guid)
|
||||
return ClrVersion.CoreCLR;
|
||||
if (enumerableType.AppDomain.CorLib?.GetName().Version == new Version(2, 0, 0, 0))
|
||||
return ClrVersion.CLR2;
|
||||
|
@ -23,7 +23,7 @@ namespace dnSpy_x86 {
|
||||
static class Program {
|
||||
[STAThread]
|
||||
static void Main() {
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
const string errmsg = "Wrong startup project";
|
||||
System.Diagnostics.Debug.Fail(errmsg);
|
||||
throw new InvalidOperationException(errmsg);
|
||||
|
@ -190,16 +190,16 @@ namespace dnSpy_Console {
|
||||
readonly AssemblyResolver assemblyResolver;
|
||||
readonly IBamlDecompiler? bamlDecompiler;
|
||||
readonly HashSet<string> reservedOptions;
|
||||
#if NETCOREAPP
|
||||
readonly dnSpy.MainApp.NetCoreAssemblyLoader netCoreAssemblyLoader = new dnSpy.MainApp.NetCoreAssemblyLoader(System.Runtime.Loader.AssemblyLoadContext.Default);
|
||||
#if NET
|
||||
readonly dnSpy.MainApp.DotNetAssemblyLoader dotNetAssemblyLoader = new dnSpy.MainApp.DotNetAssemblyLoader(System.Runtime.Loader.AssemblyLoadContext.Default);
|
||||
#endif
|
||||
|
||||
static readonly char PATHS_SEP = Path.PathSeparator;
|
||||
|
||||
public DnSpyDecompiler() {
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
// This assembly is always in the bin sub dir if one exists
|
||||
netCoreAssemblyLoader.AddSearchPath(Path.GetDirectoryName(typeof(ILSpan).Assembly.Location)!);
|
||||
dotNetAssemblyLoader.AddSearchPath(Path.GetDirectoryName(typeof(ILSpan).Assembly.Location)!);
|
||||
#endif
|
||||
files = new List<string>();
|
||||
asmPaths = new List<string>();
|
||||
|
@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
<!-- Target dir is the same as dnSpy.exe so we'll overwrite some files when creating
|
||||
a self-contained .NET Core app (System.Security.Permissions (wrong lower version), WindowsBase
|
||||
a self-contained .NET app (System.Security.Permissions (wrong lower version), WindowsBase
|
||||
(wrong file (15KB, should be 1.1MB))).
|
||||
|
||||
The workaround is to add WindowsDesktop above.
|
||||
@ -27,7 +27,7 @@ The workaround is to add WindowsDesktop above.
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\dnSpy\MainApp\NetCoreAssemblyLoader.cs" Link="NetCoreAssemblyLoader.cs" />
|
||||
<Compile Include="..\dnSpy\MainApp\DotNetAssemblyLoader.cs" Link="DotNetAssemblyLoader.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -28,8 +28,8 @@ namespace dnSpy.Contracts.Debugger.DotNet.CorDebug {
|
||||
DotNetFramework,
|
||||
|
||||
/// <summary>
|
||||
/// .NET Core
|
||||
/// .NET
|
||||
/// </summary>
|
||||
DotNetCore,
|
||||
DotNet,
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ namespace dnSpy.Contracts.Debugger.DotNet.CorDebug {
|
||||
|
||||
/// <summary>
|
||||
/// Gets the version string, eg. "v2.0.50727" or "v4.0.30319" if it's .NET Framework.
|
||||
/// If it's .NET Core, this is currently an empty string.
|
||||
/// If it's .NET, this is currently an empty string.
|
||||
/// </summary>
|
||||
public string Version { get; }
|
||||
|
||||
|
@ -21,7 +21,7 @@ using System;
|
||||
|
||||
namespace dnSpy.Contracts.Debugger.DotNet.CorDebug {
|
||||
/// <summary>
|
||||
/// Debugging options base class shared by .NET Framework code and .NET Core code
|
||||
/// Debugging options base class shared by .NET Framework code and .NET code
|
||||
/// </summary>
|
||||
public abstract class CorDebugStartDebuggingOptions : StartDebuggingOptions {
|
||||
/// <summary>
|
||||
|
@ -21,7 +21,7 @@ using dnSpy.Contracts.Debugger.DotNet.Evaluation;
|
||||
|
||||
namespace dnSpy.Contracts.Debugger.DotNet.CorDebug {
|
||||
/// <summary>
|
||||
/// .NET Framework / .NET Core runtime. It must implement <see cref="IDbgDotNetRuntime"/>
|
||||
/// .NET Framework / .NET runtime. It must implement <see cref="IDbgDotNetRuntime"/>
|
||||
/// </summary>
|
||||
public abstract class DbgCorDebugInternalRuntime : DbgDotNetInternalRuntime {
|
||||
/// <summary>
|
||||
|
@ -22,9 +22,9 @@ using System;
|
||||
namespace dnSpy.Contracts.Debugger.DotNet.CorDebug {
|
||||
/// <summary>
|
||||
/// Debugging options that will start and debug an application when passed to <see cref="DbgManager.Start(DebugProgramOptions)"/>.
|
||||
/// This is used to debug .NET Core assemblies.
|
||||
/// This is used to debug .NET assemblies.
|
||||
/// </summary>
|
||||
public sealed class DotNetCoreStartDebuggingOptions : CorDebugStartDebuggingOptions {
|
||||
public sealed class DotNetStartDebuggingOptions : CorDebugStartDebuggingOptions {
|
||||
/// <summary>
|
||||
/// If true, use <see cref="Host"/> (eg. dotnet.exe). If false, <see cref="Host"/>
|
||||
/// isn't used and <see cref="CorDebugStartDebuggingOptions.Filename"/> should be
|
||||
@ -38,7 +38,7 @@ namespace dnSpy.Contracts.Debugger.DotNet.CorDebug {
|
||||
public string? Host { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Host arguments (eg. "exec" if .NET Core's dotnet.exe is used)
|
||||
/// Host arguments (eg. "exec" if .NET's dotnet.exe is used)
|
||||
/// </summary>
|
||||
public string? HostArguments { get; set; }
|
||||
|
||||
@ -46,14 +46,14 @@ namespace dnSpy.Contracts.Debugger.DotNet.CorDebug {
|
||||
/// Clones this instance
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override DebugProgramOptions Clone() => CopyTo(new DotNetCoreStartDebuggingOptions());
|
||||
public override DebugProgramOptions Clone() => CopyTo(new DotNetStartDebuggingOptions());
|
||||
|
||||
/// <summary>
|
||||
/// Copies this instance to <paramref name="other"/> and returns it
|
||||
/// </summary>
|
||||
/// <param name="other">Destination</param>
|
||||
/// <returns></returns>
|
||||
public DotNetCoreStartDebuggingOptions CopyTo(DotNetCoreStartDebuggingOptions other) {
|
||||
public DotNetStartDebuggingOptions CopyTo(DotNetStartDebuggingOptions other) {
|
||||
if (other is null)
|
||||
throw new ArgumentNullException(nameof(other));
|
||||
base.CopyTo(other);
|
@ -23,9 +23,9 @@ namespace dnSpy.Contracts.Debugger.DotNet {
|
||||
/// </summary>
|
||||
public static class PredefinedDotNetDbgRuntimeTags {
|
||||
/// <summary>
|
||||
/// .NET runtime
|
||||
/// .NET runtime (any)
|
||||
/// </summary>
|
||||
public const string DotNet = nameof(DotNet);
|
||||
public const string DotNetBase = nameof(DotNetBase);
|
||||
|
||||
/// <summary>
|
||||
/// .NET Framework runtime
|
||||
@ -33,9 +33,9 @@ namespace dnSpy.Contracts.Debugger.DotNet {
|
||||
public const string DotNetFramework = nameof(DotNetFramework);
|
||||
|
||||
/// <summary>
|
||||
/// .NET Core runtime
|
||||
/// .NET runtime
|
||||
/// </summary>
|
||||
public const string DotNetCore = nameof(DotNetCore);
|
||||
public const string DotNet = nameof(DotNet);
|
||||
|
||||
/// <summary>
|
||||
/// .NET Mono runtime
|
||||
|
@ -31,6 +31,6 @@ namespace dnSpy.Contracts.Debugger {
|
||||
/// </summary>
|
||||
/// <param name="runtime">Runtime</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsDotNetRuntime(this DbgRuntime runtime) => runtime.Tags.Any(a => StringComparer.Ordinal.Equals(PredefinedDotNetDbgRuntimeTags.DotNet, a));
|
||||
public static bool IsDotNetRuntime(this DbgRuntime runtime) => runtime.Tags.Any(a => StringComparer.Ordinal.Equals(PredefinedDotNetDbgRuntimeTags.DotNetBase, a));
|
||||
}
|
||||
}
|
||||
|
@ -28,9 +28,9 @@ namespace dnSpy.Contracts.Debugger.Attach {
|
||||
public const string DotNetFramework = nameof(DotNetFramework);
|
||||
|
||||
/// <summary>
|
||||
/// .NET Core
|
||||
/// .NET
|
||||
/// </summary>
|
||||
public const string DotNetCore = nameof(DotNetCore);
|
||||
public const string DotNet = nameof(DotNet);
|
||||
|
||||
/// <summary>
|
||||
/// Unity Editor
|
||||
|
@ -35,14 +35,14 @@ namespace dnSpy.Contracts.Debugger {
|
||||
public static readonly Guid DotNetFramework_Guid = new Guid(DotNetFramework);
|
||||
|
||||
/// <summary>
|
||||
/// .NET Core
|
||||
/// .NET
|
||||
/// </summary>
|
||||
public const string DotNetCore = "E0B4EB52-D1D9-42AB-B130-028CA31CF9F6";
|
||||
public const string DotNet = "E0B4EB52-D1D9-42AB-B130-028CA31CF9F6";
|
||||
|
||||
/// <summary>
|
||||
/// .NET Core
|
||||
/// .NET
|
||||
/// </summary>
|
||||
public static readonly Guid DotNetCore_Guid = new Guid(DotNetCore);
|
||||
public static readonly Guid DotNet_Guid = new Guid(DotNet);
|
||||
|
||||
/// <summary>
|
||||
/// Unity
|
||||
|
@ -89,9 +89,9 @@ namespace dnSpy.Contracts.Debugger.StartDebugging {
|
||||
/// </summary>
|
||||
public static class PredefinedDbgProcessStarterOrders {
|
||||
/// <summary>
|
||||
/// .NET Core
|
||||
/// .NET
|
||||
/// </summary>
|
||||
public const double DotNetCore = 1000000;
|
||||
public const double DotNet = 1000000;
|
||||
|
||||
/// <summary>
|
||||
/// Default process starter that calls <see cref="Process.Start(string)"/>
|
||||
|
@ -28,9 +28,9 @@ namespace dnSpy.Contracts.Debugger.StartDebugging.Dialog {
|
||||
public static readonly double DotNetFramework = 100000;
|
||||
|
||||
/// <summary>
|
||||
/// .NET Core debug engine
|
||||
/// .NET debug engine
|
||||
/// </summary>
|
||||
public static readonly double DotNetCore = 101000;
|
||||
public static readonly double DotNet = 101000;
|
||||
|
||||
/// <summary>
|
||||
/// Unity debug engine (start executable)
|
||||
|
@ -49,7 +49,7 @@ namespace dnSpy.Contracts.Debugger.StartDebugging.Dialog {
|
||||
public abstract double DisplayOrder { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of debug engine shown in the UI, eg. ".NET Framework" or ".NET Core" or "Mono"
|
||||
/// Name of debug engine shown in the UI, eg. ".NET Framework" or ".NET" or "Mono"
|
||||
/// </summary>
|
||||
public abstract string DisplayName { get; }
|
||||
|
||||
@ -160,9 +160,9 @@ namespace dnSpy.Contracts.Debugger.StartDebugging.Dialog {
|
||||
public const double DotNetFramework = 1000000;
|
||||
|
||||
/// <summary>
|
||||
/// .NET Core
|
||||
/// .NET
|
||||
/// </summary>
|
||||
public const double DotNetCore = 1000000;
|
||||
public const double DotNet = 1000000;
|
||||
|
||||
/// <summary>
|
||||
/// .NET Mono
|
||||
|
@ -63,18 +63,18 @@ namespace dnSpy.Contracts.Debugger.StartDebugging {
|
||||
/// </summary>
|
||||
public static class PredefinedGenericDebugEngineGuidProviderOrders {
|
||||
/// <summary>
|
||||
/// .NET Framework / .NET Core
|
||||
/// .NET Framework / .NET
|
||||
/// </summary>
|
||||
public const double DotNet = 1000000;
|
||||
public const double DotNetAny = 1000000;
|
||||
|
||||
/// <summary>
|
||||
/// Unity
|
||||
/// </summary>
|
||||
public const double DotNetUnity = DotNet + 1;
|
||||
public const double DotNetUnity = DotNetAny + 1;
|
||||
|
||||
/// <summary>
|
||||
/// .NET Core
|
||||
/// .NET
|
||||
/// </summary>
|
||||
public const double DotNetCore = DotNet + 2;
|
||||
public const double DotNet = DotNetAny + 2;
|
||||
}
|
||||
}
|
||||
|
@ -30,9 +30,9 @@ namespace dnSpy.Contracts.Debugger.StartDebugging {
|
||||
public static readonly Guid DotNetFramework = new Guid("0F99555D-5523-4AAE-BD4C-0451B9D50126");
|
||||
|
||||
/// <summary>
|
||||
/// .NET Core
|
||||
/// .NET
|
||||
/// </summary>
|
||||
public static readonly Guid DotNetCore = new Guid("7D294510-4730-433B-85C1-61EC0B4F6C3C");
|
||||
public static readonly Guid DotNet = new Guid("7D294510-4730-433B-85C1-61EC0B4F6C3C");
|
||||
|
||||
/// <summary>
|
||||
/// Unity
|
||||
|
@ -33,13 +33,13 @@ namespace dnSpy.Documents {
|
||||
readonly DsDocumentService documentService;
|
||||
readonly Lazy<IRuntimeAssemblyResolver, IRuntimeAssemblyResolverMetadata>[] runtimeAsmResolvers;
|
||||
readonly FailedAssemblyResolveCache failedAssemblyResolveCache;
|
||||
readonly DotNetCorePathProvider dotNetCorePathProvider;
|
||||
readonly DotNetPathProvider dotNetPathProvider;
|
||||
|
||||
static readonly UTF8String mscorlibName = new UTF8String("mscorlib");
|
||||
static readonly UTF8String systemRuntimeName = new UTF8String("System.Runtime");
|
||||
static readonly UTF8String netstandardName = new UTF8String("netstandard");
|
||||
static readonly UTF8String aspNetCoreName = new UTF8String("Microsoft.AspNetCore");
|
||||
// netstandard1.5 also uses this version number, but assume it's .NET Core
|
||||
// netstandard1.5 also uses this version number, but assume it's .NET
|
||||
static readonly Version minSystemRuntimeNetCoreVersion = new Version(4, 1, 0, 0);
|
||||
|
||||
const string TFM_netframework = ".NETFramework";
|
||||
@ -47,13 +47,13 @@ namespace dnSpy.Documents {
|
||||
const string TFM_netcoreapp = ".NETCoreApp";
|
||||
const string TFM_netstandard = ".NETStandard";
|
||||
const string UnityEngineFilename = "UnityEngine.dll";
|
||||
const string SelfContainedDotNetCoreFilename = "System.Private.CoreLib.dll";
|
||||
const string SelfContainedDotNetFilename = "System.Private.CoreLib.dll";
|
||||
|
||||
public AssemblyResolver(DsDocumentService documentService, Lazy<IRuntimeAssemblyResolver, IRuntimeAssemblyResolverMetadata>[] runtimeAsmResolvers) {
|
||||
this.documentService = documentService;
|
||||
this.runtimeAsmResolvers = runtimeAsmResolvers;
|
||||
failedAssemblyResolveCache = new FailedAssemblyResolveCache();
|
||||
dotNetCorePathProvider = new DotNetCorePathProvider();
|
||||
dotNetPathProvider = new DotNetPathProvider();
|
||||
}
|
||||
|
||||
// PERF: Sometimes various pieces of code tries to resolve the same assembly and this
|
||||
@ -147,8 +147,8 @@ namespace dnSpy.Documents {
|
||||
DotNetFramework2,
|
||||
// This is .NET Framework 4.0 and later. Search in V4 GAC, not V2 GAC.
|
||||
DotNetFramework4,
|
||||
DotNetCore,
|
||||
SelfContainedDotNetCore,
|
||||
DotNet,
|
||||
SelfContainedDotNet,
|
||||
Unity,
|
||||
WindowsUniversal,
|
||||
}
|
||||
@ -183,9 +183,9 @@ namespace dnSpy.Documents {
|
||||
}
|
||||
internal void OnAssembliesCleared() => frameworkInfos = Array.Empty<FrameworkPathInfo>();
|
||||
|
||||
FrameworkKind GetFrameworkKind(ModuleDef? module, out Version? netCoreVersion, out string? sourceModuleDirectoryHint) {
|
||||
FrameworkKind GetFrameworkKind(ModuleDef? module, out Version? netVersion, out string? sourceModuleDirectoryHint) {
|
||||
if (module is null) {
|
||||
netCoreVersion = null;
|
||||
netVersion = null;
|
||||
sourceModuleDirectoryHint = null;
|
||||
return FrameworkKind.Unknown;
|
||||
}
|
||||
@ -205,14 +205,14 @@ namespace dnSpy.Documents {
|
||||
newFwkKind = GetFrameworkKind_AssemblyRefs(module, frameworkName, out fwkVersion);
|
||||
if (newFwkKind != FrameworkKind.Unknown) {
|
||||
info.FrameworkKind = Best(info.FrameworkKind, newFwkKind);
|
||||
if (info.FrameworkKind == FrameworkKind.DotNetCore && newFwkKind == FrameworkKind.DotNetCore)
|
||||
if (info.FrameworkKind == FrameworkKind.DotNet && newFwkKind == FrameworkKind.DotNet)
|
||||
info.FrameworkVersion = fwkVersion;
|
||||
}
|
||||
}
|
||||
if (info.FrameworkKind == FrameworkKind.DotNetCore)
|
||||
netCoreVersion = info.FrameworkVersion;
|
||||
if (info.FrameworkKind == FrameworkKind.DotNet)
|
||||
netVersion = info.FrameworkVersion;
|
||||
else
|
||||
netCoreVersion = null;
|
||||
netVersion = null;
|
||||
sourceModuleDirectoryHint = info.Directory;
|
||||
return info.FrameworkKind;
|
||||
}
|
||||
@ -220,10 +220,10 @@ namespace dnSpy.Documents {
|
||||
|
||||
var fwkKind = GetRuntimeFrameworkKind(sourceFilename, out var frameworkVersion);
|
||||
if (fwkKind != FrameworkKind.Unknown) {
|
||||
if (fwkKind == FrameworkKind.DotNetCore)
|
||||
netCoreVersion = frameworkVersion;
|
||||
if (fwkKind == FrameworkKind.DotNet)
|
||||
netVersion = frameworkVersion;
|
||||
else
|
||||
netCoreVersion = null;
|
||||
netVersion = null;
|
||||
sourceModuleDirectoryHint = null;
|
||||
return fwkKind;
|
||||
}
|
||||
@ -243,24 +243,24 @@ namespace dnSpy.Documents {
|
||||
fwkInfo.FrameworkVersion = null;
|
||||
fwkInfo.Frozen = isExe;
|
||||
fwkInfo = Add(fwkInfo);
|
||||
if (fwkInfo.FrameworkKind == FrameworkKind.DotNetCore)
|
||||
netCoreVersion = fwkInfo.FrameworkVersion;
|
||||
if (fwkInfo.FrameworkKind == FrameworkKind.DotNet)
|
||||
netVersion = fwkInfo.FrameworkVersion;
|
||||
else
|
||||
netCoreVersion = null;
|
||||
netVersion = null;
|
||||
sourceModuleDirectoryHint = fwkInfo.Directory;
|
||||
return fwkInfo.FrameworkKind;
|
||||
}
|
||||
|
||||
netCoreVersion = null;
|
||||
netVersion = null;
|
||||
sourceModuleDirectoryHint = null;
|
||||
return FrameworkKind.Unknown;
|
||||
}
|
||||
|
||||
static FrameworkKind Best(FrameworkKind a, FrameworkKind b) {
|
||||
if (a == FrameworkKind.SelfContainedDotNetCore || b == FrameworkKind.SelfContainedDotNetCore)
|
||||
return FrameworkKind.SelfContainedDotNetCore;
|
||||
if (a == FrameworkKind.DotNetCore || b == FrameworkKind.DotNetCore)
|
||||
return FrameworkKind.DotNetCore;
|
||||
if (a == FrameworkKind.SelfContainedDotNet || b == FrameworkKind.SelfContainedDotNet)
|
||||
return FrameworkKind.SelfContainedDotNet;
|
||||
if (a == FrameworkKind.DotNet || b == FrameworkKind.DotNet)
|
||||
return FrameworkKind.DotNet;
|
||||
if (a == FrameworkKind.Unity || b == FrameworkKind.Unity)
|
||||
return FrameworkKind.Unity;
|
||||
if (a == FrameworkKind.WindowsUniversal || b == FrameworkKind.WindowsUniversal)
|
||||
@ -273,20 +273,20 @@ namespace dnSpy.Documents {
|
||||
return FrameworkKind.Unknown;
|
||||
}
|
||||
|
||||
FrameworkKind GetRuntimeFrameworkKind(string filename, out Version? netCoreVersion) {
|
||||
FrameworkKind GetRuntimeFrameworkKind(string filename, out Version? netVersion) {
|
||||
foreach (var gacPath in GacInfo.GacPaths) {
|
||||
if (FileUtils.IsFileInDir(gacPath.Path, filename)) {
|
||||
netCoreVersion = null;
|
||||
netVersion = null;
|
||||
Debug.Assert(gacPath.Version == GacVersion.V2 || gacPath.Version == GacVersion.V4);
|
||||
return gacPath.Version == GacVersion.V2 ? FrameworkKind.DotNetFramework2 : FrameworkKind.DotNetFramework4;
|
||||
}
|
||||
}
|
||||
|
||||
netCoreVersion = dotNetCorePathProvider.TryGetDotNetCoreVersion(filename);
|
||||
if (!(netCoreVersion is null))
|
||||
return FrameworkKind.DotNetCore;
|
||||
netVersion = dotNetPathProvider.TryGetDotNetVersion(filename);
|
||||
if (!(netVersion is null))
|
||||
return FrameworkKind.DotNet;
|
||||
|
||||
netCoreVersion = null;
|
||||
netVersion = null;
|
||||
return FrameworkKind.Unknown;
|
||||
}
|
||||
|
||||
@ -295,9 +295,9 @@ namespace dnSpy.Documents {
|
||||
version = null;
|
||||
return FrameworkKind.Unity;
|
||||
}
|
||||
if (File.Exists(Path.Combine(directory, SelfContainedDotNetCoreFilename))) {
|
||||
if (File.Exists(Path.Combine(directory, SelfContainedDotNetFilename))) {
|
||||
version = null;
|
||||
return FrameworkKind.SelfContainedDotNetCore;
|
||||
return FrameworkKind.SelfContainedDotNet;
|
||||
}
|
||||
|
||||
// Could be a runtime sub dir, eg. "<basedir>\runtimes\unix\lib\netcoreapp2.0". These assemblies
|
||||
@ -306,7 +306,7 @@ namespace dnSpy.Documents {
|
||||
var dirName = Path.GetFileName(directory);
|
||||
if (TryParseVersion("netcoreapp", dirName, out var fwkVersion)) {
|
||||
version = fwkVersion;
|
||||
return FrameworkKind.DotNetCore;
|
||||
return FrameworkKind.DotNet;
|
||||
}
|
||||
else if (TryParseNetFrameworkVersion("net", dirName, out fwkVersion)) {
|
||||
version = fwkVersion;
|
||||
@ -365,10 +365,10 @@ namespace dnSpy.Documents {
|
||||
if (frameworkName == TFM_netframework)
|
||||
return version.Major < 4 ? FrameworkKind.DotNetFramework2 : FrameworkKind.DotNetFramework4;
|
||||
if (frameworkName == TFM_netcoreapp)
|
||||
return FrameworkKind.DotNetCore;
|
||||
return FrameworkKind.DotNet;
|
||||
if (frameworkName == TFM_uwp)
|
||||
return FrameworkKind.WindowsUniversal;
|
||||
if (!dotNetCorePathProvider.HasDotNetCore && frameworkName == TFM_netstandard)
|
||||
if (!dotNetPathProvider.HasDotNet && frameworkName == TFM_netstandard)
|
||||
return FrameworkKind.DotNetFramework4;
|
||||
return FrameworkKind.Unknown;
|
||||
}
|
||||
@ -381,7 +381,7 @@ namespace dnSpy.Documents {
|
||||
FrameworkKind GetFrameworkKind_AssemblyRefs(ModuleDef module, string? frameworkName, out Version? version) {
|
||||
AssemblyRef? mscorlibRef = null;
|
||||
AssemblyRef? systemRuntimeRef = null;
|
||||
// ASP.NET Core *.Views assemblies don't have a TFM attribute, so grab the .NET Core version from an ASP.NET Core asm ref
|
||||
// ASP.NET Core *.Views assemblies don't have a TFM attribute, so grab the .NET version from an ASP.NET Core asm ref
|
||||
AssemblyRef? aspNetCoreRef = null;
|
||||
foreach (var asmRef in module.GetAssemblyRefs()) {
|
||||
var name = asmRef.Name;
|
||||
@ -396,7 +396,7 @@ namespace dnSpy.Documents {
|
||||
systemRuntimeRef = asmRef;
|
||||
}
|
||||
else if (name == netstandardName) {
|
||||
if (!dotNetCorePathProvider.HasDotNetCore) {
|
||||
if (!dotNetPathProvider.HasDotNet) {
|
||||
version = null;
|
||||
return FrameworkKind.DotNetFramework4;
|
||||
}
|
||||
@ -441,7 +441,7 @@ namespace dnSpy.Documents {
|
||||
else
|
||||
Debug.Fail("Unknown .NET Core version");
|
||||
}
|
||||
return FrameworkKind.DotNetCore;
|
||||
return FrameworkKind.DotNet;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -486,8 +486,8 @@ namespace dnSpy.Documents {
|
||||
}
|
||||
|
||||
IDsDocument? ResolveNormal(IAssembly assembly, ModuleDef? sourceModule) {
|
||||
var fwkKind = GetFrameworkKind(sourceModule, out var netCoreVersion, out var sourceModuleDirectoryHint);
|
||||
if (fwkKind == FrameworkKind.DotNetCore && !dotNetCorePathProvider.HasDotNetCore)
|
||||
var fwkKind = GetFrameworkKind(sourceModule, out var netVersion, out var sourceModuleDirectoryHint);
|
||||
if (fwkKind == FrameworkKind.DotNet && !dotNetPathProvider.HasDotNet)
|
||||
fwkKind = FrameworkKind.DotNetFramework4;
|
||||
bool loaded;
|
||||
IDsDocument? document;
|
||||
@ -539,7 +539,7 @@ namespace dnSpy.Documents {
|
||||
if (!(existingDocument is null))
|
||||
return existingDocument;
|
||||
|
||||
(document, loaded) = LookupFromSearchPaths(assembly, sourceModule, sourceModuleDirectoryHint, netCoreVersion);
|
||||
(document, loaded) = LookupFromSearchPaths(assembly, sourceModule, sourceModuleDirectoryHint, netVersion);
|
||||
if (!(document is null))
|
||||
return documentService.GetOrAddCanDispose(document, assembly, loaded);
|
||||
|
||||
@ -563,18 +563,18 @@ namespace dnSpy.Documents {
|
||||
}
|
||||
break;
|
||||
|
||||
case FrameworkKind.DotNetCore:
|
||||
case FrameworkKind.DotNet:
|
||||
case FrameworkKind.Unity:
|
||||
case FrameworkKind.SelfContainedDotNetCore:
|
||||
case FrameworkKind.SelfContainedDotNet:
|
||||
case FrameworkKind.WindowsUniversal:
|
||||
document = TryRuntimeAssemblyResolvers(assembly, sourceModule);
|
||||
if (!(document is null))
|
||||
return document;
|
||||
|
||||
// If it's a self-contained .NET Core app, we don't need the version since we must only search
|
||||
// If it's a self-contained .NET app, we don't need the version since we must only search
|
||||
// the current directory.
|
||||
Debug2.Assert(fwkKind == FrameworkKind.DotNetCore || netCoreVersion is null);
|
||||
(document, loaded) = LookupFromSearchPaths(assembly, sourceModule, sourceModuleDirectoryHint, netCoreVersion);
|
||||
Debug2.Assert(fwkKind == FrameworkKind.DotNet || netVersion is null);
|
||||
(document, loaded) = LookupFromSearchPaths(assembly, sourceModule, sourceModuleDirectoryHint, netVersion);
|
||||
if (!(document is null))
|
||||
return documentService.GetOrAddCanDispose(document, assembly, loaded);
|
||||
|
||||
@ -602,8 +602,8 @@ namespace dnSpy.Documents {
|
||||
case FrameworkKind.DotNetFramework4:
|
||||
return false;
|
||||
|
||||
case FrameworkKind.DotNetCore:
|
||||
case FrameworkKind.SelfContainedDotNetCore:
|
||||
case FrameworkKind.DotNet:
|
||||
case FrameworkKind.SelfContainedDotNet:
|
||||
case FrameworkKind.Unity:
|
||||
case FrameworkKind.WindowsUniversal:
|
||||
return true;
|
||||
@ -631,15 +631,15 @@ namespace dnSpy.Documents {
|
||||
return (document, false);
|
||||
}
|
||||
|
||||
string[]? dotNetCorePaths;
|
||||
string[]? dotNetPaths;
|
||||
if (!(dotNetCoreAppVersion is null)) {
|
||||
int bitness = (sourceModule?.GetPointerSize(IntPtr.Size) ?? IntPtr.Size) * 8;
|
||||
dotNetCorePaths = dotNetCorePathProvider.TryGetDotNetCorePaths(dotNetCoreAppVersion, bitness);
|
||||
dotNetPaths = dotNetPathProvider.TryGetDotNetPaths(dotNetCoreAppVersion, bitness);
|
||||
}
|
||||
else
|
||||
dotNetCorePaths = null;
|
||||
if (!(dotNetCorePaths is null)) {
|
||||
foreach (var path in dotNetCorePaths) {
|
||||
dotNetPaths = null;
|
||||
if (!(dotNetPaths is null)) {
|
||||
foreach (var path in dotNetPaths) {
|
||||
document = TryFindFromDir(asmName, dirPath: path);
|
||||
if (!(document is null))
|
||||
return (document, false);
|
||||
@ -651,8 +651,8 @@ namespace dnSpy.Documents {
|
||||
if (!(document is null))
|
||||
return (document, true);
|
||||
}
|
||||
if (!(dotNetCorePaths is null)) {
|
||||
foreach (var path in dotNetCorePaths) {
|
||||
if (!(dotNetPaths is null)) {
|
||||
foreach (var path in dotNetPaths) {
|
||||
document = TryLoadFromDir(asmName, checkVersion: false, checkPublicKeyToken: false, dirPath: path);
|
||||
if (!(document is null))
|
||||
return (document, true);
|
||||
|
@ -27,15 +27,15 @@ using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace dnSpy.Documents {
|
||||
sealed class DotNetCorePathProvider {
|
||||
readonly FrameworkPaths[] netcorePaths;
|
||||
sealed class DotNetPathProvider {
|
||||
readonly FrameworkPaths[] netPaths;
|
||||
|
||||
public bool HasDotNetCore => netcorePaths.Length != 0;
|
||||
public bool HasDotNet => netPaths.Length != 0;
|
||||
|
||||
readonly struct NetCorePathInfo {
|
||||
readonly struct DotNetPathInfo {
|
||||
public readonly string Directory;
|
||||
public readonly int Bitness;
|
||||
public NetCorePathInfo(string directory, int bitness) {
|
||||
public DotNetPathInfo(string directory, int bitness) {
|
||||
Directory = directory ?? throw new ArgumentNullException(nameof(directory));
|
||||
Bitness = bitness;
|
||||
}
|
||||
@ -61,10 +61,10 @@ namespace dnSpy.Documents {
|
||||
public override int GetHashCode() => version.Major ^ version.Minor ^ version.Patch ^ (version.Extra.Length == 0 ? 0 : -1);
|
||||
}
|
||||
|
||||
public DotNetCorePathProvider() {
|
||||
public DotNetPathProvider() {
|
||||
var list = new List<FrameworkPath>();
|
||||
foreach (var info in GetDotNetCoreBaseDirs())
|
||||
list.AddRange(GetDotNetCorePaths(info.Directory, info.Bitness));
|
||||
foreach (var info in GetDotNetBaseDirs())
|
||||
list.AddRange(GetDotNetPaths(info.Directory, info.Bitness));
|
||||
|
||||
var paths = from p in list
|
||||
group p by new { Path = (Path.GetDirectoryName(Path.GetDirectoryName(p.Path)) ?? string.Empty).ToUpperInvariant(), p.Bitness, Version = new FrameworkVersionIgnoreExtra(p.Version) } into g
|
||||
@ -72,44 +72,44 @@ namespace dnSpy.Documents {
|
||||
select new FrameworkPaths(g.ToArray());
|
||||
var array = paths.ToArray();
|
||||
Array.Sort(array);
|
||||
netcorePaths = array;
|
||||
netPaths = array;
|
||||
}
|
||||
|
||||
public string[]? TryGetDotNetCorePaths(Version version, int bitness) {
|
||||
public string[]? TryGetDotNetPaths(Version version, int bitness) {
|
||||
Debug.Assert(bitness == 32 || bitness == 64);
|
||||
int bitness2 = bitness ^ 0x60;
|
||||
FrameworkPaths? info;
|
||||
|
||||
info = TryGetDotNetCorePathsCore(version.Major, version.Minor, bitness) ??
|
||||
TryGetDotNetCorePathsCore(version.Major, version.Minor, bitness2);
|
||||
info = TryGetDotNetPathsCore(version.Major, version.Minor, bitness) ??
|
||||
TryGetDotNetPathsCore(version.Major, version.Minor, bitness2);
|
||||
if (!(info is null))
|
||||
return info.Paths;
|
||||
|
||||
info = TryGetDotNetCorePathsCore(version.Major, bitness) ??
|
||||
TryGetDotNetCorePathsCore(version.Major, bitness2);
|
||||
info = TryGetDotNetPathsCore(version.Major, bitness) ??
|
||||
TryGetDotNetPathsCore(version.Major, bitness2);
|
||||
if (!(info is null))
|
||||
return info.Paths;
|
||||
|
||||
info = TryGetDotNetCorePathsCore(bitness) ??
|
||||
TryGetDotNetCorePathsCore(bitness2);
|
||||
info = TryGetDotNetPathsCore(bitness) ??
|
||||
TryGetDotNetPathsCore(bitness2);
|
||||
if (!(info is null))
|
||||
return info.Paths;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
FrameworkPaths? TryGetDotNetCorePathsCore(int major, int minor, int bitness) {
|
||||
FrameworkPaths? TryGetDotNetPathsCore(int major, int minor, int bitness) {
|
||||
FrameworkPaths? fpMajor = null;
|
||||
FrameworkPaths? fpMajorMinor = null;
|
||||
for (int i = netcorePaths.Length - 1; i >= 0; i--) {
|
||||
var info = netcorePaths[i];
|
||||
for (int i = netPaths.Length - 1; i >= 0; i--) {
|
||||
var info = netPaths[i];
|
||||
if (info.Bitness == bitness && info.Version.Major == major) {
|
||||
if (fpMajor is null)
|
||||
fpMajor = info;
|
||||
else
|
||||
fpMajor = BestMinorVersion(minor, fpMajor, info);
|
||||
if (info.Version.Minor == minor) {
|
||||
if (info.HasDotNetCoreAppPath)
|
||||
if (info.HasDotNetAppPath)
|
||||
return info;
|
||||
if (fpMajorMinor is null)
|
||||
fpMajorMinor = info;
|
||||
@ -140,12 +140,12 @@ namespace dnSpy.Documents {
|
||||
return 0x80000000 + (uint)minVer - (uint)ver - 1;
|
||||
}
|
||||
|
||||
FrameworkPaths? TryGetDotNetCorePathsCore(int major, int bitness) {
|
||||
FrameworkPaths? TryGetDotNetPathsCore(int major, int bitness) {
|
||||
FrameworkPaths? fpMajor = null;
|
||||
for (int i = netcorePaths.Length - 1; i >= 0; i--) {
|
||||
var info = netcorePaths[i];
|
||||
for (int i = netPaths.Length - 1; i >= 0; i--) {
|
||||
var info = netPaths[i];
|
||||
if (info.Bitness == bitness && info.Version.Major == major) {
|
||||
if (info.HasDotNetCoreAppPath)
|
||||
if (info.HasDotNetAppPath)
|
||||
return info;
|
||||
if (fpMajor is null)
|
||||
fpMajor = info;
|
||||
@ -154,12 +154,12 @@ namespace dnSpy.Documents {
|
||||
return fpMajor;
|
||||
}
|
||||
|
||||
FrameworkPaths? TryGetDotNetCorePathsCore(int bitness) {
|
||||
FrameworkPaths? TryGetDotNetPathsCore(int bitness) {
|
||||
FrameworkPaths? best = null;
|
||||
for (int i = netcorePaths.Length - 1; i >= 0; i--) {
|
||||
var info = netcorePaths[i];
|
||||
for (int i = netPaths.Length - 1; i >= 0; i--) {
|
||||
var info = netPaths[i];
|
||||
if (info.Bitness == bitness) {
|
||||
if (info.HasDotNetCoreAppPath)
|
||||
if (info.HasDotNetAppPath)
|
||||
return info;
|
||||
if (best is null)
|
||||
best = info;
|
||||
@ -169,9 +169,9 @@ namespace dnSpy.Documents {
|
||||
}
|
||||
|
||||
const string DotNetExeName = "dotnet.exe";
|
||||
static IEnumerable<NetCorePathInfo> GetDotNetCoreBaseDirs() {
|
||||
static IEnumerable<DotNetPathInfo> GetDotNetBaseDirs() {
|
||||
var hash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var tmp in GetDotNetCoreBaseDirCandidates()) {
|
||||
foreach (var tmp in GetDotNetBaseDirCandidates()) {
|
||||
var path = tmp.Trim();
|
||||
if (!Directory.Exists(path))
|
||||
continue;
|
||||
@ -204,12 +204,12 @@ namespace dnSpy.Documents {
|
||||
}
|
||||
if (bitness == -1)
|
||||
continue;
|
||||
yield return new NetCorePathInfo(path, bitness);
|
||||
yield return new DotNetPathInfo(path, bitness);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: This same method exists in DotNetCoreHelpers (CorDebug project). Update both methods if this one gets updated.
|
||||
static IEnumerable<string> GetDotNetCoreBaseDirCandidates() {
|
||||
// NOTE: This same method exists in DotNetHelpers (CorDebug project). Update both methods if this one gets updated.
|
||||
static IEnumerable<string> GetDotNetBaseDirCandidates() {
|
||||
// Microsoft tools don't check the PATH env var, only the default locations (eg. ProgramFiles)
|
||||
var envVars = new string[] {
|
||||
"PATH",
|
||||
@ -251,7 +251,7 @@ namespace dnSpy.Documents {
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerable<FrameworkPath> GetDotNetCorePaths(string basePath, int bitness) {
|
||||
static IEnumerable<FrameworkPath> GetDotNetPaths(string basePath, int bitness) {
|
||||
if (!Directory.Exists(basePath))
|
||||
yield break;
|
||||
var sharedDir = Path.Combine(basePath, "shared");
|
||||
@ -309,8 +309,8 @@ namespace dnSpy.Documents {
|
||||
}
|
||||
}
|
||||
|
||||
public Version? TryGetDotNetCoreVersion(string filename) {
|
||||
foreach (var info in netcorePaths) {
|
||||
public Version? TryGetDotNetVersion(string filename) {
|
||||
foreach (var info in netPaths) {
|
||||
foreach (var path in info.Paths) {
|
||||
if (FileUtils.IsFileInDir(path, filename))
|
||||
return info.SystemVersion;
|
@ -55,19 +55,19 @@ namespace dnSpy.Documents {
|
||||
SystemVersion = new Version(firstPath.Version.Major, firstPath.Version.Minor, firstPath.Version.Patch, 0);
|
||||
|
||||
foreach (var p in Paths) {
|
||||
if (StringComparer.OrdinalIgnoreCase.Equals(Path.GetFileName(Path.GetDirectoryName(p)), DotNetCoreAppDir)) {
|
||||
HasDotNetCoreAppPath = true;
|
||||
if (StringComparer.OrdinalIgnoreCase.Equals(Path.GetFileName(Path.GetDirectoryName(p)), DotNetAppDir)) {
|
||||
HasDotNetAppPath = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the .NET Core dir last since it also contains some assemblies that exist in some other
|
||||
// Sort the .NET dir last since it also contains some assemblies that exist in some other
|
||||
// dirs, eg. WindowsBase.dll is in both Microsoft.NETCore.App and Microsoft.WindowsDesktop.App
|
||||
// and the one in Microsoft.NETCore.App isn't the same one WPF apps expect (it has no types).
|
||||
// There are other dupe assemblies, eg. Microsoft.Win32.Registry.dll exists both in
|
||||
// Microsoft.NETCore.App and Microsoft.WindowsDesktop.App.
|
||||
const string DotNetCoreAppDir = "Microsoft.NETCore.App";
|
||||
const string DotNetAppDir = "Microsoft.NETCore.App";
|
||||
static int SortPaths(string x, string y) {
|
||||
int c = GetPathGroupOrder(x) - GetPathGroupOrder(y);
|
||||
if (c != 0)
|
||||
@ -76,7 +76,7 @@ namespace dnSpy.Documents {
|
||||
}
|
||||
|
||||
static int GetPathGroupOrder(string path) {
|
||||
if (StringComparer.OrdinalIgnoreCase.Equals(Path.GetFileName(Path.GetDirectoryName(path)), DotNetCoreAppDir))
|
||||
if (StringComparer.OrdinalIgnoreCase.Equals(Path.GetFileName(Path.GetDirectoryName(path)), DotNetAppDir))
|
||||
return int.MaxValue;
|
||||
return 0;
|
||||
}
|
||||
@ -105,7 +105,7 @@ namespace dnSpy.Documents {
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal bool HasDotNetCoreAppPath { get; }
|
||||
internal bool HasDotNetAppPath { get; }
|
||||
}
|
||||
|
||||
// It's a class since very few of these are created
|
||||
|
@ -22,7 +22,7 @@ using dnlib.DotNet;
|
||||
|
||||
namespace dnSpy.Documents {
|
||||
readonly struct TargetFrameworkAttributeInfo {
|
||||
public bool IsDotNetCore => Framework == ".NETCoreApp";
|
||||
public bool IsDotNet => Framework == ".NETCoreApp";
|
||||
public readonly string Framework;
|
||||
public readonly Version Version;
|
||||
public readonly string Profile;
|
||||
|
@ -192,8 +192,8 @@ namespace dnSpy.MainApp {
|
||||
void Write(IDecompilerOutput output) {
|
||||
#if NETFRAMEWORK
|
||||
const string frameworkName = ".NET Framework";
|
||||
#elif NETCOREAPP
|
||||
const string frameworkName = ".NET Core";
|
||||
#elif NET
|
||||
const string frameworkName = ".NET";
|
||||
#else
|
||||
#error Unknown target framework
|
||||
#endif
|
||||
|
@ -88,8 +88,8 @@ namespace dnSpy.MainApp {
|
||||
readonly List<LoadedExtension> loadedExtensions = new List<LoadedExtension>();
|
||||
readonly IAppCommandLineArgs args;
|
||||
ExportProvider? exportProvider;
|
||||
#if NETCOREAPP
|
||||
readonly NetCoreAssemblyLoader netCoreAssemblyLoader = new NetCoreAssemblyLoader(System.Runtime.Loader.AssemblyLoadContext.Default);
|
||||
#if NET
|
||||
readonly DotNetAssemblyLoader dotNetAssemblyLoader = new DotNetAssemblyLoader(System.Runtime.Loader.AssemblyLoadContext.Default);
|
||||
#endif
|
||||
|
||||
Task<ExportProvider> initializeMEFTask;
|
||||
@ -282,8 +282,8 @@ namespace dnSpy.MainApp {
|
||||
}
|
||||
|
||||
Assembly[] GetAssemblies() {
|
||||
#if NETCOREAPP
|
||||
netCoreAssemblyLoader.AddSearchPath(AppDirectories.BinDirectory);
|
||||
#if NET
|
||||
dotNetAssemblyLoader.AddSearchPath(AppDirectories.BinDirectory);
|
||||
#endif
|
||||
var list = new List<Assembly>();
|
||||
list.Add(GetType().Assembly);
|
||||
@ -318,9 +318,9 @@ namespace dnSpy.MainApp {
|
||||
// "Understanding Background JIT compilation -> What can go wrong with background JIT compilation"
|
||||
// in the PerfView docs for more info.
|
||||
var files = unsortedFiles.OrderBy(a => a, StringComparer.OrdinalIgnoreCase).ToArray();
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
foreach (var file in files)
|
||||
netCoreAssemblyLoader.AddSearchPath(Path.GetDirectoryName(file)!);
|
||||
dotNetAssemblyLoader.AddSearchPath(Path.GetDirectoryName(file)!);
|
||||
#endif
|
||||
var asms = new List<Assembly>();
|
||||
foreach (var file in files) {
|
||||
|
@ -128,8 +128,12 @@ namespace dnSpy.MainApp {
|
||||
sc.AddChild(statusBar, StackedContentChildInfo.CreateVertical(new GridLength(0, GridUnitType.Auto)));
|
||||
mainWindow = new MainWindow(sc.UIObject);
|
||||
AddTitleInfo(IntPtr.Size == 4 ? "32-bit" : "64-bit");
|
||||
#if NETCOREAPP
|
||||
AddTitleInfo(".NET Core");
|
||||
#if NETFRAMEWORK
|
||||
AddTitleInfo(".NET Framework");
|
||||
#elif NET
|
||||
AddTitleInfo(".NET");
|
||||
#else
|
||||
#error Unknown target framework
|
||||
#endif
|
||||
#if DEBUG
|
||||
AddTitleInfo("Debug Build");
|
||||
|
@ -23,8 +23,8 @@ using System.IO;
|
||||
namespace dnSpy.MainApp {
|
||||
static class BGJitUtils {
|
||||
public static string GetFolder() {
|
||||
#if NETCOREAPP
|
||||
const string frameworkDir = "netcore";
|
||||
#if NET
|
||||
const string frameworkDir = "net";
|
||||
#elif NETFRAMEWORK
|
||||
const string frameworkDir = "netframework";
|
||||
#else
|
||||
|
@ -37,7 +37,7 @@ namespace dnSpy.MainApp {
|
||||
static string GetPathToClrDll() {
|
||||
#if NETFRAMEWORK
|
||||
const string clrDllFilename = "clr.dll";
|
||||
#elif NETCOREAPP
|
||||
#elif NET
|
||||
const string clrDllFilename = "coreclr.dll";
|
||||
#else
|
||||
#error Unknown target framework
|
||||
|
@ -17,7 +17,7 @@
|
||||
along with dnSpy. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@ -25,12 +25,12 @@ using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
|
||||
namespace dnSpy.MainApp {
|
||||
sealed class NetCoreAssemblyLoader {
|
||||
sealed class DotNetAssemblyLoader {
|
||||
string[] searchPaths;
|
||||
readonly HashSet<string> searchPathsHash;
|
||||
static readonly string[] assemblyExtensions = new string[] { ".dll" };
|
||||
|
||||
public NetCoreAssemblyLoader(AssemblyLoadContext loadContext) {
|
||||
public DotNetAssemblyLoader(AssemblyLoadContext loadContext) {
|
||||
loadContext.Resolving += AssemblyLoadContext_Resolving;
|
||||
searchPaths = Array.Empty<string>();
|
||||
searchPathsHash = new HashSet<string>(StringComparer.Ordinal);
|
@ -75,7 +75,7 @@ namespace dnSpy.MainApp.Settings {
|
||||
bool enabled = value.Value;
|
||||
|
||||
var path = Assembly.GetEntryAssembly()!.Location;
|
||||
#if NETCOREAPP
|
||||
#if NET
|
||||
// Use the native exe and not the managed file
|
||||
path = Path.ChangeExtension(path, "exe");
|
||||
if (!File.Exists(path)) {
|
||||
|
@ -31,7 +31,7 @@ namespace dnSpy.Search {
|
||||
};
|
||||
|
||||
static readonly HashSet<string> frameworkAssemblyNames = new HashSet<string>(StringComparer.Ordinal) {
|
||||
// .NET Core
|
||||
// .NET
|
||||
"Accessibility",
|
||||
"DirectWriteForwarder",
|
||||
"Microsoft.AI.DependencyCollector",
|
||||
@ -456,7 +456,7 @@ namespace dnSpy.Search {
|
||||
};
|
||||
|
||||
public static bool IsFrameworkAssembly(string filename, string? assemblySimpleName) {
|
||||
// Check if it's in one of the .NET Core runtime dirs
|
||||
// Check if it's in one of the .NET runtime dirs
|
||||
if (Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(filename))) is string baseDir && Directory.Exists(Path.Combine(baseDir, "Microsoft.NETCore.App")))
|
||||
return true;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user