public static EmitResult Emit( this Compilation compilation, string outputPath, string?pdbPath = null, string?xmlDocPath = null, string?win32ResourcesPath = null, IEnumerable <ResourceDescription>?manifestResources = null, CancellationToken cancellationToken = default) { if (compilation == null) { throw new ArgumentNullException(nameof(compilation)); } using (var outputStream = FileUtilities.CreateFileStreamChecked(File.Create, outputPath, nameof(outputPath))) using (var pdbStream = (pdbPath == null ? null : FileUtilities.CreateFileStreamChecked(File.Create, pdbPath, nameof(pdbPath)))) using (var xmlDocStream = (xmlDocPath == null ? null : FileUtilities.CreateFileStreamChecked(File.Create, xmlDocPath, nameof(xmlDocPath)))) using (var win32ResourcesStream = (win32ResourcesPath == null ? null : FileUtilities.CreateFileStreamChecked(File.OpenRead, win32ResourcesPath, nameof(win32ResourcesPath)))) { return(compilation.Emit( outputStream, pdbStream: pdbStream, xmlDocumentationStream: xmlDocStream, win32Resources: win32ResourcesStream, manifestResources: manifestResources, options: new EmitOptions(pdbFilePath: pdbPath), cancellationToken: cancellationToken)); } }
internal override Stream CreateInputStream() { var path = PortableShim.Path.GetTempFileName(); Func <string, Stream> streamConstructor = lPath => new TempFileStream(lPath, PortableShim.FileStream.Create(lPath, PortableShim.FileMode.Create, PortableShim.FileAccess.ReadWrite, PortableShim.FileShare.ReadWrite)); return(FileUtilities.CreateFileStreamChecked(streamConstructor, path)); }
/// <summary> /// Emit the IL for the compilation into the specified stream. /// </summary> /// <param name="compilation">Compilation.</param> /// <param name="outputPath">Path of the file to which the compilation will be written.</param> /// <param name="pdbPath">Path of the file to which the compilation's debug info will be written. /// Also embedded in the output file. Null to forego PDB generation. /// </param> /// <param name="xmlDocPath">Path of the file to which the compilation's XML documentation will be written. Null to forego XML generation.</param> /// <param name="win32ResourcesPath">Path of the file from which the compilation's Win32 resources will be read (in RES format). /// Null to indicate that there are none.</param> /// <param name="manifestResources">List of the compilation's managed resources. Null to indicate that there are none.</param> /// <param name="cancellationToken">To cancel the emit process.</param> /// <exception cref="ArgumentNullException">Compilation or path is null.</exception> /// <exception cref="ArgumentException">Path is empty or invalid.</exception> /// <exception cref="IOException">An error occurred while reading or writing a file.</exception> public static EmitResult Emit( this Compilation compilation, string outputPath, string pdbPath = null, string xmlDocPath = null, string win32ResourcesPath = null, IEnumerable <ResourceDescription> manifestResources = null, CancellationToken cancellationToken = default(CancellationToken)) { if (compilation == null) { throw new ArgumentNullException("compilation"); } using (var outputStream = FileUtilities.CreateFileStreamChecked(File.Create, outputPath, "outputPath")) using (var pdbStream = (pdbPath == null ? null : FileUtilities.CreateFileStreamChecked(File.Create, pdbPath, "pdbPath"))) using (var xmlDocStream = (xmlDocPath == null ? null : FileUtilities.CreateFileStreamChecked(File.Create, xmlDocPath, "xmlDocPath"))) using (var win32ResourcesStream = (win32ResourcesPath == null ? null : FileUtilities.CreateFileStreamChecked(File.OpenRead, win32ResourcesPath, "win32ResourcesPath"))) { return(compilation.Emit( outputStream, outputName: null, pdbFilePath: pdbPath, pdbStream: pdbStream, xmlDocumentationStream: xmlDocStream, win32Resources: win32ResourcesStream, manifestResources: manifestResources, cancellationToken: cancellationToken)); } }
/// <summary> /// Create the stream which should be used for Emit. This should only be called one time. /// </summary> private Stream?CreateStream(DiagnosticBag diagnostics) { RoslynDebug.Assert(_stream == null); RoslynDebug.Assert(diagnostics != null); if (diagnostics.HasAnyErrors()) { return(null); } _stream = _emitStreamProvider.GetOrCreateStream(diagnostics); if (_stream == null) { return(null); } // If the current strong name provider is the Desktop version, signing can only be done to on-disk files. // If this binary is configured to be signed, create a temp file, output to that // then stream that to the stream that this method was called with. Otherwise output to the // stream that this method was called with. if (_emitStreamSignKind == EmitStreamSignKind.SignedWithFile) { RoslynDebug.Assert(_strongNameProvider != null); Stream tempStream; string tempFilePath; try { var fileSystem = _strongNameProvider.FileSystem; Func <string, Stream> streamConstructor = path => fileSystem.CreateFileStream( path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite ); var tempDir = fileSystem.GetTempPath(); tempFilePath = Path.Combine(tempDir, Guid.NewGuid().ToString("N")); tempStream = FileUtilities.CreateFileStreamChecked( streamConstructor, tempFilePath ); } catch (IOException e) { throw new Cci.PeWritingException(e); } _tempInfo = (tempStream, tempFilePath); return(tempStream); } else { return(_stream); } }
/// <exception cref="IOException"></exception> internal override Stream CreateInputStream() { Func <string, Stream> streamConstructor = lPath => new TempFileStream(lPath, new FileStream(lPath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)); string tempPath = _tempPath ?? Path.GetTempPath(); string tempName = Path.Combine(tempPath, Guid.NewGuid().ToString("N")); return(FileUtilities.CreateFileStreamChecked(streamConstructor, tempName)); }
private ComHandle <EnvDTE80.FileCodeModel2, FileCodeModel> GetFileCodeModel(object location) { if (location is string locationString) { var vsProject = _parentHandle.Value; var vsProjectItems = vsProject.ProjectItems; if (vsProjectItems == null) { throw Exceptions.ThrowEFail(); } var project = GetProject(); var projectDirectory = Path.GetDirectoryName(project.FilePath); var absoluteFilePath = Path.GetFullPath( Path.Combine(projectDirectory, locationString) ); var foundFile = false; foreach (var documentId in project.DocumentIds) { var document = project.GetDocument(documentId); if ( document.FilePath != null && string.Equals( absoluteFilePath, document.FilePath, StringComparison.OrdinalIgnoreCase ) ) { foundFile = true; break; } } if (!foundFile) { // File doesn't belong to the project, prepare & add it to project using (FileUtilities.CreateFileStreamChecked(File.Create, absoluteFilePath)) { // Note: We just want to create an empty file here, so we immediately close it. } vsProjectItems.AddFromFile(absoluteFilePath); } return(this.State.ProjectCodeModelFactory .GetProjectCodeModel(_projectId) .GetOrCreateFileCodeModel(absoluteFilePath)); } throw Exceptions.ThrowEInvalidArg(); }
private ComHandle <EnvDTE80.FileCodeModel2, FileCodeModel> GetFileCodeModel(object location) { if (location is string) { var vsProject = (EnvDTE.Project)_parentHandle.Value; var vsProjectItems = vsProject.ProjectItems; if (vsProjectItems == null) { throw Exceptions.ThrowEFail(); } var locationString = (string)location; var project = GetProject(); var projectDirectory = Path.GetDirectoryName(project.FilePath); var absoluteFilePath = Path.GetFullPath(Path.Combine(projectDirectory, locationString)); string fileName = null; foreach (var documentId in project.DocumentIds) { var document = project.GetDocument(documentId); if (document.FilePath != null && string.Equals(absoluteFilePath, document.FilePath, StringComparison.OrdinalIgnoreCase)) { var vsProjectItem = vsProjectItems.Item(Path.GetFileName(locationString)); fileName = vsProjectItem.get_FileNames(1); } } if (fileName == null) { // File doesn't belong to the project, prepare & add it to project using (FileUtilities.CreateFileStreamChecked(File.Create, absoluteFilePath)) { // Note: We just want to create an empty file here, so we immediately close it. } vsProjectItems.AddFromFile(absoluteFilePath); fileName = absoluteFilePath; } var hostProject = ((VisualStudioWorkspaceImpl)Workspace).ProjectTracker.GetProject(_projectId); var projectCodeModel = ((IProjectCodeModelProvider)hostProject).ProjectCodeModel; return(projectCodeModel.GetFileCodeModelInstance(fileName).Value); } else { throw Exceptions.ThrowEInvalidArg(); } }
public async Task <bool> CompileAsync(IWorkspaceProjectContext context, string outputFileName, ISet <string> filesToInclude, CancellationToken cancellationToken) { if (filesToInclude == null || filesToInclude.Count == 0) { throw new ArgumentException(nameof(filesToInclude), "Must specify some files to compile."); } if (outputFileName == null) { throw new ArgumentException(nameof(outputFileName), "Must specify an output file name."); } var project = _workspace.CurrentSolution.GetProject(context.Id); // Remove all files except the ones we care about var documents = project.Documents; foreach (var document in documents) { if (!filesToInclude.Contains(document.FilePath)) { project = project.RemoveDocument(document.Id); } cancellationToken.ThrowIfCancellationRequested(); } var options = project.LanguageServices.GetRequiredService <ICompilationFactoryService>().GetDefaultCompilationOptions() // copied from the old TempPE compiler used by legacy, for parity. // See: https://github.com/dotnet/roslyn/blob/fab7134296816fc80019c60b0f5bef7400cf23ea/src/VisualStudio/CSharp/Impl/ProjectSystemShim/TempPECompilerService.cs#L58 .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default) .WithSourceReferenceResolver(SourceFileResolver.Default) .WithXmlReferenceResolver(XmlFileResolver.Default) // we always want to produce a DLL .WithOutputKind(OutputKind.DynamicallyLinkedLibrary); project = project.WithCompilationOptions(options); var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); var outputPath = Path.GetDirectoryName(outputFileName); Directory.CreateDirectory(outputPath); using (var file = FileUtilities.CreateFileStreamChecked(File.Create, outputFileName, nameof(outputFileName))) { return(compilation.Emit(file, cancellationToken: cancellationToken).Success); } }
public async Task <bool> CompileAsync(IWorkspaceProjectContext context, string outputFileName, ISet <string> filesToInclude, CancellationToken cancellationToken) { if (filesToInclude == null || filesToInclude.Count == 0) { throw new ArgumentException(nameof(filesToInclude), "Must specify some files to compile."); } if (outputFileName == null) { throw new ArgumentException(nameof(outputFileName), "Must specify an output file name."); } var project = _workspace.CurrentSolution.GetProject(context.Id); // Remove all files except the ones we care about var documents = project.Documents; foreach (var document in documents) { if (!filesToInclude.Contains(document.FilePath)) { project = project.RemoveDocument(document.Id); } cancellationToken.ThrowIfCancellationRequested(); } // We need to inherit most of the projects options, mainly for VB (RootNamespace, GlobalImports etc.), but we need to override about some specific things surrounding the output var options = project.CompilationOptions // copied from the old TempPE compiler used by legacy, for parity. // See: https://github.com/dotnet/roslyn/blob/fab7134296816fc80019c60b0f5bef7400cf23ea/src/VisualStudio/CSharp/Impl/ProjectSystemShim/TempPECompilerService.cs#L58 .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default) .WithSourceReferenceResolver(SourceFileResolver.Default) .WithXmlReferenceResolver(XmlFileResolver.Default) // We always want to produce a debug, AnyCPU DLL .WithOutputKind(OutputKind.DynamicallyLinkedLibrary) .WithPlatform(Platform.AnyCpu) .WithOptimizationLevel(OptimizationLevel.Debug) // Turn off any warnings as errors just in case .WithGeneralDiagnosticOption(ReportDiagnostic.Suppress) .WithReportSuppressedDiagnostics(false) .WithSpecificDiagnosticOptions(null) // Turn off any signing and strong naming .WithDelaySign(false) .WithCryptoKeyFile(null) .WithPublicSign(false) .WithStrongNameProvider(null); project = project .WithCompilationOptions(options) // AssemblyName should be set to the filename of the output file because multiple TempPE DLLs can be created for the same project .WithAssemblyName(Path.GetFileName(outputFileName)); var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); var outputPath = Path.GetDirectoryName(outputFileName); Directory.CreateDirectory(outputPath); using (var file = FileUtilities.CreateFileStreamChecked(File.Create, outputFileName, nameof(outputFileName))) { return(compilation.Emit(file, cancellationToken: cancellationToken).Success); } }