Пример #1
0
        private CacheEntry <MetadataShadowCopy> CreateMetadataShadowCopy(string originalPath, MetadataImageKind kind)
        {
            int attempts = 10;

            while (true)
            {
                try
                {
                    if (ShadowCopyDirectory == null)
                    {
                        ShadowCopyDirectory = CreateUniqueDirectory(baseDirectory);
                    }

                    // Create directory for the assembly.
                    // If the assembly has any modules they have to be copied to the same directory
                    // and have the same names as specified in metadata.
                    string assemblyDir        = CreateUniqueDirectory(ShadowCopyDirectory);
                    string shadowCopyPath     = Path.Combine(assemblyDir, Path.GetFileName(originalPath));
                    var    manifestModuleCopy = CopyFile(originalPath, shadowCopyPath);
                    Debug.Assert(manifestModuleCopy != null);

                    ShadowCopy documentationFileCopy = null;
                    string     xmlDocumentationFilePath;
                    if (TryFindXmlDocumentationFile(originalPath, out xmlDocumentationFilePath))
                    {
                        // TODO (tomat): how do doc comments work for multi-module assembly?
                        var xmlShadowCopyPath = Path.ChangeExtension(shadowCopyPath, ".xml");
                        documentationFileCopy = CopyFile(xmlDocumentationFilePath, xmlShadowCopyPath, fileMayNotExist: true);
                    }

                    Metadata privateMetadata;
                    if (kind == MetadataImageKind.Assembly)
                    {
                        privateMetadata = CreateAssemblyMetadata(manifestModuleCopy);
                    }
                    else
                    {
                        privateMetadata = CreateModuleMetadata(manifestModuleCopy);
                    }

                    var publicMetadata = privateMetadata.Copy();
                    return(new CacheEntry <MetadataShadowCopy>(new MetadataShadowCopy(manifestModuleCopy, documentationFileCopy, publicMetadata), privateMetadata));
                }
                catch (DirectoryNotFoundException)
                {
                    // the shadow copy directory has been deleted - try to copy all files again
                    if (!Directory.Exists(ShadowCopyDirectory))
                    {
                        ShadowCopyDirectory = null;
                        if (attempts-- > 0)
                        {
                            continue;
                        }
                    }

                    throw;
                }
            }
        }
Пример #2
0
        internal MetadataShadowCopy(ShadowCopy primaryModule, ShadowCopy documentationFile, Metadata metadataCopy)
        {
            Debug.Assert(primaryModule != null);
            Debug.Assert(metadataCopy != null);
            Debug.Assert(!metadataCopy.IsImageOwner);

            this.primaryModule     = primaryModule;
            this.documentationFile = documentationFile;
            this.metadataCopy      = metadataCopy;
        }
Пример #3
0
        internal MetadataShadowCopy(ShadowCopy primaryModule, ShadowCopy documentationFile, Metadata metadataCopy)
        {
            Debug.Assert(primaryModule != null);
            Debug.Assert(metadataCopy != null);
            Debug.Assert(!metadataCopy.IsImageOwner);

            this.primaryModule = primaryModule;
            this.documentationFile = documentationFile;
            this.metadataCopy = metadataCopy;
        }
Пример #4
0
 private static ModuleMetadata CreateModuleMetadata(ShadowCopy copy)
 {
     try
     {
         return(new ModuleMetadata(copy.FullPath, copy.Stream.SafeFileHandle));
     }
     finally
     {
         // close the file handle, it's now memory mapped and locked:
         copy.DisposeFileStream();
     }
 }
Пример #5
0
        private AssemblyMetadata CreateAssemblyMetadata(ShadowCopy manifestModuleCopy)
        {
            // We don't need to use the global metadata cache here since the shadow copy
            // won't change and is private to us - only users of the same shadow copy provider see it.

            ArrayBuilder <ModuleMetadata> moduleBuilder = null;

            bool           fault          = true;
            ModuleMetadata manifestModule = null;

            try
            {
                manifestModule = CreateModuleMetadata(manifestModuleCopy);

                string originalDirectory = null, shadowCopyDirectory = null;
                foreach (string moduleName in manifestModule.GetModuleNames())
                {
                    if (moduleBuilder == null)
                    {
                        moduleBuilder = ArrayBuilder <ModuleMetadata> .GetInstance();

                        moduleBuilder.Add(manifestModule);
                        originalDirectory   = Path.GetDirectoryName(manifestModuleCopy.OriginalPath);
                        shadowCopyDirectory = Path.GetDirectoryName(manifestModuleCopy.FullPath);
                    }

                    string originalPath   = Path.Combine(originalDirectory, moduleName);
                    string shadowCopyPath = Path.Combine(shadowCopyDirectory, moduleName);

                    var moduleCopy = CopyFile(originalPath, shadowCopyPath);
                    moduleBuilder.Add(CreateModuleMetadata(moduleCopy));
                }

                var modules = (moduleBuilder != null) ? moduleBuilder.ToReadOnly() : ReadOnlyArray.Singleton(manifestModule);

                fault = false;
                return(new AssemblyMetadata(modules));
            }
            finally
            {
                if (fault)
                {
                    if (manifestModule != null)
                    {
                        manifestModule.Dispose();
                    }

                    if (moduleBuilder != null)
                    {
                        for (int i = 1; i < moduleBuilder.Count; i++)
                        {
                            moduleBuilder[i].Dispose();
                        }
                    }
                }

                if (moduleBuilder != null)
                {
                    moduleBuilder.Free();
                }
            }
        }