public ReWriter(string filePath, bool useDepsJson = true) { References = new List <string>(); _typeCache = new ConcurrentDictionary <string, Type>(); _cache = new ConcurrentDictionary <string, string>(); var domain = DomainManagment.Random; OldPath = filePath; _complier = new AssemblyComplier { Domain = domain, EnumCRTarget = ComplierResultTarget.File, AssemblyName = Path.GetFileNameWithoutExtension(filePath) }; _pluginDomain = DomainManagment.Random; _assembly = _pluginDomain.LoadStream(filePath); CSharpDecompiler _decomplier; if (useDepsJson) { var module = new PEFile(filePath); var resolver = new UniversalAssemblyResolver(filePath, false, module.Reader.DetectTargetFrameworkId()); _decomplier = new CSharpDecompiler(filePath, resolver, _setting); } else { _decomplier = new CSharpDecompiler(filePath, _setting); } foreach (var item in _assembly.ExportedTypes) { var temp = item.GetDevelopName(); _typeCache[temp] = item; _cache[temp] = _decomplier.DecompileTypeAsString(new FullTypeName(item.FullName)); } }
/// <summary> /// 获取编译后的程序集 /// </summary> /// <param name="content">脚本内容</param> /// <returns></returns> public Assembly GetAssemblyByScript(string content) { if (Domain == null) { Domain = AssemblyManagment.Default; } Exception.Source = content; Assembly assembly = ScriptComplierEngine.StreamComplier(content, Domain, out Exception.Formatter, ref Exception.Diagnostics); //判空 if (assembly == default || assembly == null) { Exception.ErrorFlag = ComplieError.Assembly; Exception.Message = "发生错误,无法生成程序集!"; } return(assembly); }
static void Main(string[] args) { AssemblyDomain.Init(); var hwFunc = FastMethodOperator .RandomDomain() .Param(typeof(string), "str1") .Param <string>("str2") .Body("return str1+str2;") .Return <string>() .Compile <Func <string, string, string> >(); Console.WriteLine(hwFunc("Hello", " World!")); var a123 = NClass.UseDomain(typeof(Program).GetDomain()); var domain = DomainManagement.Random; var type = NDelegate.UseDomain(domain).GetType("public class A{ public A(){Name=\"1\"; }public string Name;}"); var func = NDelegate.UseDomain(domain).Func <string>("return (new A()).Name;"); Console.WriteLine(type.FullName); Console.WriteLine(func()); type.RemoveReferences(); type = NDelegate.UseDomain(domain).GetType("public class A{ public A(){Name=\"2\"; }public string Name;}"); func = NDelegate.UseDomain(domain).Func <string>("return (new A()).Name;"); Console.WriteLine(type.FullName); Console.WriteLine(func()); domain = DomainManagement.Create("a"); using (DomainManagement.Lock("a")) { Console.WriteLine(domain == (AssemblyDomain)AssemblyLoadContext.CurrentContextualReflectionContext); } Console.ReadKey(); }
static DomainInitTemplate() { AssemblyDomain.Init(); }
/// <summary> /// 使用内存流进行脚本编译 /// </summary> /// <param name="sourceContent">脚本内容</param> /// <param name="errorAction">发生错误执行委托</param> /// <returns></returns> public static Assembly StreamComplier(string sourceContent, AssemblyDomain domain, out string formatContent, ref List <Diagnostic> diagnostics) { lock (domain) { var(tree, typeNames, formatter, errors) = GetTreeInfo(sourceContent.Trim()); formatContent = formatter; diagnostics.AddRange(errors); if (diagnostics.Count() != 0) { return(null); } if (domain.ClassMapping.ContainsKey(typeNames[0])) { return(domain.ClassMapping[typeNames[0]]); } //创建语言编译 CSharpCompilation compilation = CSharpCompilation.Create( typeNames[0], options: new CSharpCompilationOptions( outputKind: OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Release, allowUnsafe: true), syntaxTrees: new[] { tree }, references: domain.References); //编译并生成程序集 using (MemoryStream stream = new MemoryStream()) { var fileResult = compilation.Emit(stream); if (fileResult.Success) { stream.Position = 0; var result = domain.LoadFromStream(stream); domain.CacheAssembly(result, stream); if (NSucceed.Enabled) { NSucceed logSucceed = new NSucceed(); logSucceed.WrapperCode(formatter); logSucceed.Handler(compilation, result); } return(result); } else { diagnostics.AddRange(fileResult.Diagnostics); if (NError.Enabled) { NError logError = new NError(); logError.WrapperCode(formatter); logError.Handler(compilation, fileResult.Diagnostics); logError.Write(); } } } } return(null); }
public Form1() { InitializeComponent(); AssemblyDomain.Init(); }
static PrepareTest() { AssemblyDomain.Init(); }
public T UseDomain(AssemblyDomain domain) { Complier.Domain = domain; return(Link); }
static ComplierModel() { _default = new AssemblyDomain("Default"); }
public static T Create(AssemblyDomain domain, ComplierResultError error, ComplierResultTarget target = ComplierResultTarget.Stream) { return(Create(domain, target, error)); }
public T InDomain(AssemblyDomain domain) { Domain = domain; return(Link); }
static InitMapperBuilder() { AssemblyDomain.Init(); }
private static int Main(string[] args) { var recursiveFlag = SearchOption.TopDirectoryOnly; var enableCrossCheck = false; var rootFolder = ""; foreach (var argument in args) { if (argument == "-r" || argument == "/r") { recursiveFlag = SearchOption.AllDirectories; } else if (argument == "-c" || argument == "/c") { enableCrossCheck = true; } else if (argument == "-v" || argument == "/v") { _verbose = true; } else if (string.IsNullOrEmpty(rootFolder)) { rootFolder = argument; } } if (string.IsNullOrEmpty(rootFolder)) { Console.WriteLine("No root folder specified."); Console.WriteLine(HelpString); return((int)ErrorLevel.MissingRootFolder); } const string configFileType = "*.config"; string[] dllFileType = { "*.exe", "*.dll" }; string[] filesList; var outdatedList = new List <ReportItem>(); //check .config file references try { filesList = Directory.GetFiles(rootFolder, configFileType, recursiveFlag); } catch (Exception e) { Console.WriteLine("File search exception: " + e + Environment.NewLine + "Possibly a file system link found."); return((int)ErrorLevel.FileSearchError); } var domain = new AssemblyDomain(); Parallel.ForEach(filesList, fromFile => { var config = new XmlDocument(); try { config.Load(fromFile); } catch { // not XML file, skip it return; } var assemblyNodes = config.GetElementsByTagName("dependentAssembly"); if (assemblyNodes.Count <= 0) { // no assembly references, skip it return; } // process each assembly reference in the .config file foreach (XmlNode node in assemblyNodes) { // get assembly name from config var dllFileNode = node["assemblyIdentity"]; if (dllFileNode == null) { // no DLL name fixed in XML, skip it continue; } var dllFileName = ""; foreach (XmlAttribute attribute in dllFileNode.Attributes) { if (attribute.Name == "name") { // DLL name tag found in XML dllFileName = attribute.Value; break; } } if (string.IsNullOrEmpty(dllFileName)) { // DLL name tag not found in XML, skip it continue; } // get assembly version from config var dllVersionNode = node["bindingRedirect"]; if (dllVersionNode == null) { // no DLL version tag found in XML continue; } Version expectedVersion = null; foreach (XmlAttribute attribute in dllVersionNode.Attributes) { if (attribute.Name == "newVersion") { try { expectedVersion = new Version(attribute.Value); } catch { } // DLL version tag found in XML break; } } if (expectedVersion == null) { // DLL version tag not found in XML, skip it continue; } // Get file version. var dllFullFileName = FilePath(fromFile) + dllFileName + ".dll"; Version dllVersion; try { dllVersion = AssemblyName.GetAssemblyName(dllFullFileName).Version; } catch { // no such DLL in the folder or error opening it //Console.WriteLine("Can't open file: " + dllPath); continue; } if (dllVersion == null) { // can't get file version, skip it continue; } if (dllVersion < expectedVersion) { var fromFileItem = new FileItem(fromFile, expectedVersion); var rptList = outdatedList.FindAll(x => x.AssemblyFile.FullFileName == dllFullFileName); if (rptList.Count > 1) { Console.WriteLine("Duplicate assembly name in collection: " + dllFullFileName); } if (rptList.Count <= 0) { var rpt = new ReportItem(dllFullFileName, dllVersion); rpt.CalledFromFiles.Add(fromFileItem); outdatedList.Add(rpt); } else if (rptList.Count == 1) { rptList[0].CalledFromFiles.Add(fromFileItem); } } } }); // collect folder assembly collection var assemblyList = new BlockingCollection <AssemblyInfoItem>(); foreach (var fileType in dllFileType) { try { filesList = Directory.GetFiles(rootFolder, fileType, recursiveFlag); } catch (Exception e) { Console.WriteLine("File search exception: " + e + Environment.NewLine + "Possibly a file system link found."); return((int)ErrorLevel.FileSearchError); } var fileNum = filesList.Length; foreach (var file in filesList) { var newAssembly = domain.GetAssemblyInfo(file); assemblyList.Add(newAssembly); fileNum--; } } domain.Unload(); var crossList = new List <CrossReportItem>(); // check references for files grouped by folder while (true) { var activeFiles = assemblyList.Where(x => !x.Processed); if (activeFiles == null || !activeFiles.Any()) { break; } var currentPath = activeFiles.First().FilePath; var folderFiles = assemblyList.Where(x => x.FilePath == currentPath); foreach (var srcDllFile in folderFiles) { srcDllFile.Processed = true; //check cross-references for different versions if (enableCrossCheck) { var verList = new CrossReportItem(srcDllFile.FullFileName, srcDllFile.FileVersion); foreach (var refFromFile in folderFiles) { if (srcDllFile.FileName == refFromFile.FileName) { continue; } foreach (var referenceItem in refFromFile.ReferenceList) { if (referenceItem.FullFileName == srcDllFile.FileName) { if (!verList.CalledFromFiles.ContainsKey(referenceItem.FileVersion)) { verList.CalledFromFiles.Add(referenceItem.FileVersion, refFromFile.FileName); } } } } if (verList.CalledFromFiles.Count > 1) { crossList.Add(verList); } } if (srcDllFile.ReferenceList == null || srcDllFile.ReferenceList.Count <= 0) { continue; } // check for files with version other than required by caller foreach (var refFile in srcDllFile.ReferenceList) { var foundFiles = folderFiles.Where(x => x.FileName == refFile.FileName); if (foundFiles.Any()) { if (foundFiles.Count() > 1) { Console.WriteLine("Duplicate assembly name in collection: " + refFile.FileName); } var element = foundFiles.First(); if (element.FileVersion < refFile.FileVersion) { var fromFileItem = new FileItem(srcDllFile.FullFileName, refFile.FileVersion); var rptList = outdatedList.Where(x => x.AssemblyFile.FullFileName == element.FullFileName); if (!rptList.Any()) { var rpt = new ReportItem(element.FullFileName, element.FileVersion); rpt.CalledFromFiles.Add(fromFileItem); outdatedList.Add(rpt); } else { rptList.First().CalledFromFiles.Add(fromFileItem); } } } } } } var errorLevel = ErrorLevel.NoError; // generate report to console if (crossList.Any()) { Console.WriteLine("Assembly files reference check:"); errorLevel = ErrorLevel.MultiReference; foreach (var reportItem in crossList) { Console.WriteLine(reportItem.AssemblyFile + "[" + reportItem.AssemblyFileVersion + "] cross-referenced by:"); foreach (var fileItem in reportItem.CalledFromFiles) { Console.WriteLine("\tv." + fileItem.Key + " expected by " + fileItem.Value); } } } // generate batch file to get correct files if any if (outdatedList.Count > 0) { Console.WriteLine("Assembly files reference check:"); errorLevel = ErrorLevel.RecoverableErrors; var currentDir = ""; var copyCommand = new StringBuilder(); foreach (var report in outdatedList) { if (report.AssemblyFile.FilePath != currentDir) { currentDir = report.AssemblyFile.FilePath; Console.WriteLine(currentDir + ":"); } Console.WriteLine("\t" + report.AssemblyFile.FileName + " v." + report.AssemblyFile.FileVersion + " outdated"); foreach (var refFile in report.CalledFromFiles) { Console.WriteLine("\t\tv." + refFile.FileVersion + " expected by " + refFile.FileName); var correctFile = assemblyList.FirstOrDefault(x => x.FileName == report.AssemblyFile.FileName && x.FileVersion == refFile.FileVersion); if (correctFile != null) { copyCommand.AppendLine("rem v." + correctFile.FileVersion + " => " + report.AssemblyFile.FileVersion); copyCommand.AppendLine("copy " + correctFile.FullFileName + " " + report.AssemblyFile.FullFileName); } else { copyCommand.AppendLine("rem v." + refFile.FileVersion + " => " + report.AssemblyFile.FileVersion); copyCommand.AppendLine("rem copy " + "_from_repository_" + " " + report.AssemblyFile.FullFileName); errorLevel = ErrorLevel.UnRecoverableErrors; } } } if (copyCommand.Length > 0) { File.WriteAllText("fix.bat", copyCommand.ToString()); } } return((int)errorLevel); }
public AssemblyUnitInfo(AssemblyDomain context, string path) : this(context, new FileStream(path, FileMode.Open)) { }