⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filedisassemblerhelper.cs

📁 VS.NET2003插件开发电子书
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using System.Collections;
using System.Collections.Specialized;
using System.IO;
using System.Resources;
using System.Xml;
using Reflector.CodeModel;
using Reflector.CodeModel.Memory;

namespace Reflector.FileDisassembler
{
	/// <summary>
	/// Summary description for FileDisassemblerHelper.
	/// </summary>
	public class FileDisassemblerHelper
	{
		public delegate void WriteLineDelegate(string line);
		public delegate void SetProgressBarDelegate(int pos);

		private IAssemblyManager _assemblyManager;
		private ILanguageManager _languageManager;
		private ITranslatorManager _TranslatorManager;

		private int _projectType = -1;
		private string _outputDirectory = string.Empty;

		private event WriteLineDelegate WriteLine;
		private event SetProgressBarDelegate SetProgressBar;

		private StringCollection _projectFiles = new StringCollection();

		public FileDisassemblerHelper(
			IAssemblyManager assemblyManager,
			ITranslatorManager TranslatorManager,
			ILanguageManager languageManager,
			int projectType,
			string outputDirectory,
			WriteLineDelegate writeLineDelegate,
			SetProgressBarDelegate setProgressBarDelegate)
		{
			_assemblyManager = assemblyManager;
			_TranslatorManager = TranslatorManager;
			_languageManager = languageManager;
			_projectType = projectType;
			_outputDirectory = outputDirectory;
			WriteLine += writeLineDelegate;
			SetProgressBar += setProgressBarDelegate;
		}

		public ILanguageManager LanguageManager
		{
			get { return _languageManager; }
		}

		public ITranslatorManager TranslatorManager
		{
			get { return _TranslatorManager; }
		}

		public IAssemblyManager AssemblyManager
		{
			get	{ return _assemblyManager; }
		}

		public int GenerateCode(object activeItem)
		{
			int exceptions = 0;

			ILanguageWriterConfiguration configuration = new LanguageWriterConfiguration();
			IAssemblyResolver resolver = AssemblyManager.Resolver;
			AssemblyManager.Resolver = new AssemblyResolver(resolver);
			try
			{
				// write assembly
				IAssembly assembly = activeItem as IAssembly;
				if (assembly != null)
				{
					// calc progress bar count
					int pos = 0;
					int count = 2; // 1 for the assembly info, 1 for the project
					foreach (IModule module in assembly.Modules)
					{
						count += module.Types.Count;
					}
					count += assembly.Resources.Count;

					// write assembly info
					exceptions += WriteAssemblyInfo(assembly, configuration);
					SetProgressBar((++pos * 100) / count);

					// write modules
					string location = string.Empty;
					foreach (IModule module in assembly.Modules)
					{
						if (module.Location != location)
							location = module.Location;

						foreach (ITypeDeclaration typeDeclaration in module.Types)
						{
							if ((typeDeclaration.Namespace.Length != 0) || (
								(typeDeclaration.Name != "<Module>") &&
								(typeDeclaration.Name != "<PrivateImplementationDetails>")))
							{
								exceptions += WriteTypeDeclaration(typeDeclaration, configuration);
							}
							SetProgressBar((++pos * 100) / count);
						}
					}

					// write resources
					foreach (IResource resource in assembly.Resources)
					{
						exceptions += WriteResource(resource);
						SetProgressBar((++pos * 100) / count);
					}

					GenerateVisualStudioProject(assembly.Name, _outputDirectory, assembly.Modules[0].AssemblyReferences);
					SetProgressBar((++pos * 100) / count);
				}

					// write single item
				else if (activeItem is ITypeDeclaration)
				{
					ITypeDeclaration typeDeclaration = activeItem as ITypeDeclaration;
					if ((typeDeclaration.Namespace.Length != 0) || (
						(typeDeclaration.Name != "<Module>") &&
						(typeDeclaration.Name != "<PrivateImplementationDetails>")))
					{
						exceptions += WriteTypeDeclaration(typeDeclaration, configuration);
					}
				}
			}
			catch (Exception ex)
			{
				WriteLine("Error: " + ex.Message + Environment.NewLine + ex.StackTrace);
				exceptions++;
			}
			finally
			{
				AssemblyManager.Resolver = resolver;
			}
			return exceptions;
		}

		private int WriteAssemblyInfo(IAssembly assembly, ILanguageWriterConfiguration configuration)
		{
			ILanguage language = LanguageManager.ActiveLanguage;
			ITranslator translator = TranslatorManager.CreateDisassembler("Xml", null);

			int exceptions = 0;

			using (StreamWriter streamWriter = CreateFile(string.Empty, "AssemblyInfo"))
			{
				TextFormatter formatter = new TextFormatter();
				try
				{
					ILanguageWriter writer = language.GetWriter(formatter, configuration);
					assembly = translator.TranslateAssembly(assembly, false);
					writer.WriteAssembly(assembly);

					foreach (IModule module in assembly.Modules)
					{
						IModule visitedModule = translator.TranslateModule(module, false);
						writer.WriteModule(visitedModule);

						foreach (IAssemblyReference assemblyReference in module.AssemblyReferences)
						{
							IAssemblyReference visitedAssemblyReference = translator.TranslateAssemblyReference(assemblyReference);
							writer.WriteAssemblyReference(visitedAssemblyReference);
						}

						foreach (IModuleReference moduleReference in module.ModuleReferences)
						{
							IModuleReference visitedModuleReference = translator.TranslateModuleReference(moduleReference);
							writer.WriteModuleReference(visitedModuleReference);
						}
					}

					foreach (IResource resource in assembly.Resources)
					{
						writer.WriteResource(resource);
					}
				}
				catch (Exception exception)
				{
					streamWriter.WriteLine(exception.ToString());
					WriteLine(exception.ToString());
					exceptions++;
				}

				string output = formatter.ToString().Replace("\r\n", "\n").Replace("\n", "\r\n");
				streamWriter.WriteLine(output);
			}
			return exceptions;
		}
		
		private int WriteTypeDeclaration(ITypeDeclaration typeDeclaration, ILanguageWriterConfiguration configuration)
		{
			ILanguage language = LanguageManager.ActiveLanguage;
			ITranslator translator = TranslatorManager.CreateDisassembler("Xml", null);

			int exceptions = 0;
			using (StreamWriter streamWriter = CreateTypeDeclarationFile(typeDeclaration))
			{
				INamespace namespaceItem = new Namespace();
				namespaceItem.Name = typeDeclaration.Namespace;

				try
				{
					if (language.Translate)
					{
						typeDeclaration = translator.TranslateTypeDeclaration(typeDeclaration, true, true);
					}
					namespaceItem.Types.Add(typeDeclaration);
				}
				catch (Exception ex)
				{
					streamWriter.WriteLine(ex.ToString());
					WriteLine(ex.ToString());
					exceptions++;
				}
				
				TextFormatter formatter = new TextFormatter();
				ILanguageWriter writer = language.GetWriter(formatter, configuration);
				try
				{
					writer.WriteNamespace(namespaceItem);
				}
				catch (Exception exception)
				{
					streamWriter.WriteLine(exception.ToString());
					WriteLine(exception.ToString());
				}

				string output = formatter.ToString().Replace("\r\n", "\n").Replace("\n", "\r\n");
				streamWriter.WriteLine(output);
			}
			
			return exceptions;
		}

		private StreamWriter CreateTypeDeclarationFile(ITypeDeclaration typeDeclaration)
		{
			string directory = typeDeclaration.Namespace;

			string fileName = typeDeclaration.Name;
			if (typeDeclaration.GenericArguments.Count > 0)
			{
				fileName = fileName + "!" +	typeDeclaration.GenericArguments.Count.ToString();
			}

			return CreateFile(directory, fileName);
		}

		private StreamWriter CreateFile(string directory, string fileName)
		{
			//somehow Path.InvalidPathChars does not include all invalid chars
			ArrayList invalidPathChars = new ArrayList();
			invalidPathChars.AddRange(Path.InvalidPathChars);
			invalidPathChars.Add('^');
			invalidPathChars.Add('<');
			invalidPathChars.Add('>');
			invalidPathChars.Add(':');
			invalidPathChars.Add('|');
			invalidPathChars.Add('?');
			invalidPathChars.Add('*');

			foreach(char invalidChar in invalidPathChars)
				directory = directory.Replace(invalidChar, '_');

			directory = Path.Combine(_outputDirectory, directory);

			if (!Directory.Exists(directory))
			{
				Directory.CreateDirectory(directory);
			}

			ILanguage language = LanguageManager.ActiveLanguage;
			string fileExtension = language.FileExtension;

			foreach(char invalidChar in invalidPathChars)
				fileName = fileName.Replace(invalidChar, '_');

			fileName = Path.Combine(directory, fileName);
			fileName = Path.ChangeExtension(fileName, fileExtension);

			AddToProjectFiles(fileName);

			StreamWriter writer = null;
			try
			{
				writer = new StreamWriter(fileName);
			}
			catch(NotSupportedException ex)
			{
				throw new ApplicationException(string.Format("Could not create file '{0}'", fileName), ex);
			}
			return writer;
		}

		private int WriteResource(IResource resource)
		{
			IEmbeddedResource embeddedResource = resource as IEmbeddedResource;
			if (embeddedResource != null)
			{
				try 
				{
					byte[] buffer = embeddedResource.Value;
					string fileName = Path.Combine(_outputDirectory, resource.Name);
					
					if (resource.Name.EndsWith(".resources"))
					{
						fileName = Path.ChangeExtension(fileName, ".resx");
						using (MemoryStream ms = new MemoryStream(embeddedResource.Value))
						{
							ResXResourceWriter resxw = new ResXResourceWriter(fileName);
							IResourceReader reader = new ResourceReader(ms);
							IDictionaryEnumerator en = reader.GetEnumerator();
							while (en.MoveNext()) 
							{
								resxw.AddResource(en.Key.ToString(), en.Value);
							}
							reader.Close();
							resxw.Close();
						}
					}
					else // other embedded resource
					{
						if (buffer != null)
						{
							using (Stream stream = File.Create(fileName))
							{
								stream.Write(buffer, 0, buffer.Length);
							}
						}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -