internal static StateFileBase DeserializeCache(string stateFile, TaskLoggingHelper log, Type requiredReturnType) { StateFileBase o = null; try { if (((stateFile == null) || (stateFile.Length <= 0)) || !File.Exists(stateFile)) { return(o); } using (FileStream stream = new FileStream(stateFile, FileMode.Open)) { object obj2 = new BinaryFormatter().Deserialize(stream); o = obj2 as StateFileBase; if ((o == null) && (obj2 != null)) { log.LogMessageFromResources("General.CouldNotReadStateFileMessage", new object[] { stateFile, log.FormatResourceString("General.IncompatibleStateFileType", new object[0]) }); } if ((o != null) && !requiredReturnType.IsInstanceOfType(o)) { log.LogWarningWithCodeFromResources("General.CouldNotReadStateFile", new object[] { stateFile, log.FormatResourceString("General.IncompatibleStateFileType", new object[0]) }); o = null; } } } catch (Exception exception) { log.LogWarningWithCodeFromResources("General.CouldNotReadStateFile", new object[] { stateFile, exception.Message }); } return(o); }
/// <summary> /// Reads the specified file from disk into a StateFileBase derived object. /// </summary> /// <param name="stateFile"></param> /// <returns></returns> static internal StateFileBase DeserializeCache(string stateFile, TaskLoggingHelper log, Type requiredReturnType) { StateFileBase retVal = null; // First, we read the cache from disk if one exists, or if one does not exist // then we create one. try { if (!string.IsNullOrEmpty(stateFile) && File.Exists(stateFile)) { using (FileStream s = new FileStream(stateFile, FileMode.Open)) { BinaryFormatter formatter = new BinaryFormatter(); object deserializedObject = formatter.Deserialize(s); retVal = deserializedObject as StateFileBase; // If the deserialized object is null then there would be no cast error but retVal would still be null // only log the message if there would have been a cast error if (retVal == null && deserializedObject != null) { // When upgrading to Visual Studio 2008 and running the build for the first time the resource cache files are replaced which causes a cast error due // to a new version number on the tasks class. "Unable to cast object of type 'Microsoft.Build.Tasks.SystemState' to type 'Microsoft.Build.Tasks.StateFileBase”. // If there is an invalid cast, a message rather than a warning should be emitted. log.LogMessageFromResources("General.CouldNotReadStateFileMessage", stateFile, log.FormatResourceString("General.IncompatibleStateFileType")); } if ((retVal != null) && (!requiredReturnType.IsInstanceOfType(retVal))) { log.LogWarningWithCodeFromResources("General.CouldNotReadStateFile", stateFile, log.FormatResourceString("General.IncompatibleStateFileType")); retVal = null; } // If we get back a valid object and internals were changed, things are likely to be null. Check the version before we use it. if (retVal != null && retVal._serializedVersion != CurrentSerializationVersion) { log.LogMessageFromResources("General.CouldNotReadStateFileMessage", stateFile, log.FormatResourceString("General.IncompatibleStateFileType")); retVal = null; } } } } catch (Exception e) { if (ExceptionHandling.IsCriticalException(e)) { throw; } // The deserialization process seems like it can throw just about // any exception imaginable. Catch them all here. // Not being able to deserialize the cache is not an error, but we let the user know anyway. // Don't want to hold up processing just because we couldn't read the file. log.LogWarningWithCodeFromResources("General.CouldNotReadStateFile", stateFile, e.Message); } return(retVal); }
/// <summary> /// Reads the specified file from disk into a StateFileBase derived object. /// </summary> internal static StateFileBase DeserializeCache(string stateFile, TaskLoggingHelper log, Type requiredReturnType) { StateFileBase retVal = null; // First, we read the cache from disk if one exists, or if one does not exist, we create one. try { if (!string.IsNullOrEmpty(stateFile) && FileSystems.Default.FileExists(stateFile)) { using (FileStream s = File.OpenRead(stateFile)) { var translator = BinaryTranslator.GetReadTranslator(s, buffer: null); byte version = 0; translator.Translate(ref version); var constructors = requiredReturnType.GetConstructors(); foreach (var constructor in constructors) { var parameters = constructor.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ITranslator)) { retVal = constructor.Invoke(new object[] { translator }) as StateFileBase; } } // If retVal is still null or the version is wrong, log a message not a warning. This could be a valid cache with the wrong version preventing correct deserialization. // For the latter case, internals may be unexpectedly null. if (retVal == null || version != CurrentSerializationVersion) { // When upgrading to Visual Studio 2008 and running the build for the first time the resource cache files are replaced which causes a cast error due // to a new version number on the tasks class. "Unable to cast object of type 'Microsoft.Build.Tasks.SystemState' to type 'Microsoft.Build.Tasks.StateFileBase". // If there is an invalid cast, a message rather than a warning should be emitted. log.LogMessageFromResources("General.CouldNotReadStateFileMessage", stateFile, log.FormatResourceString("General.IncompatibleStateFileType")); return(null); } else if (!requiredReturnType.IsInstanceOfType(retVal)) { log.LogMessageFromResources("General.CouldNotReadStateFileMessage", stateFile, log.FormatResourceString("General.IncompatibleStateFileType")); retVal = null; } } } } catch (Exception e) when(!ExceptionHandling.IsCriticalException(e)) { // The deserialization process seems like it can throw just about // any exception imaginable. Catch them all here. // Not being able to deserialize the cache is not an error, but we let the user know anyway. // Don't want to hold up processing just because we couldn't read the file. log.LogMessageFromResources("General.CouldNotReadStateFileMessage", stateFile, e.Message); } return(retVal); }
/// <summary> /// Reads the .cache file from disk into a ResGenDependencies object. /// </summary> /// <param name="stateFile"></param> /// <param name="useSourcePath"></param> /// <returns></returns> internal static ResGenDependencies DeserializeCache(string stateFile, bool useSourcePath, TaskLoggingHelper log) { ResGenDependencies retVal = (ResGenDependencies)StateFileBase.DeserializeCache(stateFile, log, typeof(ResGenDependencies)); if (retVal == null) { retVal = new ResGenDependencies(); } // Ensure that the cache is properly initialized with respect to how resgen will // resolve linked files within .resx files. ResGen has two different // ways for resolving relative file-paths in linked files. The way // that ResGen resolved relative paths before Whidbey was always to // resolve from the current working directory. In Whidbey a new command-line // switch "/useSourcePath" instructs ResGen to use the folder that // contains the .resx file as the path from which it should resolve // relative paths. So we should base our timestamp/existence checking // on the same switch & resolve in the same manner as ResGen. retVal.UseSourcePath = useSourcePath; return(retVal); }
/// <summary> /// Task entry point /// </summary> /// <returns></returns> public override bool Execute() { AssemblyRegistrationCache cacheFile; if (AssemblyListFile != null) { cacheFile = (AssemblyRegistrationCache)StateFileBase.DeserializeCache(AssemblyListFile.ItemSpec, Log, typeof(AssemblyRegistrationCache)); // no cache file, nothing to do. In case there was a problem reading the cache file, we can't do anything anyway. if (cacheFile == null) { StateFileBase.DeleteFile(AssemblyListFile.ItemSpec, Log); return(true); } } else { if (Assemblies == null) { Log.LogErrorWithCodeFromResources("UnregisterAssembly.AssemblyPathOrStateFileIsRequired", GetType().Name); return(false); } // TypeLibFiles isn't [Required], but if it is specified, it must have the same length as Assemblies if (TypeLibFiles != null && TypeLibFiles.Length != Assemblies.Length) { Log.LogErrorWithCodeFromResources("General.TwoVectorsMustHaveSameLength", Assemblies.Length, TypeLibFiles.Length, "Assemblies", "TypeLibFiles"); return(false); } cacheFile = new AssemblyRegistrationCache(); for (int i = 0; i < Assemblies.Length; i++) { // if the type lib path is not supplied, generate default one if (TypeLibFiles != null && TypeLibFiles[i] != null && TypeLibFiles[i].ItemSpec.Length > 0) { cacheFile.AddEntry(Assemblies[i].ItemSpec, TypeLibFiles[i].ItemSpec); } else { cacheFile.AddEntry(Assemblies[i].ItemSpec, Path.ChangeExtension(Assemblies[i].ItemSpec, ".tlb")); } } } bool taskReturnValue = true; try { for (int i = 0; i < cacheFile.Count; i++) { cacheFile.GetEntry(i, out string assemblyPath, out string typeLibraryPath); try { // If one of assemblies failed to unregister, the whole task failed. // We still process the rest of assemblies though. if (!Unregister(assemblyPath, typeLibraryPath)) { taskReturnValue = false; } } catch (ArgumentException ex) // assembly path has invalid chars in it { Log.LogErrorWithCodeFromResources("General.InvalidAssemblyName", assemblyPath, ex.Message); taskReturnValue = false; } #if _DEBUG catch (Exception e) { Debug.Assert(false, "Unexpected exception in AssemblyRegistration.Execute. " + "Please log a MSBuild bug specifying the steps to reproduce the problem. " + e.Message); throw; } #endif } } finally { if (AssemblyListFile != null) { StateFileBase.DeleteFile(AssemblyListFile.ItemSpec, Log); } } return(taskReturnValue); }
public override bool Execute() { AssemblyRegistrationCache cache = null; if (this.AssemblyListFile != null) { cache = (AssemblyRegistrationCache)StateFileBase.DeserializeCache(this.AssemblyListFile.ItemSpec, base.Log, typeof(AssemblyRegistrationCache)); if (cache == null) { StateFileBase.DeleteFile(this.AssemblyListFile.ItemSpec, base.Log); return(true); } } else { if (this.Assemblies == null) { base.Log.LogErrorWithCodeFromResources("UnregisterAssembly.AssemblyPathOrStateFileIsRequired", new object[] { base.GetType().Name }); return(false); } if ((this.TypeLibFiles != null) && (this.TypeLibFiles.Length != this.Assemblies.Length)) { base.Log.LogErrorWithCodeFromResources("General.TwoVectorsMustHaveSameLength", new object[] { this.Assemblies.Length, this.TypeLibFiles.Length, "Assemblies", "TypeLibFiles" }); return(false); } cache = new AssemblyRegistrationCache(); for (int i = 0; i < this.Assemblies.Length; i++) { if (((this.TypeLibFiles != null) && (this.TypeLibFiles[i] != null)) && (this.TypeLibFiles[i].ItemSpec.Length > 0)) { cache.AddEntry(this.Assemblies[i].ItemSpec, this.TypeLibFiles[i].ItemSpec); } else { cache.AddEntry(this.Assemblies[i].ItemSpec, Path.ChangeExtension(this.Assemblies[i].ItemSpec, ".tlb")); } } } bool flag = true; try { for (int j = 0; j < cache.Count; j++) { string assemblyPath = null; string typeLibraryPath = null; cache.GetEntry(j, out assemblyPath, out typeLibraryPath); try { if (!this.Unregister(assemblyPath, typeLibraryPath)) { flag = false; } } catch (ArgumentException exception) { base.Log.LogErrorWithCodeFromResources("General.InvalidAssemblyName", new object[] { assemblyPath, exception.Message }); flag = false; } } } finally { if (this.AssemblyListFile != null) { StateFileBase.DeleteFile(this.AssemblyListFile.ItemSpec, base.Log); } } return(flag); }
/// <summary> /// Task entry point /// </summary> /// <returns></returns> override public bool Execute() { // TypeLibFiles isn't [Required], but if it is specified, it must have the same length as Assemblies if ((TypeLibFiles != null) && (TypeLibFiles.Length != Assemblies.Length)) { Log.LogErrorWithCodeFromResources("General.TwoVectorsMustHaveSameLength", Assemblies.Length, TypeLibFiles.Length, "Assemblies", "TypeLibFiles"); return(false); } if (TypeLibFiles == null) { TypeLibFiles = new TaskItem[Assemblies.Length]; } AssemblyRegistrationCache cacheFile = null; if ((AssemblyListFile != null) && (AssemblyListFile.ItemSpec.Length > 0)) { cacheFile = (AssemblyRegistrationCache)StateFileBase.DeserializeCache(AssemblyListFile.ItemSpec, Log, typeof(AssemblyRegistrationCache)); if (cacheFile == null) { cacheFile = new AssemblyRegistrationCache(); } } bool taskReturnValue = true; try { for (int i = 0; i < Assemblies.Length; i++) { try { string tlbPath; // if the type lib path is not supplied, generate default one if ((TypeLibFiles[i] != null) && (TypeLibFiles[i].ItemSpec.Length > 0)) { tlbPath = TypeLibFiles[i].ItemSpec; } else { tlbPath = Path.ChangeExtension(Assemblies[i].ItemSpec, ".tlb"); TypeLibFiles[i] = new TaskItem(tlbPath); } // If one of assemblies failed to register, the whole task failed. // We still process the rest of assemblies though. if (!Register(Assemblies[i].ItemSpec, tlbPath)) { taskReturnValue = false; } else { if (cacheFile != null) { cacheFile.AddEntry(Assemblies[i].ItemSpec, tlbPath); } } } catch (ArgumentException ex) // assembly path has invalid chars in it { Log.LogErrorWithCodeFromResources("General.InvalidAssemblyName", Assemblies[i], ex.Message); taskReturnValue = false; } #if _DEBUG catch (Exception e) { Debug.Assert(false, "Unexpected exception in AssemblyRegistration.Execute. " + "Please log a MSBuild bug specifying the steps to reproduce the problem. " + e.Message); throw; } #endif } } finally { if (cacheFile != null) { cacheFile.SerializeCache(AssemblyListFile.ItemSpec, Log); } } return(taskReturnValue); }
public override bool Execute() { if ((this.TypeLibFiles != null) && (this.TypeLibFiles.Length != this.Assemblies.Length)) { base.Log.LogErrorWithCodeFromResources("General.TwoVectorsMustHaveSameLength", new object[] { this.Assemblies.Length, this.TypeLibFiles.Length, "Assemblies", "TypeLibFiles" }); return(false); } if (this.TypeLibFiles == null) { this.TypeLibFiles = new TaskItem[this.Assemblies.Length]; } AssemblyRegistrationCache cache = null; if ((this.AssemblyListFile != null) && (this.AssemblyListFile.ItemSpec.Length > 0)) { cache = (AssemblyRegistrationCache)StateFileBase.DeserializeCache(this.AssemblyListFile.ItemSpec, base.Log, typeof(AssemblyRegistrationCache)); if (cache == null) { cache = new AssemblyRegistrationCache(); } } bool flag = true; try { for (int i = 0; i < this.Assemblies.Length; i++) { try { string itemSpec; if ((this.TypeLibFiles[i] != null) && (this.TypeLibFiles[i].ItemSpec.Length > 0)) { itemSpec = this.TypeLibFiles[i].ItemSpec; } else { itemSpec = Path.ChangeExtension(this.Assemblies[i].ItemSpec, ".tlb"); this.TypeLibFiles[i] = new TaskItem(itemSpec); } if (!this.Register(this.Assemblies[i].ItemSpec, itemSpec)) { flag = false; } else if (cache != null) { cache.AddEntry(this.Assemblies[i].ItemSpec, itemSpec); } } catch (ArgumentException exception) { base.Log.LogErrorWithCodeFromResources("General.InvalidAssemblyName", new object[] { this.Assemblies[i], exception.Message }); flag = false; } } } finally { if (cache != null) { cache.SerializeCache(this.AssemblyListFile.ItemSpec, base.Log); } } return(flag); }