mirror of https://github.com/icsharpcode/ILSpy.git
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							101 lines
						
					
					
						
							2.7 KiB
						
					
					
				
			
		
		
	
	
							101 lines
						
					
					
						
							2.7 KiB
						
					
					
				using System; | 
						|
using System.Collections.Concurrent; | 
						|
using System.IO; | 
						|
using System.Management.Automation; | 
						|
using System.Threading; | 
						|
using System.Threading.Tasks; | 
						|
 | 
						|
using ICSharpCode.Decompiler.CSharp; | 
						|
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler; | 
						|
using ICSharpCode.Decompiler.Metadata; | 
						|
 | 
						|
namespace ICSharpCode.Decompiler.PowerShell | 
						|
{ | 
						|
	[Cmdlet(VerbsCommon.Get, "DecompiledProject")] | 
						|
	[OutputType(typeof(string))] | 
						|
	public class GetDecompiledProjectCmdlet : PSCmdlet, IProgress<DecompilationProgress> | 
						|
	{ | 
						|
		[Parameter(Position = 0, Mandatory = true)] | 
						|
		public CSharpDecompiler Decompiler { get; set; } | 
						|
 | 
						|
		[Parameter(Position = 1, Mandatory = true)] | 
						|
		[Alias("PSPath", "OutputPath")] | 
						|
		[ValidateNotNullOrEmpty] | 
						|
		public string LiteralPath { get; set; } | 
						|
 | 
						|
		readonly object syncObject = new object(); | 
						|
		int completed; | 
						|
		string fileName; | 
						|
		ProgressRecord progress; | 
						|
 | 
						|
		public void Report(DecompilationProgress value) | 
						|
		{ | 
						|
			lock (syncObject) | 
						|
			{ | 
						|
				completed++; | 
						|
				progress = new ProgressRecord(1, "Decompiling " + fileName, $"Completed {completed} of {value.TotalUnits}: {value.Status}") { | 
						|
					PercentComplete = (int)(completed * 100.0 / value.TotalUnits) | 
						|
				}; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		protected override void ProcessRecord() | 
						|
		{ | 
						|
			string path = GetUnresolvedProviderPathFromPSPath(LiteralPath); | 
						|
			if (!Directory.Exists(path)) | 
						|
			{ | 
						|
				WriteObject("Destination directory must exist prior to decompilation"); | 
						|
				return; | 
						|
			} | 
						|
 | 
						|
			try | 
						|
			{ | 
						|
				var task = Task.Run(() => DoDecompile(path)); | 
						|
				int timeout = 100; | 
						|
 | 
						|
				// Give the decompiler some time to spin up all threads | 
						|
				Thread.Sleep(timeout); | 
						|
 | 
						|
				while (!task.IsCompleted) | 
						|
				{ | 
						|
					ProgressRecord progress; | 
						|
					lock (syncObject) | 
						|
					{ | 
						|
						progress = this.progress; | 
						|
						this.progress = null; | 
						|
					} | 
						|
					if (progress != null) | 
						|
					{ | 
						|
						timeout = 100; | 
						|
						WriteProgress(progress); | 
						|
					} | 
						|
					else | 
						|
					{ | 
						|
						Thread.Sleep(timeout); | 
						|
						timeout = Math.Min(1000, timeout * 2); | 
						|
					} | 
						|
				} | 
						|
 | 
						|
				task.Wait(); | 
						|
 | 
						|
				WriteProgress(new ProgressRecord(1, "Decompiling " + fileName, "Decompilation finished") { RecordType = ProgressRecordType.Completed }); | 
						|
			} | 
						|
			catch (Exception e) | 
						|
			{ | 
						|
				WriteVerbose(e.ToString()); | 
						|
				WriteError(new ErrorRecord(e, ErrorIds.DecompilationFailed, ErrorCategory.OperationStopped, null)); | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		private void DoDecompile(string path) | 
						|
		{ | 
						|
			PEFile module = Decompiler.TypeSystem.MainModule.PEFile; | 
						|
			var assemblyResolver = new UniversalAssemblyResolver(module.FileName, false, module.Metadata.DetectTargetFrameworkId()); | 
						|
			WholeProjectDecompiler decompiler = new WholeProjectDecompiler(assemblyResolver); | 
						|
			decompiler.ProgressIndicator = this; | 
						|
			fileName = module.FileName; | 
						|
			completed = 0; | 
						|
			decompiler.DecompileProject(module, path); | 
						|
		} | 
						|
	} | 
						|
}
 | 
						|
 |