void Write(AssemblyDefinition assemblyToPatch, NPath assemblyToPatchPath, PatchOptions patchOptions = default) { // atomic write of file with backup // TODO: skip backup if existing file already patched. want the .orig to only be the unpatched file. // write to tmp and release the lock var tmpPath = assemblyToPatchPath.ChangeExtension(".tmp"); tmpPath.DeleteIfExists(); assemblyToPatch.Write(tmpPath); // $$$ , new WriterParameters { WriteSymbols = true }); see https://github.com/jbevain/cecil/issues/421 assemblyToPatch.Dispose(); // TODO: peverify obviously won't work with memory written streams. also needs all the dependencies. // solution is to create a temp folder, write the patched dll there as well as any of its direct dependencies, and run peverify if ((patchOptions & PatchOptions.SkipPeVerify) == 0) { PeVerify.Verify(tmpPath); } // move the actual file to backup, and move the tmp to actual var backupPath = ElevatedWeaver.GetPatchBackupPathFor(assemblyToPatchPath); File.Replace(tmpPath, assemblyToPatchPath, backupPath); }
public void OneTimeSetUp() { var testAssemblyPath = Compile(GetType().Name, k_FixtureTestCode); var results = ElevatedWeaver.PatchAllDependentAssemblies(testAssemblyPath, PatchOptions.PatchTestAssembly); results.Count.ShouldBe(2); results.ShouldContain(new PatchResult("mscorlib", null, PatchState.IgnoredForeignAssembly)); results.ShouldContain(new PatchResult(testAssemblyPath, ElevatedWeaver.GetPatchBackupPathFor(testAssemblyPath), PatchState.Patched)); m_TestAssembly = AssemblyDefinition.ReadAssembly(testAssemblyPath); MockInjector.IsPatched(m_TestAssembly).ShouldBeTrue(); }
public TestAssembly(string assemblyName, string testSourceCodeFile) { var outputFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); outputFolder.ShouldNotBeNull(); m_TestAssemblyPath = Path.Combine(outputFolder, assemblyName + ".dll"); var compiler = new Microsoft.CSharp.CSharpCodeProvider(); var compilerArgs = new CompilerParameters { OutputAssembly = m_TestAssemblyPath, IncludeDebugInformation = true, CompilerOptions = "/o- /debug+ /warn:0" }; compilerArgs.ReferencedAssemblies.Add(typeof(Enumerable).Assembly.Location); var compilerResult = compiler.CompileAssemblyFromSource(compilerArgs, testSourceCodeFile); if (compilerResult.Errors.Count > 0) { var errorText = compilerResult.Errors .OfType <CompilerError>() .Select(e => $"({e.Line},{e.Column}): error {e.ErrorNumber}: {e.ErrorText}") .Prepend("Compiler errors:") .StringJoin("\n"); throw new Exception(errorText); } m_TestAssemblyPath = compilerResult.PathToAssembly; PeVerify.Verify(m_TestAssemblyPath); // pre-check..sometimes we can compile code that doesn't verify var results = ElevatedWeaver.PatchAllDependentAssemblies(m_TestAssemblyPath, PatchTestAssembly.Yes); results.Count.ShouldBe(2); results.ShouldContain(new PatchResult("mscorlib", null, PatchState.IgnoredOutsideAllowedPaths)); results.ShouldContain(new PatchResult(m_TestAssemblyPath, ElevatedWeaver.GetPatchBackupPathFor(m_TestAssemblyPath), PatchState.Patched)); m_TestAssembly = AssemblyDefinition.ReadAssembly(m_TestAssemblyPath); MockInjector.IsPatched(m_TestAssembly).ShouldBeTrue(); PeVerify.Verify(m_TestAssemblyPath); }