mscorlib(4.0.0.0) API with additions
CodeCompiler.cs
2 using System.IO;
3 using System.Reflection;
4 using System.Security;
7 using System.Text;
8 
10 {
12  [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
13  [PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
14  public abstract class CodeCompiler : CodeGenerator, ICodeCompiler
15  {
18  protected abstract string FileExtension
19  {
20  get;
21  }
22 
25  protected abstract string CompilerName
26  {
27  get;
28  }
29 
37  {
38  if (options == null)
39  {
40  throw new ArgumentNullException("options");
41  }
42  try
43  {
44  return FromDom(options, e);
45  }
46  finally
47  {
48  options.TempFiles.SafeDelete();
49  }
50  }
51 
58  CompilerResults ICodeCompiler.CompileAssemblyFromFile(CompilerParameters options, string fileName)
59  {
60  if (options == null)
61  {
62  throw new ArgumentNullException("options");
63  }
64  try
65  {
66  return FromFile(options, fileName);
67  }
68  finally
69  {
70  options.TempFiles.SafeDelete();
71  }
72  }
73 
80  CompilerResults ICodeCompiler.CompileAssemblyFromSource(CompilerParameters options, string source)
81  {
82  if (options == null)
83  {
84  throw new ArgumentNullException("options");
85  }
86  try
87  {
88  return FromSource(options, source);
89  }
90  finally
91  {
92  options.TempFiles.SafeDelete();
93  }
94  }
95 
102  CompilerResults ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options, string[] sources)
103  {
104  if (options == null)
105  {
106  throw new ArgumentNullException("options");
107  }
108  try
109  {
110  return FromSourceBatch(options, sources);
111  }
112  finally
113  {
114  options.TempFiles.SafeDelete();
115  }
116  }
117 
122  CompilerResults ICodeCompiler.CompileAssemblyFromFileBatch(CompilerParameters options, string[] fileNames)
123  {
124  if (options == null)
125  {
126  throw new ArgumentNullException("options");
127  }
128  if (fileNames == null)
129  {
130  throw new ArgumentNullException("fileNames");
131  }
132  try
133  {
134  foreach (string path in fileNames)
135  {
136  using (File.OpenRead(path))
137  {
138  }
139  }
140  return FromFileBatch(options, fileNames);
141  }
142  finally
143  {
144  options.TempFiles.SafeDelete();
145  }
146  }
147 
152  CompilerResults ICodeCompiler.CompileAssemblyFromDomBatch(CompilerParameters options, CodeCompileUnit[] ea)
153  {
154  if (options == null)
155  {
156  throw new ArgumentNullException("options");
157  }
158  try
159  {
160  return FromDomBatch(options, ea);
161  }
162  finally
163  {
164  options.TempFiles.SafeDelete();
165  }
166  }
167 
168  internal void Compile(CompilerParameters options, string compilerDirectory, string compilerExe, string arguments, ref string outputFile, ref int nativeReturnValue, string trueArgs)
169  {
170  string errorName = null;
171  outputFile = options.TempFiles.AddExtension("out");
172  string text = Path.Combine(compilerDirectory, compilerExe);
173  if (File.Exists(text))
174  {
175  string trueCmdLine = null;
176  if (trueArgs != null)
177  {
178  trueCmdLine = "\"" + text + "\" " + trueArgs;
179  }
180  nativeReturnValue = Executor.ExecWaitWithCapture(options.SafeUserToken, "\"" + text + "\" " + arguments, Environment.CurrentDirectory, options.TempFiles, ref outputFile, ref errorName, trueCmdLine);
181  return;
182  }
183  throw new InvalidOperationException(SR.GetString("CompilerNotFound", text));
184  }
185 
193  {
194  if (options == null)
195  {
196  throw new ArgumentNullException("options");
197  }
198  new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
199  return FromDomBatch(options, new CodeCompileUnit[1]
200  {
201  e
202  });
203  }
204 
212  protected virtual CompilerResults FromFile(CompilerParameters options, string fileName)
213  {
214  if (options == null)
215  {
216  throw new ArgumentNullException("options");
217  }
218  if (fileName == null)
219  {
220  throw new ArgumentNullException("fileName");
221  }
222  new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
223  using (File.OpenRead(fileName))
224  {
225  }
226  return FromFileBatch(options, new string[1]
227  {
228  fileName
229  });
230  }
231 
238  protected virtual CompilerResults FromSource(CompilerParameters options, string source)
239  {
240  if (options == null)
241  {
242  throw new ArgumentNullException("options");
243  }
244  new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
245  return FromSourceBatch(options, new string[1]
246  {
247  source
248  });
249  }
250 
259  {
260  if (options == null)
261  {
262  throw new ArgumentNullException("options");
263  }
264  if (ea == null)
265  {
266  throw new ArgumentNullException("ea");
267  }
268  new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
269  string[] array = new string[ea.Length];
270  CompilerResults compilerResults = null;
271  try
272  {
273  WindowsImpersonationContext impersonation = Executor.RevertImpersonation();
274  try
275  {
276  for (int i = 0; i < ea.Length; i++)
277  {
278  if (ea[i] != null)
279  {
280  ResolveReferencedAssemblies(options, ea[i]);
281  array[i] = options.TempFiles.AddExtension(i + FileExtension);
282  Stream stream = new FileStream(array[i], FileMode.Create, FileAccess.Write, FileShare.Read);
283  try
284  {
285  using (StreamWriter streamWriter = new StreamWriter(stream, Encoding.UTF8))
286  {
287  ((ICodeGenerator)this).GenerateCodeFromCompileUnit(ea[i], (TextWriter)streamWriter, base.Options);
288  streamWriter.Flush();
289  }
290  }
291  finally
292  {
293  stream.Close();
294  }
295  }
296  }
297  return FromFileBatch(options, array);
298  }
299  finally
300  {
301  Executor.ReImpersonate(impersonation);
302  }
303  }
304  catch
305  {
306  throw;
307  }
308  }
309 
310  private void ResolveReferencedAssemblies(CompilerParameters options, CodeCompileUnit e)
311  {
312  if (e.ReferencedAssemblies.Count > 0)
313  {
315  try
316  {
317  while (enumerator.MoveNext())
318  {
319  string current = enumerator.Current;
320  if (!options.ReferencedAssemblies.Contains(current))
321  {
322  options.ReferencedAssemblies.Add(current);
323  }
324  }
325  }
326  finally
327  {
328  (enumerator as IDisposable)?.Dispose();
329  }
330  }
331  }
332 
340  protected virtual CompilerResults FromFileBatch(CompilerParameters options, string[] fileNames)
341  {
342  if (options == null)
343  {
344  throw new ArgumentNullException("options");
345  }
346  if (fileNames == null)
347  {
348  throw new ArgumentNullException("fileNames");
349  }
350  new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
351  string outputFile = null;
352  int nativeReturnValue = 0;
353  CompilerResults compilerResults = new CompilerResults(options.TempFiles);
354  SecurityPermission securityPermission = new SecurityPermission(SecurityPermissionFlag.ControlEvidence);
355  securityPermission.Assert();
356  try
357  {
358  compilerResults.Evidence = options.Evidence;
359  }
360  finally
361  {
363  }
364  bool flag = false;
365  if (options.OutputAssembly == null || options.OutputAssembly.Length == 0)
366  {
367  string fileExtension = options.GenerateExecutable ? "exe" : "dll";
368  options.OutputAssembly = compilerResults.TempFiles.AddExtension(fileExtension, !options.GenerateInMemory);
369  new FileStream(options.OutputAssembly, FileMode.Create, FileAccess.ReadWrite).Close();
370  flag = true;
371  }
372  compilerResults.TempFiles.AddExtension("pdb");
373  string text = CmdArgsFromParameters(options) + " " + JoinStringArray(fileNames, " ");
374  string responseFileCmdArgs = GetResponseFileCmdArgs(options, text);
375  string trueArgs = null;
376  if (responseFileCmdArgs != null)
377  {
378  trueArgs = text;
379  text = responseFileCmdArgs;
380  }
381  Compile(options, Executor.GetRuntimeInstallDirectory(), CompilerName, text, ref outputFile, ref nativeReturnValue, trueArgs);
382  compilerResults.NativeCompilerReturnValue = nativeReturnValue;
383  if (nativeReturnValue != 0 || options.WarningLevel > 0)
384  {
385  FileStream fileStream = new FileStream(outputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
386  try
387  {
388  if (fileStream.Length > 0)
389  {
390  StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8);
391  string text2;
392  do
393  {
394  text2 = streamReader.ReadLine();
395  if (text2 != null)
396  {
397  compilerResults.Output.Add(text2);
398  ProcessCompilerOutputLine(compilerResults, text2);
399  }
400  }
401  while (text2 != null);
402  }
403  }
404  finally
405  {
406  fileStream.Close();
407  }
408  if (nativeReturnValue != 0 && flag)
409  {
410  File.Delete(options.OutputAssembly);
411  }
412  }
413  if (!compilerResults.Errors.HasErrors && options.GenerateInMemory)
414  {
415  FileStream fileStream2 = new FileStream(options.OutputAssembly, FileMode.Open, FileAccess.Read, FileShare.Read);
416  try
417  {
418  int num = (int)fileStream2.Length;
419  byte[] array = new byte[num];
420  fileStream2.Read(array, 0, num);
421  SecurityPermission securityPermission2 = new SecurityPermission(SecurityPermissionFlag.ControlEvidence);
422  securityPermission2.Assert();
423  try
424  {
425  compilerResults.CompiledAssembly = Assembly.Load(array, null, options.Evidence);
426  return compilerResults;
427  }
428  finally
429  {
431  }
432  }
433  finally
434  {
435  fileStream2.Close();
436  }
437  }
438  compilerResults.PathToAssembly = options.OutputAssembly;
439  return compilerResults;
440  }
441 
445  protected abstract void ProcessCompilerOutputLine(CompilerResults results, string line);
446 
450  protected abstract string CmdArgsFromParameters(CompilerParameters options);
451 
456  protected virtual string GetResponseFileCmdArgs(CompilerParameters options, string cmdArgs)
457  {
458  string text = options.TempFiles.AddExtension("cmdline");
459  Stream stream = new FileStream(text, FileMode.Create, FileAccess.Write, FileShare.Read);
460  try
461  {
462  using (StreamWriter streamWriter = new StreamWriter(stream, Encoding.UTF8))
463  {
464  streamWriter.Write(cmdArgs);
465  streamWriter.Flush();
466  }
467  }
468  finally
469  {
470  stream.Close();
471  }
472  return "@\"" + text + "\"";
473  }
474 
482  protected virtual CompilerResults FromSourceBatch(CompilerParameters options, string[] sources)
483  {
484  if (options == null)
485  {
486  throw new ArgumentNullException("options");
487  }
488  if (sources == null)
489  {
490  throw new ArgumentNullException("sources");
491  }
492  new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
493  string[] array = new string[sources.Length];
494  CompilerResults compilerResults = null;
495  try
496  {
497  WindowsImpersonationContext impersonation = Executor.RevertImpersonation();
498  try
499  {
500  for (int i = 0; i < sources.Length; i++)
501  {
502  string text = options.TempFiles.AddExtension(i + FileExtension);
503  Stream stream = new FileStream(text, FileMode.Create, FileAccess.Write, FileShare.Read);
504  try
505  {
506  using (StreamWriter streamWriter = new StreamWriter(stream, Encoding.UTF8))
507  {
508  streamWriter.Write(sources[i]);
509  streamWriter.Flush();
510  }
511  }
512  finally
513  {
514  stream.Close();
515  }
516  array[i] = text;
517  }
518  return FromFileBatch(options, array);
519  }
520  finally
521  {
522  Executor.ReImpersonate(impersonation);
523  }
524  }
525  catch
526  {
527  throw;
528  }
529  }
530 
535  protected static string JoinStringArray(string[] sa, string separator)
536  {
537  if (sa == null || sa.Length == 0)
538  {
539  return string.Empty;
540  }
541  if (sa.Length == 1)
542  {
543  return "\"" + sa[0] + "\"";
544  }
545  StringBuilder stringBuilder = new StringBuilder();
546  for (int i = 0; i < sa.Length - 1; i++)
547  {
548  stringBuilder.Append("\"");
549  stringBuilder.Append(sa[i]);
550  stringBuilder.Append("\"");
551  stringBuilder.Append(separator);
552  }
553  stringBuilder.Append("\"");
554  stringBuilder.Append(sa[sa.Length - 1]);
555  stringBuilder.Append("\"");
556  return stringBuilder.ToString();
557  }
558  }
559 }
Represents a character encoding.To browse the .NET Framework source code for this type,...
Definition: Encoding.cs:15
static string JoinStringArray(string[] sa, string separator)
Joins the specified string arrays.
int Add(string value)
Adds a string to the end of the T:System.Collections.Specialized.StringCollection.
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
string Current
Gets the current element in the collection.
Describes a set of security permissions applied to code. This class cannot be inherited.
Provides command execution functions for invoking compilers. This class cannot be inherited.
Definition: Executor.cs:18
TempFileCollection TempFiles
Gets or sets the temporary file collection to use.
static bool Exists(string path)
Determines whether the specified file exists.
Definition: File.cs:435
unsafe override string ToString()
Converts the value of this instance to a T:System.String.
static string Combine(string path1, string path2)
Combines two strings into a path.
Definition: Path.cs:1107
Represents the results of compilation that are returned from a compiler.
static Assembly Load(string assemblyString)
Loads an assembly given the long form of its name.
Definition: Assembly.cs:507
abstract string CompilerName
Gets the name of the compiler executable.
Definition: CodeCompiler.cs:26
FileMode
Specifies how the operating system should open a file.
Definition: FileMode.cs:8
Assembly CompiledAssembly
Gets or sets the compiled assembly.
Definition: __Canon.cs:3
virtual CompilerResults FromDomBatch(CompilerParameters options, CodeCompileUnit[] ea)
Compiles the specified compile units using the specified options, and returns the results from the co...
Provides an example implementation of the T:System.CodeDom.Compiler.ICodeGenerator interface....
bool HasErrors
Gets a value that indicates whether the collection contains errors.
Supports a simple iteration over a T:System.Collections.Specialized.StringCollection.
Implements a T:System.IO.TextReader that reads characters from a byte stream in a particular encoding...
Definition: StreamReader.cs:13
abstract string FileExtension
Gets the file name extension to use for source files.
Definition: CodeCompiler.cs:19
static FileStream OpenRead(string path)
Opens an existing file for reading.
Definition: File.cs:985
StringCollection Output
Gets the compiler output messages.
override string ReadLine()
Reads a line of characters from the current stream and returns the data as a string.
override int Read([In] [Out] byte[] array, int offset, int count)
Reads a block of bytes from the stream and writes the data in a given buffer.
Definition: FileStream.cs:1222
Represents the parameters used to invoke a compiler.
SecurityAction
Specifies the security actions that can be performed using declarative security.
Implements a T:System.IO.TextWriter for writing characters to a stream in a particular encoding....
Definition: StreamWriter.cs:15
virtual void Close()
Closes the current stream and releases any resources (such as sockets and file handles) associated wi...
Definition: Stream.cs:855
Defines an interface for invoking compilation of source code or a CodeDOM tree using a specific compi...
Definition: ICodeCompiler.cs:6
StringBuilder Append(char value, int repeatCount)
Appends a specified number of copies of the string representation of a Unicode character to this inst...
Defines an interface for generating code.
Evidence Evidence
Indicates the evidence object that represents the security policy permissions of the compiled assembl...
Represents a collection that can contain many different types of permissions.
StringEnumerator GetEnumerator()
Returns a T:System.Collections.Specialized.StringEnumerator that iterates through the T:System....
abstract string CmdArgsFromParameters(CompilerParameters options)
Gets the command arguments to be passed to the compiler from the specified T:System....
virtual CompilerResults FromFile(CompilerParameters options, string fileName)
Compiles the specified file using the specified options, and returns the results from the compilation...
StringCollection ReferencedAssemblies
Gets the referenced assemblies.
Provides a T:System.IO.Stream for a file, supporting both synchronous and asynchronous read and write...
Definition: FileStream.cs:15
Represents a writer that can write a sequential series of characters. This class is abstract.
Definition: TextWriter.cs:15
Represents an assembly, which is a reusable, versionable, and self-describing building block of a com...
Definition: Assembly.cs:22
Defines the underlying structure of all code access permissions.
virtual CompilerResults FromFileBatch(CompilerParameters options, string[] fileNames)
Compiles the specified files using the specified options, and returns the results from the compilatio...
bool MoveNext()
Advances the enumerator to the next element of the collection.
virtual CompilerResults FromDom(CompilerParameters options, CodeCompileUnit e)
Compiles the specified compile unit using the specified options, and returns the results from the com...
virtual void Flush()
Clears all buffers for the current writer and causes any buffered data to be written to the underlyin...
Definition: TextWriter.cs:515
CompilerResults CompileAssemblyFromDom(CompilerParameters options, CodeCompileUnit compilationUnit)
Compiles an assembly from the N:System.CodeDom tree contained in the specified T:System....
virtual CompilerResults FromSource(CompilerParameters options, string source)
Compiles the specified source code string using the specified options, and returns the results from t...
Represents a mutable string of characters. This class cannot be inherited.To browse the ....
static void RevertAssert()
Causes any previous M:System.Security.CodeAccessPermission.Assert for the current frame to be removed...
virtual string GetResponseFileCmdArgs(CompilerParameters options, string cmdArgs)
Gets the command arguments to use when invoking the compiler to generate a response file.
Provides a container for a CodeDOM program graph.
abstract void ProcessCompilerOutputLine(CompilerResults results, string line)
Processes the specified line from the specified T:System.CodeDom.Compiler.CompilerResults.
void Demand()
Forces a T:System.Security.SecurityException at run time if all callers higher in the call stack have...
override void Write(char value)
Writes a character to the stream.
override long Length
Gets the length in bytes of the stream.
Definition: FileStream.cs:126
int Count
Gets the number of strings contained in the T:System.Collections.Specialized.StringCollection.
Provides an example implementation of the T:System.CodeDom.Compiler.ICodeCompiler interface.
Definition: CodeCompiler.cs:14
CompilerErrorCollection Errors
Gets the collection of compiler errors and warnings.
string PathToAssembly
Gets or sets the path of the compiled assembly.
virtual CompilerResults FromSourceBatch(CompilerParameters options, string[] sources)
Compiles the specified source code strings using the specified options, and returns the results from ...
FileAccess
Defines constants for read, write, or read/write access to a file.
Definition: FileAccess.cs:9
int NativeCompilerReturnValue
Gets or sets the compiler's return value.
static Encoding UTF8
Gets an encoding for the UTF-8 format.
Definition: Encoding.cs:1023
Provides static methods for the creation, copying, deletion, moving, and opening of a single file,...
Definition: File.cs:14
static void Delete(string path)
Deletes the specified file.
Definition: File.cs:324
void Assert()
Declares that the calling code can access the resource protected by a permission demand through the c...
SecurityPermissionFlag
Specifies access flags for the security permission object.
override void Flush()
Clears all buffers for the current writer and causes any buffered data to be written to the underlyin...
Performs operations on T:System.String instances that contain file or directory path information....
Definition: Path.cs:13
string AddExtension(string fileExtension)
Adds a file name with the specified file name extension to the collection.
Represents the Windows user prior to an impersonation operation.
FileShare
Contains constants for controlling the kind of access other T:System.IO.FileStream objects can have t...
Definition: FileShare.cs:9
Provides a generic view of a sequence of bytes. This is an abstract class.To browse the ....
Definition: Stream.cs:16