/// <exception cref="ArgumentNullException"><paramref name="fullPath"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="fullPath"/> is not an absolute path.</exception> public override PortableExecutableReference GetReference(string fullPath, MetadataReferenceProperties properties = default(MetadataReferenceProperties)) { CompilerFileUtilities.RequireAbsolutePath(fullPath, "fullPath"); // return a new reference - whenever we are asked for a reference the consumer wants a new snapshot return(new ShadowCopyReference(this, fullPath, properties)); }
/// <summary> /// Determine whether given path is under the shadow-copy directory managed by this shadow-copy provider. /// </summary> /// <param name="fullPath">Absolute path.</param> /// <exception cref="ArgumentNullException"><paramref name="fullPath"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="fullPath"/> is not an absolute path.</exception> public bool IsShadowCopy(string fullPath) { CompilerFileUtilities.RequireAbsolutePath(fullPath, "fullPath"); string directory = ShadowCopyDirectory; return(directory != null && NormalizePath(fullPath).StartsWith(directory, StringComparison.OrdinalIgnoreCase)); }
/// <summary> /// Suppresses shadow-coping of specified path. /// </summary> /// <param name="originalPath">Full path.</param> /// <exception cref="ArgumentNullException"><paramref name="originalPath"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="originalPath"/> is not an absolute path.</exception> /// <remarks> /// Doesn't affect files that have already been shadow-copied. /// </remarks> public void SuppressShadowCopy(string originalPath) { CompilerFileUtilities.RequireAbsolutePath(originalPath, "originalPath"); lock (Guard) { if (lazySuppressedFiles == null) { lazySuppressedFiles = new HashSet <string>(StringComparer.OrdinalIgnoreCase); } lazySuppressedFiles.Add(originalPath); } }
/// <summary> /// Determines whether given file is a candidate for shadow-copy. /// </summary> /// <param name="fullPath">An absolute path.</param> /// <returns>True if the shadow-copy policy applies to the specified path.</returns> /// <exception cref="NullReferenceException"><paramref name="fullPath"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="fullPath"/> is not absolute.</exception> public bool NeedsShadowCopy(string fullPath) { CompilerFileUtilities.RequireAbsolutePath(fullPath, "fullPath"); string directory = Path.GetDirectoryName(fullPath); // do not shadow-copy shadow-copies: string referencesDir = ShadowCopyDirectory; if (referencesDir != null && directory.StartsWith(referencesDir, StringComparison.OrdinalIgnoreCase)) { return(false); } return(!noShadowCopyDirectories.Any(dir => directory.StartsWith(dir, StringComparison.OrdinalIgnoreCase))); }
/// <summary> /// Creates an instance of <see cref="MetadataShadowCopyProvider"/>. /// </summary> /// <param name="directory">The directory to use to store file copies.</param> /// <param name="noShadowCopyDirectories">Directories to exclude from shadow-copying.</param> /// <exception cref="ArgumentNullException"><paramref name="directory"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="directory"/> is not an absolute path.</exception> public MetadataShadowCopyProvider(string directory = null, IEnumerable <string> noShadowCopyDirectories = null) { if (directory != null) { CompilerFileUtilities.RequireAbsolutePath(directory, "directory"); this.baseDirectory = directory; } else { this.baseDirectory = Path.Combine(Path.GetTempPath(), "Roslyn", "MetadataShadowCopyProvider"); } this.noShadowCopyDirectories = (noShadowCopyDirectories != null ? noShadowCopyDirectories.Select(dir => NormalizePath(dir)).ToArray() : SpecializedCollections.EmptyArray <string>()) .Concat(frameworkNoShadowCopyDirectories); // We want to be sure to delete the shadow-copied files when the process goes away. Frankly // there's nothing we can do if the process is forcefully quit or goes down in a completely // uncontrolled manner (like a stack overflow). When the process goes down in a controlled // manned, we should generally expect this event to be called. AppDomain.CurrentDomain.ProcessExit += HandleProcessExit; }