Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / CompMod / System / CodeDOM / Compiler / CodeCompiler.cs / 2 / CodeCompiler.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.CodeDom.Compiler { using System.Text; using System.Diagnostics; using System; using Microsoft.Win32; using Microsoft.Win32.SafeHandles; using System.IO; using System.Collections; using System.Security; using System.Security.Permissions; using System.Security.Principal; using System.Reflection; using System.CodeDom; using System.Globalization; using System.Runtime.Versioning; ////// [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] [PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")] public abstract class CodeCompiler : CodeGenerator, ICodeCompiler { ///Provides a /// base /// class for code compilers. ///CompilerResults ICodeCompiler.CompileAssemblyFromDom(CompilerParameters options, CodeCompileUnit e) { if( options == null) { throw new ArgumentNullException("options"); } try { return FromDom(options, e); } finally { options.TempFiles.SafeDelete(); } } /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] CompilerResults ICodeCompiler.CompileAssemblyFromFile(CompilerParameters options, string fileName) { if( options == null) { throw new ArgumentNullException("options"); } try { return FromFile(options, fileName); } finally { options.TempFiles.SafeDelete(); } } /// CompilerResults ICodeCompiler.CompileAssemblyFromSource(CompilerParameters options, string source) { if( options == null) { throw new ArgumentNullException("options"); } try { return FromSource(options, source); } finally { options.TempFiles.SafeDelete(); } } /// CompilerResults ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options, string[] sources) { if( options == null) { throw new ArgumentNullException("options"); } try { return FromSourceBatch(options, sources); } finally { options.TempFiles.SafeDelete(); } } /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] CompilerResults ICodeCompiler.CompileAssemblyFromFileBatch(CompilerParameters options, string[] fileNames) { if( options == null) { throw new ArgumentNullException("options"); } if (fileNames == null) throw new ArgumentNullException("fileNames"); try { // Try opening the files to make sure they exists. This will throw an exception // if it doesn't foreach (string fileName in fileNames) { using (Stream str = File.OpenRead(fileName)) { } } return FromFileBatch(options, fileNames); } finally { options.TempFiles.SafeDelete(); } } /// CompilerResults ICodeCompiler.CompileAssemblyFromDomBatch(CompilerParameters options, CodeCompileUnit[] ea) { if( options == null) { throw new ArgumentNullException("options"); } try { return FromDomBatch(options, ea); } finally { options.TempFiles.SafeDelete(); } } /// /// protected abstract string FileExtension { get; } ////// Gets /// or sets the file extension to use for source files. /// ////// protected abstract string CompilerName { get; } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] internal void Compile(CompilerParameters options, string compilerDirectory, string compilerExe, string arguments, ref string outputFile, ref int nativeReturnValue, string trueArgs) { string errorFile = null; outputFile = options.TempFiles.AddExtension("out"); // We try to execute the compiler with a full path name. string fullname = Path.Combine(compilerDirectory, compilerExe); if (File.Exists(fullname)) { string trueCmdLine = null; if (trueArgs != null) trueCmdLine = "\"" + fullname + "\" " + trueArgs; nativeReturnValue = Executor.ExecWaitWithCapture(options.SafeUserToken, "\"" + fullname + "\" " + arguments, Environment.CurrentDirectory, options.TempFiles, ref outputFile, ref errorFile, trueCmdLine); } else { throw new InvalidOperationException(SR.GetString(SR.CompilerNotFound, fullname)); } } ///Gets or /// sets the name of the compiler executable. ////// protected virtual CompilerResults FromDom(CompilerParameters options, CodeCompileUnit e) { if( options == null) { throw new ArgumentNullException("options"); } new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); CodeCompileUnit[] units = new CodeCompileUnit[1]; units[0] = e; return FromDomBatch(options, units); } ////// Compiles the specified compile unit and options, and returns the results /// from the compilation. /// ////// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected virtual CompilerResults FromFile(CompilerParameters options, string fileName) { if( options == null) { throw new ArgumentNullException("options"); } if (fileName == null) throw new ArgumentNullException("fileName"); new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); // Try opening the file to make sure it exists. This will throw an exception // if it doesn't using (Stream str = File.OpenRead(fileName)) { } string[] filenames = new string[1]; filenames[0] = fileName; return FromFileBatch(options, filenames); } ////// Compiles the specified file using the specified options, and returns the /// results from the compilation. /// ////// protected virtual CompilerResults FromSource(CompilerParameters options, string source) { if( options == null) { throw new ArgumentNullException("options"); } new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); string[] sources = new string[1]; sources[0] = source; return FromSourceBatch(options, sources); } ////// Compiles the specified source code using the specified options, and /// returns the results from the compilation. /// ////// protected virtual CompilerResults FromDomBatch(CompilerParameters options, CodeCompileUnit[] ea) { if( options == null) { throw new ArgumentNullException("options"); } if (ea == null) throw new ArgumentNullException("ea"); new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); string[] filenames = new string[ea.Length]; CompilerResults results = null; #if !FEATURE_PAL // the extra try-catch is here to mitigate exception filter injection attacks. try { WindowsImpersonationContext impersonation = Executor.RevertImpersonation(); try { #endif // !FEATURE_PAL for (int i = 0; i < ea.Length; i++) { if (ea[i] == null) continue; // the other two batch methods just work if one element is null, so we'll match that. ResolveReferencedAssemblies(options, ea[i]); filenames[i] = options.TempFiles.AddExtension(i + FileExtension); Stream temp = new FileStream(filenames[i], FileMode.Create, FileAccess.Write, FileShare.Read); try { using (StreamWriter sw = new StreamWriter(temp, Encoding.UTF8)){ ((ICodeGenerator)this).GenerateCodeFromCompileUnit(ea[i], sw, Options); sw.Flush(); } } finally { temp.Close(); } } results = FromFileBatch(options, filenames); #if !FEATURE_PAL } finally { Executor.ReImpersonate(impersonation); } } catch { throw; } #endif // !FEATURE_PAL return results; } ////// Compiles the specified compile units and /// options, and returns the results from the compilation. /// ////// private void ResolveReferencedAssemblies(CompilerParameters options, CodeCompileUnit e) { if (e.ReferencedAssemblies.Count > 0) { foreach(string assemblyName in e.ReferencedAssemblies) { if (!options.ReferencedAssemblies.Contains(assemblyName)) { options.ReferencedAssemblies.Add(assemblyName); } } } } ////// Because CodeCompileUnit and CompilerParameters both have a referenced assemblies /// property, they must be reconciled. However, because you can compile multiple /// compile units with one set of options, it will simply merge them. /// ////// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] protected virtual CompilerResults FromFileBatch(CompilerParameters options, string[] fileNames) { if( options == null) { throw new ArgumentNullException("options"); } if (fileNames == null) throw new ArgumentNullException("fileNames"); new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); string outputFile = null; int retValue = 0; CompilerResults results = new CompilerResults(options.TempFiles); SecurityPermission perm1 = new SecurityPermission(SecurityPermissionFlag.ControlEvidence); perm1.Assert(); try { results.Evidence = options.Evidence; } finally { SecurityPermission.RevertAssert(); } bool createdEmptyAssembly = false; if (options.OutputAssembly == null || options.OutputAssembly.Length == 0) { string extension = (options.GenerateExecutable) ? "exe" : "dll"; options.OutputAssembly = results.TempFiles.AddExtension(extension, !options.GenerateInMemory); // Create an empty assembly. This is so that the file will have permissions that // we can later access with our current credential. If we don't do this, the compiler // could end up creating an assembly that we cannot open new FileStream(options.OutputAssembly, FileMode.Create, FileAccess.ReadWrite).Close(); createdEmptyAssembly = true; } #if FEATURE_PAL results.TempFiles.AddExtension("ildb"); #else results.TempFiles.AddExtension("pdb"); #endif string args = CmdArgsFromParameters(options) + " " + JoinStringArray(fileNames, " "); // Use a response file if the compiler supports it string responseFileArgs = GetResponseFileCmdArgs(options, args); string trueArgs = null; if (responseFileArgs != null) { trueArgs = args; args = responseFileArgs; } Compile(options, Executor.GetRuntimeInstallDirectory(), CompilerName, args, ref outputFile, ref retValue, trueArgs); results.NativeCompilerReturnValue = retValue; // only look for errors/warnings if the compile failed or the caller set the warning level if (retValue != 0 || options.WarningLevel > 0) { FileStream outputStream = new FileStream(outputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); try { if (outputStream.Length > 0) { // The output of the compiler is in UTF8 StreamReader sr = new StreamReader(outputStream, Encoding.UTF8); string line; do { line = sr.ReadLine(); if (line != null) { results.Output.Add(line); ProcessCompilerOutputLine(results, line); } } while (line != null); } } finally { outputStream.Close(); } // Delete the empty assembly if we created one if (retValue != 0 && createdEmptyAssembly) File.Delete(options.OutputAssembly); } if (!results.Errors.HasErrors && options.GenerateInMemory) { FileStream fs = new FileStream(options.OutputAssembly, FileMode.Open, FileAccess.Read, FileShare.Read); try { int fileLen = (int)fs.Length; byte[] b = new byte[fileLen]; fs.Read(b, 0, fileLen); SecurityPermission perm = new SecurityPermission(SecurityPermissionFlag.ControlEvidence); perm.Assert(); try { results.CompiledAssembly = Assembly.Load(b,null,options.Evidence); } finally { SecurityPermission.RevertAssert(); } } finally { fs.Close(); } } else { results.PathToAssembly = options.OutputAssembly; } return results; } ////// Compiles the specified files using the specified options, and returns the /// results from the compilation. /// ////// protected abstract void ProcessCompilerOutputLine(CompilerResults results, string line); ///Processes the specified line from the specified ///. /// protected abstract string CmdArgsFromParameters(CompilerParameters options); ////// Gets the command arguments from the specified ///. /// /// protected virtual string GetResponseFileCmdArgs(CompilerParameters options, string cmdArgs) { string responseFileName = options.TempFiles.AddExtension("cmdline"); Stream temp = new FileStream(responseFileName, FileMode.Create, FileAccess.Write, FileShare.Read); try { using (StreamWriter sw = new StreamWriter(temp, Encoding.UTF8)) { sw.Write(cmdArgs); sw.Flush(); } } finally { temp.Close(); } return "@\"" + responseFileName + "\""; } ///[To be supplied.] ////// protected virtual CompilerResults FromSourceBatch(CompilerParameters options, string[] sources) { if( options == null) { throw new ArgumentNullException("options"); } if (sources == null) throw new ArgumentNullException("sources"); new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); string[] filenames = new string[sources.Length]; CompilerResults results = null; #if !FEATURE_PAL // the extra try-catch is here to mitigate exception filter injection attacks. try { WindowsImpersonationContext impersonation = Executor.RevertImpersonation(); try { #endif // !FEATURE_PAL for (int i = 0; i < sources.Length; i++) { string name = options.TempFiles.AddExtension(i + FileExtension); Stream temp = new FileStream(name, FileMode.Create, FileAccess.Write, FileShare.Read); try { using (StreamWriter sw = new StreamWriter(temp, Encoding.UTF8)) { sw.Write(sources[i]); sw.Flush(); } } finally { temp.Close(); } filenames[i] = name; } results = FromFileBatch(options, filenames); #if !FEATURE_PAL } finally { Executor.ReImpersonate(impersonation); } } catch { throw; } #endif // !FEATURE_PAL return results; } ////// Compiles the specified source code strings using the specified options, and /// returns the results from the compilation. /// ////// protected static string JoinStringArray(string[] sa, string separator) { if (sa == null || sa.Length == 0) return String.Empty; if (sa.Length == 1) { return "\"" + sa[0] + "\""; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < sa.Length - 1; i++) { sb.Append("\""); sb.Append(sa[i]); sb.Append("\""); sb.Append(separator); } sb.Append("\""); sb.Append(sa[sa.Length - 1]); sb.Append("\""); return sb.ToString(); } } }Joins the specified string arrays. ///
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XPathParser.cs
- FlowDocumentFormatter.cs
- FragmentQuery.cs
- graph.cs
- MultiBindingExpression.cs
- WithParamAction.cs
- MetadataHelper.cs
- BitmapMetadata.cs
- ProfileGroupSettingsCollection.cs
- RawStylusInputCustomDataList.cs
- DataSourceControl.cs
- _LocalDataStore.cs
- ClientEventManager.cs
- CompilerGlobalScopeAttribute.cs
- DbFunctionCommandTree.cs
- DataReceivedEventArgs.cs
- ContentHostHelper.cs
- PackageDigitalSignature.cs
- WorkflowMarkupSerializationProvider.cs
- OleDbStruct.cs
- NetworkInformationException.cs
- WeakHashtable.cs
- CfgSemanticTag.cs
- ClientSponsor.cs
- TableRow.cs
- InfoCardRSACryptoProvider.cs
- StringUtil.cs
- ParameterInfo.cs
- WeakReferenceList.cs
- SecureEnvironment.cs
- ImageAnimator.cs
- DefaultValueAttribute.cs
- VSDExceptions.cs
- QilXmlReader.cs
- ThrowHelper.cs
- DataViewSettingCollection.cs
- AmbientEnvironment.cs
- DescendentsWalkerBase.cs
- SafeNativeMethods.cs
- BuildManagerHost.cs
- SelectionRangeConverter.cs
- GraphicsContainer.cs
- HttpCachePolicyElement.cs
- EmptyStringExpandableObjectConverter.cs
- TemplateField.cs
- PeerNearMe.cs
- DialogResultConverter.cs
- UTF32Encoding.cs
- Point3DAnimationUsingKeyFrames.cs
- DataSourceHelper.cs
- TimeIntervalCollection.cs
- TransformerConfigurationWizardBase.cs
- Frame.cs
- XPathMultyIterator.cs
- MediaSystem.cs
- ImageSource.cs
- ZipFileInfo.cs
- RijndaelManagedTransform.cs
- EntryPointNotFoundException.cs
- StorageAssociationSetMapping.cs
- RuleSettingsCollection.cs
- CompoundFileStreamReference.cs
- NumericUpDown.cs
- SettingsPropertyNotFoundException.cs
- StrokeNodeEnumerator.cs
- TableAutomationPeer.cs
- PassportPrincipal.cs
- CollectionConverter.cs
- JpegBitmapEncoder.cs
- ToolStripSplitButton.cs
- SortFieldComparer.cs
- RequestCacheValidator.cs
- FormattedText.cs
- SqlTypesSchemaImporter.cs
- PerformanceCountersElement.cs
- __Filters.cs
- ApplicationTrust.cs
- ListManagerBindingsCollection.cs
- DataGridItemCollection.cs
- SecurityState.cs
- TextParagraph.cs
- NetTcpSection.cs
- Relationship.cs
- Formatter.cs
- COM2FontConverter.cs
- RegexParser.cs
- OpenTypeCommon.cs
- Table.cs
- XmlParserContext.cs
- EncodingStreamWrapper.cs
- WebConfigurationHostFileChange.cs
- AttachmentCollection.cs
- TableLayoutStyleCollection.cs
- ObjectListDesigner.cs
- SourceSwitch.cs
- SmiRecordBuffer.cs
- AddingNewEventArgs.cs
- QueryableDataSourceEditData.cs
- CreateRefExpr.cs
- TimeEnumHelper.cs