Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / CompMod / System / CodeDOM / Compiler / CodeCompiler.cs / 1305376 / 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;
///
/// Provides a
/// base
/// class for code compilers.
///
[PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
[PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")]
public abstract class CodeCompiler : CodeGenerator, ICodeCompiler {
///
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();
}
}
///
///
/// Gets
/// or sets the file extension to use for source files.
///
///
protected abstract string FileExtension {
get;
}
///
/// Gets or
/// sets the name of the compiler executable.
///
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));
}
}
///
///
/// Compiles the specified compile unit and options, and returns the results
/// from the compilation.
///
///
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 file using the specified 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 source code 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 compile units and
/// options, and returns the results from the compilation.
///
///
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
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;
}
///
///
/// 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.
///
///
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);
}
}
}
}
///
///
/// Compiles the specified files using the specified options, and returns the
/// results from the compilation.
///
///
[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 {
#pragma warning disable 618
results.Evidence = options.Evidence;
#pragma warning restore 618
}
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 {
#pragma warning disable 618 // Load with evidence is obsolete - this warning is passed on via the options parameter
results.CompiledAssembly = Assembly.Load(b,null,options.Evidence);
#pragma warning restore 618
}
finally {
SecurityPermission.RevertAssert();
}
}
finally {
fs.Close();
}
}
else {
results.PathToAssembly = options.OutputAssembly;
}
return results;
}
///
/// Processes the specified line from the specified .
///
protected abstract void ProcessCompilerOutputLine(CompilerResults results, string line);
///
///
/// Gets the command arguments from the specified .
///
///
protected abstract string CmdArgsFromParameters(CompilerParameters options);
///
/// [To be supplied.]
///
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
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 + "\"";
}
///
///
/// Compiles the specified source code strings using the specified options, and
/// returns the results from the compilation.
///
///
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
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;
}
///
/// Joins the specified string arrays.
///
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();
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PopupRootAutomationPeer.cs
- Stroke2.cs
- SafeProcessHandle.cs
- BindValidator.cs
- Mappings.cs
- ControlCachePolicy.cs
- ExitEventArgs.cs
- AncillaryOps.cs
- QueueProcessor.cs
- HuffmanTree.cs
- RSAOAEPKeyExchangeDeformatter.cs
- PasswordTextNavigator.cs
- RegexMatchCollection.cs
- ColumnWidthChangingEvent.cs
- SoapAttributeAttribute.cs
- SiteMapPath.cs
- ToolStripItemRenderEventArgs.cs
- WpfKnownType.cs
- ProviderUtil.cs
- UnmanagedBitmapWrapper.cs
- ErrorProvider.cs
- SafeRsaProviderHandle.cs
- EntityDataSourceValidationException.cs
- sqlmetadatafactory.cs
- Camera.cs
- SchemaCollectionPreprocessor.cs
- SqlDelegatedTransaction.cs
- PropertyValueUIItem.cs
- MemoryPressure.cs
- Message.cs
- Wizard.cs
- Command.cs
- TableLayoutSettingsTypeConverter.cs
- DynamicFilter.cs
- DetailsViewUpdatedEventArgs.cs
- Matrix.cs
- ThreadAbortException.cs
- ChangePasswordDesigner.cs
- InternalConfigRoot.cs
- WebPartZone.cs
- EmptyCollection.cs
- TileModeValidation.cs
- TimeSpanStorage.cs
- AddInPipelineAttributes.cs
- FlowDocumentPageViewerAutomationPeer.cs
- TraceData.cs
- SmtpReplyReader.cs
- IntSecurity.cs
- WebPartExportVerb.cs
- EmptyCollection.cs
- DiscoveryDocumentSerializer.cs
- ItemCheckEvent.cs
- EncoderFallback.cs
- XmlSchemaAnnotated.cs
- PageStatePersister.cs
- Light.cs
- OdbcError.cs
- WebPartCancelEventArgs.cs
- ResourceCategoryAttribute.cs
- ObjectPropertyMapping.cs
- RawAppCommandInputReport.cs
- KeyPressEvent.cs
- WinInetCache.cs
- XmlSchemaSimpleContentExtension.cs
- DataServiceHost.cs
- EventManager.cs
- FlowchartDesigner.xaml.cs
- ChtmlSelectionListAdapter.cs
- RuleCache.cs
- WebPartExportVerb.cs
- XamlPoint3DCollectionSerializer.cs
- Int32Rect.cs
- FileAuthorizationModule.cs
- TableRow.cs
- BitmapEffectOutputConnector.cs
- StringUtil.cs
- PrimitiveCodeDomSerializer.cs
- Module.cs
- ExtensionWindow.cs
- Transform.cs
- ByteFacetDescriptionElement.cs
- DynamicFilter.cs
- ElementMarkupObject.cs
- PageVisual.cs
- basemetadatamappingvisitor.cs
- MDIControlStrip.cs
- XPathNavigatorKeyComparer.cs
- WebService.cs
- PagedDataSource.cs
- _AuthenticationState.cs
- Privilege.cs
- ConnectionProviderAttribute.cs
- PrivateFontCollection.cs
- SystemEvents.cs
- Perspective.cs
- CodeCatchClauseCollection.cs
- UrlMappingCollection.cs
- GZipStream.cs
- TextOnlyOutput.cs
- BitmapSource.cs