2 // System.Reflection.Emit/AssemblyBuilder.cs
5 // Paolo Molaro (lupus@ximian.com)
7 // (C) 2001 Ximian, Inc. http://www.ximian.com
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System
.Reflection
;
35 using System
.Resources
;
37 using System
.Security
.Policy
;
38 using System
.Runtime
.Serialization
;
39 using System
.Globalization
;
40 using System
.Runtime
.CompilerServices
;
41 using System
.Collections
;
42 using System
.Runtime
.InteropServices
;
43 using System
.Security
;
44 using System
.Security
.Cryptography
;
45 using System
.Security
.Permissions
;
48 using Mono
.Security
.Cryptography
;
50 namespace System
.Reflection
.Emit
{
52 internal struct RefEmitPermissionSet
{
53 public SecurityAction action
;
56 public RefEmitPermissionSet (SecurityAction action
, string pset
) {
62 internal struct MonoResource
{
65 public string filename
;
66 public ResourceAttributes attrs
;
70 internal struct MonoWin32Resource
{
76 public MonoWin32Resource (int res_type
, int res_id
, int lang_id
, byte[] data
) {
77 this.res_type
= res_type
;
79 this.lang_id
= lang_id
;
84 public sealed class AssemblyBuilder
: Assembly
{
85 #region Sync with reflection.h
86 private IntPtr dynamic_assembly
;
87 private MethodInfo entry_point
;
88 private ModuleBuilder
[] modules
;
91 private CustomAttributeBuilder
[] cattrs
;
92 private MonoResource
[] resources
;
98 PEFileKinds pekind
= PEFileKinds
.Dll
;
101 Module
[] loaded_modules
;
102 MonoWin32Resource
[] win32_resources
;
103 private RefEmitPermissionSet
[] permissions_minimum
;
104 private RefEmitPermissionSet
[] permissions_optional
;
105 private RefEmitPermissionSet
[] permissions_refused
;
106 PortableExecutableKind peKind
;
107 ImageFileMachine machine
;
109 internal Type corlib_object_type
= typeof (System
.Object
);
110 internal Type corlib_value_type
= typeof (System
.ValueType
);
111 internal Type corlib_enum_type
= typeof (System
.Enum
);
112 internal Type corlib_void_type
= typeof (void);
113 ArrayList resource_writers
= null;
114 Win32VersionResource version_res
;
117 private Mono
.Security
.StrongName sn
;
119 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
120 private static extern void basic_init (AssemblyBuilder ab
);
122 internal AssemblyBuilder (AssemblyName n
, string directory
, AssemblyBuilderAccess access
) {
124 if (directory
== null || directory
== String
.Empty
)
125 dir
= Directory
.GetCurrentDirectory ();
128 this.access
= (uint)access
;
130 /* Set defaults from n */
131 if (n
.CultureInfo
!= null) {
132 culture
= n
.CultureInfo
.Name
;
134 Version v
= n
.Version
;
136 version
= v
.ToString ();
139 if (n
.KeyPair
!= null) {
140 // full keypair is available (for signing)
141 sn
= n
.KeyPair
.StrongName ();
144 // public key is available (for delay-signing)
145 byte[] pk
= n
.GetPublicKey ();
146 if ((pk
!= null) && (pk
.Length
> 0)) {
147 sn
= new Mono
.Security
.StrongName (pk
);
154 public override string CodeBase
{
156 throw not_supported ();
160 public override MethodInfo EntryPoint
{
166 public override string Location
{
168 throw not_supported ();
173 /* This is to keep signature compatibility with MS.NET */
174 public override string ImageRuntimeVersion
{
176 return base.ImageRuntimeVersion
;
181 public void AddResourceFile (string name
, string fileName
)
183 AddResourceFile (name
, fileName
, ResourceAttributes
.Public
);
186 public void AddResourceFile (string name
, string fileName
, ResourceAttributes attribute
)
188 AddResourceFile (name
, fileName
, attribute
, true);
191 private void AddResourceFile (string name
, string fileName
, ResourceAttributes attribute
, bool fileNeedsToExists
)
193 check_name_and_filename (name
, fileName
, fileNeedsToExists
);
195 // Resource files are created/searched under the assembly storage
198 fileName
= Path
.Combine (dir
, fileName
);
200 if (resources
!= null) {
201 MonoResource
[] new_r
= new MonoResource
[resources
.Length
+ 1];
202 System
.Array
.Copy(resources
, new_r
, resources
.Length
);
205 resources
= new MonoResource
[1];
207 int p
= resources
.Length
- 1;
208 resources
[p
].name
= name
;
209 resources
[p
].filename
= fileName
;
210 resources
[p
].attrs
= attribute
;
214 /// Don't change the method name and parameters order. It is used by mcs
216 internal void AddPermissionRequests (PermissionSet required
, PermissionSet optional
, PermissionSet refused
)
219 throw new InvalidOperationException ("Assembly was already saved.");
221 // required for base Assembly class (so the permissions
222 // can be used even if the assembly isn't saved to disk)
224 _optional
= optional
;
227 // required to reuse AddDeclarativeSecurity support
228 // already present in the runtime
229 if (required
!= null) {
230 permissions_minimum
= new RefEmitPermissionSet
[1];
231 permissions_minimum
[0] = new RefEmitPermissionSet (
232 SecurityAction
.RequestMinimum
, required
.ToXml ().ToString ());
234 if (optional
!= null) {
235 permissions_optional
= new RefEmitPermissionSet
[1];
236 permissions_optional
[0] = new RefEmitPermissionSet (
237 SecurityAction
.RequestOptional
, optional
.ToXml ().ToString ());
239 if (refused
!= null) {
240 permissions_refused
= new RefEmitPermissionSet
[1];
241 permissions_refused
[0] = new RefEmitPermissionSet (
242 SecurityAction
.RequestRefuse
, refused
.ToXml ().ToString ());
246 internal void EmbedResourceFile (string name
, string fileName
)
248 EmbedResourceFile (name
, fileName
, ResourceAttributes
.Public
);
251 internal void EmbedResourceFile (string name
, string fileName
, ResourceAttributes attribute
)
253 if (resources
!= null) {
254 MonoResource
[] new_r
= new MonoResource
[resources
.Length
+ 1];
255 System
.Array
.Copy(resources
, new_r
, resources
.Length
);
258 resources
= new MonoResource
[1];
260 int p
= resources
.Length
- 1;
261 resources
[p
].name
= name
;
262 resources
[p
].attrs
= attribute
;
264 FileStream s
= new FileStream (fileName
, FileMode
.Open
, FileAccess
.Read
);
266 resources
[p
].data
= new byte [len
];
267 s
.Read (resources
[p
].data
, 0, (int)len
);
274 internal void EmbedResource (string name
, byte[] blob
, ResourceAttributes attribute
)
276 if (resources
!= null) {
277 MonoResource
[] new_r
= new MonoResource
[resources
.Length
+ 1];
278 System
.Array
.Copy(resources
, new_r
, resources
.Length
);
281 resources
= new MonoResource
[1];
283 int p
= resources
.Length
- 1;
284 resources
[p
].name
= name
;
285 resources
[p
].attrs
= attribute
;
286 resources
[p
].data
= blob
;
289 public ModuleBuilder
DefineDynamicModule (string name
)
291 return DefineDynamicModule (name
, name
, false, true);
294 public ModuleBuilder
DefineDynamicModule (string name
, bool emitSymbolInfo
)
296 return DefineDynamicModule (name
, name
, emitSymbolInfo
, true);
299 public ModuleBuilder
DefineDynamicModule(string name
, string fileName
)
301 return DefineDynamicModule (name
, fileName
, false, false);
304 public ModuleBuilder
DefineDynamicModule (string name
, string fileName
,
307 return DefineDynamicModule (name
, fileName
, emitSymbolInfo
, false);
310 private ModuleBuilder
DefineDynamicModule (string name
, string fileName
,
311 bool emitSymbolInfo
, bool transient
)
313 check_name_and_filename (name
, fileName
, false);
316 if (Path
.GetExtension (fileName
) == String
.Empty
)
317 throw new ArgumentException ("Module file name '" + fileName
+ "' must have file extension.");
319 throw new NotSupportedException ("Persistable modules are not supported in a dynamic assembly created with AssemblyBuilderAccess.Run");
321 throw new InvalidOperationException ("Assembly was already saved.");
324 ModuleBuilder r
= new ModuleBuilder (this, name
, fileName
, emitSymbolInfo
, transient
);
326 if ((modules
!= null) && is_module_only
)
327 throw new InvalidOperationException ("A module-only assembly can only contain one module.");
329 if (modules
!= null) {
330 ModuleBuilder
[] new_modules
= new ModuleBuilder
[modules
.Length
+ 1];
331 System
.Array
.Copy(modules
, new_modules
, modules
.Length
);
332 modules
= new_modules
;
334 modules
= new ModuleBuilder
[1];
336 modules
[modules
.Length
- 1] = r
;
340 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
341 private extern Module
InternalAddModule (string fileName
);
344 * Mono extension to support /addmodule in mcs.
346 internal Module
AddModule (string fileName
)
348 if (fileName
== null)
349 throw new ArgumentNullException (fileName
);
351 Module m
= InternalAddModule (fileName
);
353 if (loaded_modules
!= null) {
354 Module
[] new_modules
= new Module
[loaded_modules
.Length
+ 1];
355 System
.Array
.Copy (loaded_modules
, new_modules
, loaded_modules
.Length
);
356 loaded_modules
= new_modules
;
358 loaded_modules
= new Module
[1];
360 loaded_modules
[loaded_modules
.Length
- 1] = m
;
365 public IResourceWriter
DefineResource (string name
, string description
, string fileName
)
367 return DefineResource (name
, description
, fileName
, ResourceAttributes
.Public
);
370 public IResourceWriter
DefineResource (string name
, string description
,
371 string fileName
, ResourceAttributes attribute
)
373 IResourceWriter writer
;
375 // description seems to be ignored
376 AddResourceFile (name
, fileName
, attribute
, false);
377 writer
= new ResourceWriter (fileName
);
378 if (resource_writers
== null)
379 resource_writers
= new ArrayList ();
380 resource_writers
.Add (writer
);
384 private void AddUnmanagedResource (Win32Resource res
) {
385 MemoryStream ms
= new MemoryStream ();
388 if (win32_resources
!= null) {
389 MonoWin32Resource
[] new_res
= new MonoWin32Resource
[win32_resources
.Length
+ 1];
390 System
.Array
.Copy (win32_resources
, new_res
, win32_resources
.Length
);
391 win32_resources
= new_res
;
394 win32_resources
= new MonoWin32Resource
[1];
396 win32_resources
[win32_resources
.Length
- 1] = new MonoWin32Resource (res
.Type
.Id
, res
.Name
.Id
, res
.Language
, ms
.ToArray ());
400 public void DefineUnmanagedResource (byte[] resource
)
402 if (resource
== null)
403 throw new ArgumentNullException ("resource");
406 * The format of the argument byte array is not documented
407 * so this method is impossible to implement.
410 throw new NotImplementedException ();
413 public void DefineUnmanagedResource (string resourceFileName
)
415 if (resourceFileName
== null)
416 throw new ArgumentNullException ("resourceFileName");
417 if (resourceFileName
== String
.Empty
)
418 throw new ArgumentException ("resourceFileName");
419 if (!File
.Exists (resourceFileName
) || Directory
.Exists (resourceFileName
))
420 throw new FileNotFoundException ("File '" + resourceFileName
+ "' does not exists or is a directory.");
422 using (FileStream fs
= new FileStream (resourceFileName
, FileMode
.Open
)) {
423 Win32ResFileReader reader
= new Win32ResFileReader (fs
);
425 foreach (Win32EncodedResource res
in reader
.ReadResources ()) {
426 if (res
.Name
.IsName
|| res
.Type
.IsName
)
427 throw new InvalidOperationException ("resource files with named resources or non-default resource types are not supported.");
429 AddUnmanagedResource (res
);
434 public void DefineVersionInfoResource ()
436 if (version_res
!= null)
437 throw new ArgumentException ("Native resource has already been defined.");
439 version_res
= new Win32VersionResource (1, 0);
441 if (cattrs
!= null) {
442 foreach (CustomAttributeBuilder cb
in cattrs
) {
443 string attrname
= cb
.Ctor
.ReflectedType
.FullName
;
445 if (attrname
== "System.Reflection.AssemblyProductAttribute")
446 version_res
.ProductName
= cb
.string_arg ();
447 else if (attrname
== "System.Reflection.AssemblyCompanyAttribute")
448 version_res
.CompanyName
= cb
.string_arg ();
449 else if (attrname
== "System.Reflection.AssemblyCopyrightAttribute")
450 version_res
.LegalCopyright
= cb
.string_arg ();
451 else if (attrname
== "System.Reflection.AssemblyTrademarkAttribute")
452 version_res
.LegalTrademarks
= cb
.string_arg ();
453 else if (attrname
== "System.Reflection.AssemblyCultureAttribute")
454 version_res
.FileLanguage
= new CultureInfo (GetCultureString (cb
.string_arg ())).LCID
;
455 else if (attrname
== "System.Reflection.AssemblyFileVersionAttribute")
456 version_res
.FileVersion
= cb
.string_arg ();
457 else if (attrname
== "System.Reflection.AssemblyInformationalVersionAttribute")
458 version_res
.ProductVersion
= cb
.string_arg ();
459 else if (attrname
== "System.Reflection.AssemblyTitleAttribute")
460 version_res
.FileDescription
= cb
.string_arg ();
461 else if (attrname
== "System.Reflection.AssemblyDescriptionAttribute")
462 version_res
.Comments
= cb
.string_arg ();
467 public void DefineVersionInfoResource (string product
, string productVersion
,
468 string company
, string copyright
, string trademark
)
470 if (version_res
!= null)
471 throw new ArgumentException ("Native resource has already been defined.");
474 * We can only create the resource later, when the file name and
475 * the binary version is known.
478 version_res
= new Win32VersionResource (1, 0);
479 version_res
.ProductName
= product
;
480 version_res
.ProductVersion
= productVersion
;
481 version_res
.CompanyName
= company
;
482 version_res
.LegalCopyright
= copyright
;
483 version_res
.LegalTrademarks
= trademark
;
487 * Mono extension to support /win32icon in mcs
489 internal void DefineIconResource (string iconFileName
)
491 if (iconFileName
== null)
492 throw new ArgumentNullException ("iconFileName");
493 if (iconFileName
== String
.Empty
)
494 throw new ArgumentException ("iconFileName");
495 if (!File
.Exists (iconFileName
) || Directory
.Exists (iconFileName
))
496 throw new FileNotFoundException ("File '" + iconFileName
+ "' does not exists or is a directory.");
498 using (FileStream fs
= new FileStream (iconFileName
, FileMode
.Open
)) {
499 Win32IconFileReader reader
= new Win32IconFileReader (fs
);
501 ICONDIRENTRY
[] entries
= reader
.ReadIcons ();
503 Win32IconResource
[] icons
= new Win32IconResource
[entries
.Length
];
504 for (int i
= 0; i
< entries
.Length
; ++i
) {
505 icons
[i
] = new Win32IconResource (i
+ 1, 0, entries
[i
]);
506 AddUnmanagedResource (icons
[i
]);
509 Win32GroupIconResource
group = new Win32GroupIconResource (1, 0, icons
);
510 AddUnmanagedResource (group);
514 private void DefineVersionInfoResourceImpl (string fileName
) {
516 if (version_res
.FileVersion
== "0.0.0.0")
517 version_res
.FileVersion
= version
;
518 version_res
.InternalName
= Path
.GetFileNameWithoutExtension (fileName
);
519 version_res
.OriginalFilename
= fileName
;
521 AddUnmanagedResource (version_res
);
524 public ModuleBuilder
GetDynamicModule (string name
)
527 throw new ArgumentNullException ("name");
529 throw new ArgumentException ("Name can't be null");
532 for (int i
= 0; i
< modules
.Length
; ++i
)
533 if (modules
[i
].name
== name
)
538 public override Type
[] GetExportedTypes ()
540 throw not_supported ();
543 public override FileStream
GetFile (string name
)
545 throw not_supported ();
548 public override FileStream
[] GetFiles(bool getResourceModules
) {
549 throw not_supported ();
552 public override ManifestResourceInfo
GetManifestResourceInfo(string resourceName
) {
553 throw not_supported ();
556 public override string[] GetManifestResourceNames() {
557 throw not_supported ();
560 public override Stream
GetManifestResourceStream(string name
) {
561 throw not_supported ();
563 public override Stream
GetManifestResourceStream(Type type
, string name
) {
564 throw not_supported ();
567 internal bool IsSave
{
569 return access
!= (uint)AssemblyBuilderAccess
.Run
;
573 internal string AssemblyDir
{
580 * Mono extension. If this is set, the assembly can only contain one
581 * module, access should be Save, and the saved image will not contain an
584 internal bool IsModuleOnly
{
586 return is_module_only
;
589 is_module_only
= value;
598 void Save (string assemblyFileName
, PortableExecutableKind portableExecutableKind
, ImageFileMachine imageFileMachine
)
600 this.peKind
= portableExecutableKind
;
601 this.machine
= imageFileMachine
;
603 if (resource_writers
!= null) {
604 foreach (IResourceWriter writer
in resource_writers
) {
610 // Create a main module if not already created
611 ModuleBuilder mainModule
= null;
612 if (modules
!= null) {
613 foreach (ModuleBuilder module
in modules
)
614 if (module
.FullyQualifiedName
== assemblyFileName
)
617 if (mainModule
== null)
618 mainModule
= DefineDynamicModule ("RefEmit_OnDiskManifestModule", assemblyFileName
);
621 mainModule
.IsMain
= true;
624 * Create a new entry point if the one specified
625 * by the user is in another module.
627 if ((entry_point
!= null) && entry_point
.DeclaringType
.Module
!= mainModule
) {
629 if (entry_point
.GetParameters ().Length
== 1)
630 paramTypes
= new Type
[] { typeof (string) }
;
632 paramTypes
= new Type
[0];
634 MethodBuilder mb
= mainModule
.DefineGlobalMethod ("__EntryPoint$", MethodAttributes
.Static
|MethodAttributes
.PrivateScope
, entry_point
.ReturnType
, paramTypes
);
635 ILGenerator ilgen
= mb
.GetILGenerator ();
636 if (paramTypes
.Length
== 1)
637 ilgen
.Emit (OpCodes
.Ldarg_0
);
638 ilgen
.Emit (OpCodes
.Tailcall
);
639 ilgen
.Emit (OpCodes
.Call
, entry_point
);
640 ilgen
.Emit (OpCodes
.Ret
);
645 if (version_res
!= null)
646 DefineVersionInfoResourceImpl (assemblyFileName
);
649 // runtime needs to value to embed it into the assembly
650 public_key
= sn
.PublicKey
;
653 foreach (ModuleBuilder module
in modules
)
654 if (module
!= mainModule
)
657 // Write out the main module at the end, because it needs to
658 // contain the hash of the other modules
661 if ((sn
!= null) && (sn
.CanSign
)) {
662 sn
.Sign (System
.IO
.Path
.Combine (this.AssemblyDir
, assemblyFileName
));
668 public void Save (string assemblyFileName
)
670 Save (assemblyFileName
, PortableExecutableKind
.ILOnly
, ImageFileMachine
.I386
);
673 public void SetEntryPoint (MethodInfo entryMethod
)
675 SetEntryPoint (entryMethod
, PEFileKinds
.ConsoleApplication
);
678 public void SetEntryPoint (MethodInfo entryMethod
, PEFileKinds fileKind
)
680 if (entryMethod
== null)
681 throw new ArgumentNullException ("entryMethod");
682 if (entryMethod
.DeclaringType
.Assembly
!= this)
683 throw new InvalidOperationException ("Entry method is not defined in the same assembly.");
685 entry_point
= entryMethod
;
689 public void SetCustomAttribute( CustomAttributeBuilder customBuilder
)
691 if (customBuilder
== null)
692 throw new ArgumentNullException ("customBuilder");
694 string attrname
= customBuilder
.Ctor
.ReflectedType
.FullName
;
698 if (attrname
== "System.Reflection.AssemblyVersionAttribute") {
699 version
= create_assembly_version (customBuilder
.string_arg ());
701 } else if (attrname
== "System.Reflection.AssemblyCultureAttribute") {
702 culture
= GetCultureString (customBuilder
.string_arg ());
703 } else if (attrname
== "System.Reflection.AssemblyAlgorithmIdAttribute") {
704 data
= customBuilder
.Data
;
706 algid
= (uint)data
[pos
];
707 algid
|= ((uint)data
[pos
+ 1]) << 8;
708 algid
|= ((uint)data
[pos
+ 2]) << 16;
709 algid
|= ((uint)data
[pos
+ 3]) << 24;
710 } else if (attrname
== "System.Reflection.AssemblyFlagsAttribute") {
711 data
= customBuilder
.Data
;
713 flags
= (uint)data
[pos
];
714 flags
|= ((uint)data
[pos
+ 1]) << 8;
715 flags
|= ((uint)data
[pos
+ 2]) << 16;
716 flags
|= ((uint)data
[pos
+ 3]) << 24;
720 if (cattrs
!= null) {
721 CustomAttributeBuilder
[] new_array
= new CustomAttributeBuilder
[cattrs
.Length
+ 1];
722 cattrs
.CopyTo (new_array
, 0);
723 new_array
[cattrs
.Length
] = customBuilder
;
726 cattrs
= new CustomAttributeBuilder
[1];
727 cattrs
[0] = customBuilder
;
731 public void SetCustomAttribute ( ConstructorInfo con
, byte[] binaryAttribute
) {
733 throw new ArgumentNullException ("con");
734 if (binaryAttribute
== null)
735 throw new ArgumentNullException ("binaryAttribute");
737 SetCustomAttribute (new CustomAttributeBuilder (con
, binaryAttribute
));
740 internal void SetCorlibTypeBuilders (Type corlib_object_type
, Type corlib_value_type
, Type corlib_enum_type
) {
741 this.corlib_object_type
= corlib_object_type
;
742 this.corlib_value_type
= corlib_value_type
;
743 this.corlib_enum_type
= corlib_enum_type
;
746 internal void SetCorlibTypeBuilders (Type corlib_object_type
, Type corlib_value_type
, Type corlib_enum_type
, Type corlib_void_type
)
748 SetCorlibTypeBuilders (corlib_object_type
, corlib_value_type
, corlib_enum_type
);
749 this.corlib_void_type
= corlib_void_type
;
752 private Exception
not_supported () {
753 // Strange message but this is what MS.NET prints...
754 return new NotSupportedException ("The invoked member is not supported in a dynamic module.");
757 private void check_name_and_filename (string name
, string fileName
,
758 bool fileNeedsToExists
) {
760 throw new ArgumentNullException ("name");
761 if (fileName
== null)
762 throw new ArgumentNullException ("fileName");
764 throw new ArgumentException ("name cannot be empty", "name");
766 throw new ArgumentException ("fileName cannot be empty", "fileName");
767 if (Path
.GetFileName (fileName
) != fileName
)
768 throw new ArgumentException ("fileName '" + fileName
+ "' must not include a path.");
770 // Resource files are created/searched under the assembly storage
772 string fullFileName
= fileName
;
774 fullFileName
= Path
.Combine (dir
, fileName
);
776 if (fileNeedsToExists
&& !File
.Exists (fullFileName
))
777 throw new FileNotFoundException ("Could not find file '" + fileName
+ "'");
779 if (resources
!= null) {
780 for (int i
= 0; i
< resources
.Length
; ++i
) {
781 if (resources
[i
].filename
== fullFileName
)
782 throw new ArgumentException ("Duplicate file name '" + fileName
+ "'");
783 if (resources
[i
].name
== name
)
784 throw new ArgumentException ("Duplicate name '" + name
+ "'");
788 if (modules
!= null) {
789 for (int i
= 0; i
< modules
.Length
; ++i
) {
790 // Use fileName instead of fullFileName here
791 if (!modules
[i
].IsTransient () && (modules
[i
].FileName
== fileName
))
792 throw new ArgumentException ("Duplicate file name '" + fileName
+ "'");
793 if (modules
[i
].Name
== name
)
794 throw new ArgumentException ("Duplicate name '" + name
+ "'");
799 private String
create_assembly_version (String version
) {
800 String
[] parts
= version
.Split ('.');
801 int[] ver
= new int [4] { 0, 0, 0, 0 }
;
803 if ((parts
.Length
< 0) || (parts
.Length
> 4))
804 throw new ArgumentException ("The version specified '" + version
+ "' is invalid");
806 for (int i
= 0; i
< parts
.Length
; ++i
) {
807 if (parts
[i
] == "*") {
808 DateTime now
= DateTime
.Now
;
811 ver
[2] = (now
- new DateTime (2000, 1, 1)).Days
;
812 if (parts
.Length
== 3)
813 ver
[3] = (now
.Second
+ (now
.Minute
* 60) + (now
.Hour
* 3600)) / 2;
817 ver
[3] = (now
.Second
+ (now
.Minute
* 60) + (now
.Hour
* 3600)) / 2;
819 throw new ArgumentException ("The version specified '" + version
+ "' is invalid");
823 ver
[i
] = Int32
.Parse (parts
[i
]);
825 catch (FormatException
) {
826 throw new ArgumentException ("The version specified '" + version
+ "' is invalid");
831 return ver
[0] + "." + ver
[1] + "." + ver
[2] + "." + ver
[3];
834 private string GetCultureString (string str
)
836 return (str
== "neutral" ? String
.Empty
: str
);