source program preferably have. csproj or. vbproj files, if not, take some time to debug
I'll take vb.net as an example to explain the following:
from Proj we can get the following useful information
There are many configuration options in the Settings section that correspond to some compiler options
The <References> section is a reference to the project, the 3rd party class library is best to use absolute path
The <Imports> section is some namespaces to import
<Files> all files in the project, select buildaction = "Compile" file
With the VBC test, it is easy to note the following:
RootNamespace
Reference
Target
Imports
Plus bugreport can output all the source file code and bug reports. Not bad
Give you one end compile example:
Vbc/r:system.dll/r:system.data.dll/r:system.drawing.dll/r:system.web.dll/r:system.xml.dll/r:bin\ Microsoft.applicationblocks.data.dll/r:bin\exporttechnologies.webcontrols.rte.dll/imports: Microsoft.visualbasic/imports:system/imports:system.collections/imports:system.configuration/imports: System.data/imports:system.drawing/imports:system.web/imports:system.web.ui/imports:system.web.ui.htmlcontrols /imports:system.web.ui.webcontrols/imports:mms/rootnamespace:mms/t:library/out:truly.mms.dll/bugreport:bug.log AssemblyInfo.vb Global.asax.vb HDAdd.aspx.vb HDticketLogAdd.aspx.vb Mis.vb Pagebase.vb
If you do not have a proj file, you can use the following command to obtain:
dir/b *.vb > Filelist.txt
The use of CSC depends on your own thinking. There are 1 differences between what we compile and vs., because many of our options are not configured, but after testing, we can basically work properly.
-------------------------------------------------------------------------------------------------------
Using the C # 2.0 command line compiler
http://msdn.microsoft.com/zh-cn/library/ms379563 (vs.80). aspx
Summary: This article analyzes the process of building an application using the C # command-line compiler csc.exe. The reader is also presented with a number of compiler options unique to C # 2.0, such as extended/reference flags and strong name support. After reading the contents of this article, you will be able to easily generate a single file assembly and a multiple-file assembly in an environment that does not have a wizard.
Apply to:
Microsoft Visual C # 2.0
Note This article assumes that you are familiar with the C # programming language and the structure of the. NET Framework. It will also prove helpful to experience the sense of using command line tools.
Download the Cscsample.msi file.
The fun of Scsc.exe
Almost no one denies that the integrated development environment (IDE) (for example, Visual Studio 2005 and Visual C # Express 2005) offers many features that make programming work quite simple. However, in fact, the IDE itself usually does not provide access to all aspects of the underlying compiler. For example, Visual Studio 2005 does not support generating a multiple-file assembly.
In addition, understanding the process of compiling code at the command line may be useful for users with the following characteristics:
Prefer the simplest way to build a. NET Framework application.
The secret of how you want to uncover the way the IDE handles source code files.
You want to take advantage of the. NET build utility, such asNant or MSBuild.
There is no integrated development environment, for example, Visual Studio (but actually has a free . NET Framework SDK).
The. NET Framework is being used on unix-based systems where the command line is the tool that must be used, and you want to better understand the Mono and/or portable. NET ECMA compatible C # compilers.
Studying alternative. NET programming languages that are not currently integrated into Visual Studio.
Just want to expand their knowledge of the C # programming language.
If you belong to the users mentioned above, be faithful to your choice and read on.
C # Compiler Options Overview
The C # compiler csc.exe provides a number of options for controlling how to create a. NET assembly. At a higher level, command-line options fall into one of the following eight categories (table 1).
table 1. Categories of tags provided by csc.exe
C # compiler Category |
Defined |
Output file |
Options for controlling the format of the generated assembly, optional XML document files, and strong name information. |
Input file |
Allows users to specify options for input files and referenced assemblies. |
Resources |
Options for embedding any required resources, such as icons and string tables, into an assembly. |
Code generation |
These options control the generation of debug symbols. |
Errors and warnings |
Controls how the compiler handles source code errors/warnings. |
Language |
Enables/disables the definition of C # language features (for example, unsafe code) and conditional compilation symbols. |
Miscellaneous |
The most interesting options for this category allow you to specify the csc.exe response file. |
Senior |
This category specifies some compiler options that are more esoteric and often less important. |
The/incremental flags present in the 1.0 and 1.1 versions of the C # compiler are now obsolete.
As you read this article, you will learn about the core flags that exist in each compiler category (the most important word is the core). For most development scenarios, you can safely ignore many of the advanced options for the C # compiler. If you need more information about the csc.exe features not discussed in this article, be assured that you can refer to the Microsoft Visual Studio 2005 Documentation Help system (just search for "csc.exe" from the "Search" tab and drill down).
Note The MSDN documentation also helps you, because it describes how to set specific options for csc.exe within Visual Studio (if available).
Configure Environment variables
Before you can use any. NET SDK command-line tools, including the C # compiler, you need to configure your development computer to recognize their presence. The easiest way to do this is to use Start | All Programs | Visual Studio | Visual Studio Tools menu option to start a preconfigured Visual studio command prompt. This particular console can automatically initialize the necessary environment variables without you performing any action. (Visual Studio. NET 2003 users need to start their respective command prompts).
Note If you do not have Visual Studio, but you have installed the. NET Framework SDK, you can start | All Programs | The Microsoft. NET Framework SDK 2.0 menu option launches a preconfigured command prompt.
If you want to use the. NET command-line tool from any command prompt, you need to manually update your computer's Path variable. To do this, right-click the My Computer icon on your desktop and select the Properties menu option. From the dialog box that appears, click the Environment Variables button located below the Advanced tab. From the dialog box that appears, add the following directory listing at the end of the current Path variable in the System variable list (note that each entry must be separated by semicolons):
C:\Windows\Microsoft.NET\Framework\v2.0.40607
C:\Program Files\Microsoft Visual Studio 8\sdk\v2.0\bin
Note The list above points to the path to my current. NET 2.0 beta. Your path may vary slightly depending on the installation and version of Visual Studio and/or. NET SDK, so be sure to perform an integrity check.
Immediately after you update the Path variable, close all dialog boxes and any currently open Console windows so that you can submit your settings. You should now be able to execute csc.exe and other. NET tools from any command prompt. To test, enter the following command:
csc-?
ILDASM-?
If you see a lot of information showing up, you can continue.
back to the top of the page
Basic knowledge of command line
Users who have been able to work on the command line without any problems using csc.exe can skip to the next section. However, if the number of times you use the command line is limited, let me explain some basic details for the necessary preparation.
First, you can use backslashes or a single dash to specify the options for csc.exe. Second, it is illegal to have additional spaces between/or-and subsequent flags. Therefore, "-help" is completely correct, and "-help" is not feasible. To illustrate this, let's check the complete command-line option set using the Help flag:
Csc–help
Csc/help
If everything works, you should see all the possible flags, as shown in Figure 1.
Many options provide shorthand notation to save you some typing time. Suppose the shorthand notation for help flags is?, you can list the options for csc.exe as shown below:
csc–?
csc/?
Many options require additional adornments, such as directory paths and file names. A flag of this nature separates the flag from its adornment by using a colon. For example, the/reference option requires that the name of the. NET assembly be included in the assembly manifest:
Csc/reference:mylibrary.dll ...
Other logos are two yuan in nature because they are either enabled (+) or disabled (-). Binary flags always default to their disabled state, so you typically only need to use the plus sign mark. For example, to treat all compilation warnings as errors, you can enable the WARNASERROR flag:
Csc/warnaserror+ ...
The order of flags does not matter, but you must list the collection of all flags before you specify the input file collection. It is also worth noting that it is illegal to have additional spaces between the adornment and its associated data. For example, use/reference:mylibrary.dll instead of using/reference:mylibrary.dll.
back to the top of the page
Options for specifying input and control output
The first set of command-line options that we will analyze are used to specify compiler input (table 2) and controlled output (table 3). Note that the following table also marks the C # 2.0-specific option and any available shorthand notation.
table 2. Input-centric options for csc.exe
Input flags |
Defined |
Is it specific to C # 2.0? |
/recurse |
Notifies csc.exe to compile a C # file located in the project's subdirectory structure. The flag supports wildcard syntax. |
Whether |
/reference (/R) |
Used to specify an external assembly to be referenced in the current compilation. |
No, but the 2.0 compiler provides an alias Variant. |
/addmodule |
Used to specify modules to include in a multiple-file assembly. |
Whether |
table 3. Output-centric options for csc.exe
is the
Output flag |
Defined |
Specific to C # 2.0? |
/out |
Specifies the name of the assembly to be generated. If this flag is omitted, the name of the output file is based on the name of the initial input file (for the *.dll assembly) or the name of the class that defines the Main () method (for the *.exe assembly). The |
No |
,
/target (/t) |
Specifies the file format of the assembly to be created. The |
No |
the /doc |
is used to generate an XML document file. |
No |
,
/delaysign |
Allows you to generate assemblies with a strong name delay signature. The |
is a |
/keyfile |
Specifies the path to the *.snk file that is used to strongly name the assembly. |
is a |
/keycontainer |
Specifies the name of the container that contains the *.snk file. |
is a |
/platform |
Specifies the CPU that must exist to host the assembly (x86, Itanium, x64 or ANYCPU). Default is AnyCPU. |
is |
Perhaps the most versatile input/output option is/target. By using additional adornments (table 4), the flag tells the compiler that you are interested in which type of. NET assembly to generate.
table 4. Variants of the/target logo
Target Grooming |
Defined |
/target:exe |
Create a console-based assembly. This is the default option if the/target option is not specified. |
/target:winexe |
Creates an executable assembly that is based on Windows forms. Although you can use/target:exe to create a Windows forms application, the console window looms in the background of the main form. |
/target:library |
Used to build a. NET code base (*.dll). |
/target:module |
Create a module that will become part of a multiple-file assembly. |
back to the top of the page
Compiling the. NET code Base
To illustrate the process of using csc.exe input/Output options, we will create a strongly named Single file assembly (MyCodeLibrary.dll) to define a class type named SimpleType . To demonstrate the role of the/doc option, we will also generate an XML document file.
First, create a new folder named Mycsharpcode on drive C. In this folder, create a subdirectory named Mycodelibrary. Enter the following code using the text editor of your choice (notepad.exe), and save the file as a simpleType.cs in the C:\MyCSharpCode\MyCodeLibrary directory you just created.
SimpleType.cs
using System;
Namespace Mycodelibrary
{
///<summary>
///Simple utility type.
</summary> public
class SimpleType
{
///<summary>
///Print out Select environment Information
///</summary> public
static void Displayenvironment ()
{
Console.WriteLine (" Location of this program: {0} ",
environment.currentdirectory);
Console.WriteLine ("Name of machine: {0}",
environment.machinename);
Console.WriteLine ("OS of machine: {0}",
environment.osversion);
Console.WriteLine ("Version of. NET: {0}",
environment.version);
}
}
Now, open the command prompt and use the CD (change directory) command to navigate to the location of the SimpleType.cs file (C:\MyCSharpCode\MyCodeLibrary):
CD Mycsharpcode\mycodelibrary
Or
CD C:\MyCSharpCode\MyCodeLibrary
To compile the source code file as a single file assembly named MyCodeLibrary.dll, specify the following set of commands:
Csc/t:library/out:mycodelibrary.dll SimpleType.cs
At this point, you should have a completely new. NET code base in the application directory, as shown in Figure 2.
Figure 2. New. NET code Base
When compiling multiple C # files on the command line, you can list each file individually-this can be helpful if you want to compile a subset of C # files that are contained in a single directory. Suppose we have created another C # code file named AsmInfo.cs (saved in the same directory), which defines the following assembly-level attributes to describe our code base:
AsmInfo.cs
using System;
Using System.Reflection;
A Few assembly level attributes.
[Assembly:assemblyversion ("1.0.0.0")]
[Assembly:assemblydescription ("Just An example Library")]
[Assembly:assemblycompany ("Intertech training")]
To compile only SimpleType.cs and AsmInfo.cs files, type:
Csc/t:library/out:mycodelibrary.dll SimpleType.cs AsmInfo.cs
As you might expect, csc.exe supports wildcard notation. Therefore, to compile all the files in a single directory, specify only *.cs as input options:
Csc/t:library/out:mycodelibrary.dll *.cs
Use /recurse Specify subdirectories
When you create an application, you definitely like to create a logical directory structure for your project. Instead of dumping up to 25 files into a single directory named MYAPP, you can organize code files into specific subdirectories (\core, \asminfo, \menusystem, and so on). Although our current example contains only a few files, suppose you place the AsmInfo.cs file in a new subdirectory named \asminfo (shown in Figure 3).
Figure 3. New \asminfo subdirectory
To tell the C # compiler to compile all C # files located in the root directory and the Asminfo subdirectory, use the/recurse option:
Csc/t:library/out:mycodelibrary.dll/recurse:asminfo/doc:mydoc.xml *.cs
Here,/recurse has been qualified with the name of a specific subdirectory. To specify more than one subdirectory, we can use wildcard syntax again. If we want to move the SimpleType.cs file to a new subdirectory named Core, we can compile all the C # files in all subdirectories with the following command set:
Csc/t:library/out:mycodelibrary.dll/recurse:*.cs
In either case, the output is the same.
Use /doc generate XML document files
The SimpleType class is already equipped with various XML elements. As you probably know, the C # compiler will use these three-slash code annotations to generate an XML document file. To tell Csc.exe to create such a file, you must provide the/doc option and decorate it with the name of the file you want to generate:
Csc/t:library/out:mycodelibrary.dll/recurse:*.cs/doc:mydoc.xml
In the application directory, you should now see a new file named Mydoc.xml. If you open the file, you will find that your type is described in XML, as shown in Figure 5.
Figure 5. Type document in XML form
Note If you would like to know more about C # XML code comments, see the article XML Comments let your build documentation directly from Your Visual Studio. NET Source Files.
make a strong name with /keyfile
The final task of the current example is to assign a strong name to our assembly. Under. NET 1.1, creating a strong-named assembly requires the use of the [AssemblyKeyFile] attribute. While this is fine, the C # 2.0 compiler now provides the/KEYFILE flag to specify the location of the strong name key file (*.snk).
Create a new folder named Mykeypair on drive C, and then change to that directory using the command prompt. Next, use the Sn.exe utility â? " The k option creates a new key pair named Mykeypair.snk.
Sn-k mykeypair.snk
To strongly name a MyCodeLibrary.dll using csc.exe, issue the following set of commands:
Csc/t:library/out:mycodelibrary.dll/recurse:*.cs/doc:mydoc.xml/keyfile:c:\mykeypair\mykeypair.snk
To verify that the assembly does have a strong name, use the security utility (Secutil.exe) and the Â? The S option displays strong name information:
Secutil/smycodelibrary.dll
You should find that the public key value that is recorded in the assembly manifest is displayed as the output shown in Figure 6.
Figure 6. The output of the public key value
The C # 2.0 compiler does have other strong-name-centric flags (/delaysign and/keycontainer) that you might want to study in your spare time. In particular, use the/delaysign option if you want to enable delay signing.
back to the top of the page
Using C # response files
While it is possible to experience its inherent advantages while working through the command line, no one can deny that typing dozens of compiler options can result in finger cramps and typos. To help mitigate both issues, the C # compiler supports the use of response files.
Note All command prompts allow you to traverse the previous command using the UP and DOWN ARROW keys.
Response files (which, by convention, *.RSP file extensions) contain all the options that you want to supply to csc.exe. After you create the file, you can specify its name as the only option for the C # compiler. For illustration purposes, the following provides a response file that will be used to generate MyCodeLibrary.dll (note that you can use the # symbol to specify a comment).
# mycodelibraryargs.rsp # These
are ' options used
# to compile MyCodeLibrary.dll
# Output Target and Name.
/t:library
/out:mycodelibrary.dll
# Location of C # files.
/recurse:*.cs
# give me an XML doc.
/doc:mydoc.xml
# give me a strong name as.
/keyfile:c:\mykeypair\mykeypair.snk
Given the file, you can now specify MYCODELIBRARYARGS.RSP with the @ option:
csc @MyCodeLibraryArgs. RSP
If you prefer, you can specify multiple response files:
csc @MyCodeLibraryArgs. RSP @MoreArgs. RSP @EvenMoreArgs. RSP
Keep in mind that the response file is processed in the order in which it was encountered. Therefore, the settings in the previous file may be overridden by the settings in a later file.
The default response file and /noconfig Options
Finally, keep in mind that there is a default response file-csc.rsp, which is automatically processed by csc.exe during each compilation. If you analyze the contents of the file (which is in the same folder as the csc.exe itself), you will only find a set of frequently referenced assemblies (System.Windows.Forms.dll, System.Data.dll, and so on).
In the rare occasions where you want to ban including csc.rsp, you can specify the/NOCONFIG flag:
Csc/noconfig @MyCodeLibraryArgs. RSP
Note If you reference an assembly and do not actually use it, it will not be listed in the assembly manifest. Therefore, do not worry about code bloat because they do not exist at all.
back to the top of the page
Referencing an external assembly using/reference
At this point, we have created a single file code base with a strong name (and a description) using the command-line compiler. Now, we need a client application to use it. Please create a new folder named MyClient in C:\MyCSharpCode. In this folder, create a new C # code file (SimpleTypeClient.cs) that calls the static Simpletype.displayenvironment () method from the entry point of the program:
SimpleTypeClient.cs
using System;
Namespace in MyCodeLibrary.dll
using Mycodelibrary;
Namespace Myclientapp
{public
class MyApp
{public
static void Main ()
{
Simpletype.displayenvironment ();
Console.ReadLine ();}}
Because our client application uses MyCodeLibrary.dll, we need to use/reference (or just use the/r) option. This flag is flexible because you can specify the full path of the *dll you are discussing, as follows:
Csc/t:exe/r:c:\mycsharpcode\mycodelibrary\mycodelibrary.dll *.cs
Alternatively, if a copy of the private assembly is in the same folder as the input file, you can specify only the assembly name:
Csc/t:exe/r:mycodelibrary.dll *.cs
Please note that I do not specify the/OUT option. Given this condition, Csc.exe creates a name based on our initial input file (SimpleTypeClient.cs). In addition, the default behavior of the known/target is to generate a console based application, so the/t:exe parameter is optional.
In any case, because MyCodeLibrary.dll is a private assembly, you need to place a copy of the library in the MyClient directory. After you have completed the work, you will be able to execute the SimpleTypeClient.exe application. Figure 7 shows a possible test run.
Figure 7. Possible test run output
Note Please recall this problem without deploying a strong-named assembly into the global Assembly cache (GAC). In fact, because strong names have a natural security benefit, it is a. NET best policy to provide a strong name to each assembly, regardless of whether it is shared or not.
referencing multiple external assemblies
If you want to reference a large number of assemblies on the command line, you can specify multiple/reference options. To illustrate this point, suppose that our client application needs to use a type that is contained in a library named NewLib.dll:
Csc/t:exe/r:mycodelibrary.dll/r:newlib.dll *.cs
As a slightly simpler workaround, you can use a single/reference option and specify each assembly using a semicolon-delimited list:
CSC/T:EXE/R:MYCODELIBRARY.DL; NewLib.dll *.cs
Of course, the same syntax is used when authoring C # response files.
about brief description of/lib
Before you look at the role of the C # 2.0 assembly alias, allow me to briefly describe the/LIB flag. This option can be used to tell csc.exe the directory containing the assembly specified by the/reference option. For instructions, suppose you have three *.dll assemblies located in the root directory of drive C. To instruct Csc.exe in C:\ To find Asm1.dll, Asm2.dll, and Asm3.dll, you need to issue the following set of commands:
Csc/lib:c:\/reference:asm1.dll;asm2.dll;asm3.dll *.cs
If you are not using/lib, you will need to manually copy these three. NET code libraries to the directory that contains the input files. Also note that if the/LIB flag is issued more than once in a given set of commands, the results accumulate.
back to the top of the page
Understanding C # 2.0 Reference aliases
The last thing you need to do about the/reference option is that in C # 2.0, you can now create aliases for referenced assemblies. This feature resolves a name conflict problem that exists between types that contain exactly the same names in a uniquely named assembly.
To illustrate the usefulness of this feature, create a new folder named MyCodeLibrary2 in the C:\MyCSharpCode directory. Place a copy of the existing SimpleType.cs and AsmInfo.cs files in the new directory. Now, add a new way to SimpleType to display the strings provided by the client:
<summary>
///Display A user supplied message.
</summary> public
static void Printmessage (String msg)
{
Console.WriteLine (' you said: {0} ', msg) ;
}
Compile the files to create a new assembly named MyCodeLibrary2.dll, as follows:
Csc/t:library/out:mycodelibrary2.dll *.cs
Finally, a copy of this new code base is placed in the myclient folder (Figure 8).
Figure 8. New code in the MyClient folder
Now, if our current client program wants to refer to MyCodeLibrary.dll and MyCodeLibrary2.dll, we do the following:
Csc/t:exe/r:mycodelibrary.dll; MyCodeLibrary2.dll *.cs
The compiler tells us that we have introduced name collisions because both assemblies define a class named SimpleType :
SimpleTypeClient.cs (13,7): Error cs0433:the type ' Mycodelibrary.simpletype '
exists in both ' c:\MyCSharpCode\ Myclient\mycodelibrary.dll ' and
' C:\MyCSharpCode\MyClient\MyCodeLibrary2.dll '
At first glance, you may think you can fix the problem by using the fully qualified name in your client code. However, this does not correct the problem because the two assemblies define the same fully qualified name (Mycodelibrary). SimpleType).
With the new alias option for the/reference flag, we can generate a unique name for each referenced code base. After we do this, we can update the client code to associate a type with a particular assembly.
The first step is to modify the SimpleTypeClient.cs file to use the alias that we will specify on the command line via the new extern alias syntax:
Extern alias statements must to
//listed before all other code!
extern alias ST1;
extern alias ST2;
Using System;
Namespace Myclientapp
{public
class MyApp
{public
static void Main ()
{
//Bind assembly to Type using the ':: ' operator.
St1::mycodelibrary.simpletype.displayenvironment ();
St2::mycodelibrary.simpletype.printmessage ("hello!");
Console.ReadLine ();}}
Note that we have captured the alias defined on the command line using the C # 2.0 extern alias statement. Here,ST1(Simple Type 1) is an alias defined for MyCodeLibrary.dll, and ST2 is an alias for MyCodeLibrary2.dll:
Csc/r:st1=mycodelibrary.dll/r:st2=mycodelibrary2.dll *.cs
Given these aliases, note how the Main () method uses the C # 2.0 range resolution operator (::) To bind an assembly alias to the type itself:
This says ' I want the Mycodelibrary.simpletype class
//is defined in MyCodeLibrary.dll '.
St1::mycodelibrary.simpletype.displayenvironment ();
In turn, this variant of the/reference option provides a way to avoid name collisions (occurs when two of assemblies with unique names occur with identically named types).
back to the top of the page
Using/addmodule to generate a multiple-file assembly
As you may already know, a multiple-file assembly provides a way to decompose a single. NET binary file into smaller small files, which can prove helpful when downloading. NET modules remotely. The final effect of a multiple-file assembly is to make a set of files work like a separate reference and version-controlled unit.
A multiple-file assembly contains a primary *.dll, which contains an assembly manifest. Other modules of the multiple-file assembly (which, by convention, they use the *.netmodule file extension) are recorded in the main module's manifest and loaded on demand by the CLR. To date, the only way to generate a multiple-file assembly is by using a command-line compiler.
To illustrate this procedure, create a new subdirectory named Multifileasm in the C:\MyCSharpCode directory. Our goal is to create a multiple-file assembly named Airvehicles. The main module (Airvehicles.dll) will contain a single class type named helicopter (defined later). The assembly manifest catalogs an additional module (Ufos.netmodule) that defines a class type named UFO :
Ufo.cs
using System;
Using System.Windows.Forms;
Namespace Airvehicles
{public
class UFO
{public
void Abducthuman ()
{
MessageBox.Show () Resistance is futile ");}}}
To compile Ufo.cs as a. NET module, specify/t:module as the target type, which automatically follows the *.netmodule naming convention (recall that the default response file is automatically referenced System.Windows.Forms.dll, so we don't need to explicitly reference the library):
Csc/t:module Ufo.cs
If you are loading ufo.netmodule into Ildasm.exe, you will find a module-level manifest that records the name of the module and the external reference assembly (note that *.netmodules does not specify a version number because that is the work of the main module):
. assembly extern mscorlib{...}
. assembly extern system.windows.forms{...}
. Module Ufo.netmodule
Now, create a new file named Helicopter.cs that will be used to compile the main module Airvehicles.dll:
Helicopter.cs
using System;
Using System.Windows.Forms;
Namespace Airvehicles
{public
class helicopter
{public
void takeoff ()
{
MessageBox.Show ("Helicopter taking off!");}}
Assuming that Airvehicles.dll is the main module of the multiple-file assembly, you will need to specify the/T:LIBRARY flag. However, because you also want to encode the ufo.netmodule binaries into the assembly manifest, you must also specify the/addmodule option:
Csc/t:library/addmodule:ufo.netmodule/out:airvehicles.dll Helicopter.cs
If you are parsing an assembly-level manifest that is contained within a Airvehicles.dll binary (using Ildasm.exe), you will find that Ufo.netmodule is actually logged with the. File CIL instruction:
. Assembly airvehicles{...}
. File Ufo.netmodule
Users of multiple-file assemblies can be less concerned about the fact that the assemblies they are referencing consist of a large number of binary files. In fact, the syntax will look exactly the same as the behavior of using a single file assembly. To make this article more interesting, let's create a client application based on Windows forms.
back to the top of the page
Creating a Windows Forms application
Our next sample project will be a Windows forms application that uses the Airvehicles.dll assembly of multiple files. Create a new subdirectory named Winformclient in the C:\MyCSharpCode directory. Creates a class derived from Form that defines a single Button type that, when clicked, creates helicopter and UFO types, and calls their members:
Using System;
Using System.Windows.Forms;
Using Airvehicles;
public class Myform:form
{
private button btnusevehicles = New button ();
Public MyForm ()
{this
. Text = "My multifile Asm Client";
Btnusevehicles.text = "click Me";
Btnusevehicles.width = m;
Btnusevehicles.height = m;
Btnusevehicles.top = ten;
Btnusevehicles.left = ten;
Btnusevehicles.click + = new EventHandler (Btnusevehicles_click);
This. Controls.Add (btnusevehicles);
}
private void Btnusevehicles_click (object o, EventArgs e)
{
helicopter h = new helicopter ();
H.takeoff ();
UFO u = new UFO ();
U.abducthuman ();
}
private static void Main ()
{
Application.Run (new MyForm ());
}
note Before proceeding, make sure that the Airvehicals.dll and Ufo.netmodule binaries are copied to the winformclient directory.
To compile the application as a Windows forms executable, make sure that you specify the winexe as the adornment for the/target flag. Note that when referencing a multiple-file assembly, you must specify only the name of the main module:
Csc/t:winexe/r:airvehicles.dll *.cs
After you run your program and click the button, you should see each message box that appears as expected. Figure 9 shows a message box that I created.
Figure 9. Sample message box
back to the top of the page
Using Resources through Csc.exe
The next agenda is to analyze how to embed a resource, such as a string table or an image file, into a. NET assembly using csc.exe. First, you can use the/win32icon option to specify the path to the Win32 *.ico file. Suppose you have placed an icon file named Happydude.ico in the application directory of the current Windows forms application. To set the Happydude.ico as an icon for an executable file, issue the following command set:
Csc/t:winexe/win32icon:happydude.ico/r:airvehicles.dll *.cs
At this point, you should update the executable assembly, as shown in Figure 10.
Figure 10. An updated executable assembly
In addition to using/win32icon to assign application icons, Csc.exe provides three additional resource-centric options (table 5).
table 5. Resource-centric options for csc.exe
Resource-centric options for csc.exe |
Defined |
/resource |
Embeds the resources contained within the *.resources file into the current assembly. Note that this option allows you to embed resources "in public" for use by all consumers, or "private" to embed resources for use only with assemblies. |
/linkresource |
A link to an external resource file is recorded in the assembly manifest, but is not actually embedded in the resource itself. |
/win32res |
Allows you to embed resources that exist in legacy *.res files. |
Before we learn how to embed resources in our assemblies, let me briefly describe the nature of the resources in the. NET platform. As you may already know,. NET resources are initially typically rendered as a set of name/value pairs that are recorded as XML (*.resx files) or simple text (*.txt). The xml/text file is then converted to the equivalent binary, which takes the *.resources file name extension. These binaries are then embedded in the assembly and are recorded in the manifest. When you need to programmatically read a resource from this assembly, the System.Resources namespace provides many types to complete the work, the most notable of which is the ResourceManager class.
Although you can certainly create *.resx files manually, you might want to use the Resgen.exe command-line tool (or, of course, you can use Visual Studio. NET itself). Although this article does not intend to describe all the details of Resgen.exe, let's walkthrough a simple example.
Use /resource Embedded Resources
Under mycsharpcode , create a new directory named Myresourceapp. In this directory, use Notepad.exe to create a new file named MyStrings.txt that contains some interesting name/value pairs that you choose. For example:
# A List of personal data
#
Company=intertech training
lastclasstaught=.net Security
lastpresentation =SD East Best Practices
Favoritegameconsole=xbox
Favoritecomic=cerebus
Now, use the command prompt to convert the *.txt file to an xml-based *.resx file by using the following command:
ResGen MyStrings.txt Mystrings.resx
If you use Notepad.exe to open the file, you will find many XML elements that describe the name/value pairs, such as:
<data name= "Company" >
<value xml:space= "preserve" >intertech training</value>
</data >
<data name= "Lastclasstaught" >
<value xml:space= "preserve" >.net security</value>
</data>
To convert the *.resx file to a binary *.resources file, you must update the file name extension as a parameter to the Resgen.exe:
ResGen Mystrings.resx mystrings.resources
At this point, we have a binary resource file named Mystrings.resources. The/RESOURCE flag enables you to use the csc.exe to embed the data into a. NET assembly. Suppose we have authored the following C # file (ResApp.cs) located in the myresourceapp directory:
This is simple app. reads embedded//Resources and
displays them to the
//console.
Using System;
Using System.Resources;
Using System.Reflection;
public class ResApp
{
private static void Main ()
{
ResourceManager rm = new ResourceManager ("MyStrings ",
assembly.getexecutingassembly ());
Console.WriteLine ("Last taught a {0} class.",
RM. GetString ("Lastclasstaught"));
}
To compile the assembly relative to your mystrings.resources file, enter the following command:
Csc/resource:mystrings.resources *.cs
Because I haven't specified the/out flag, in this example, the name of our executable file will be based on the file resApp.exe that defines Main () . If everything works, you should find the output similar to Figure 11 after execution.
I hope you can easily create a single file and a multiple-file. NET assembly (with resources!) using csc.exe and the selected text editor. )。 You have learned the most common command-line options for csc.exe, and the remainder of this article will analyze some of the less common but still helpful options.
If you would like to continue with your study, create a new directory named Finalexample in the mycsharpcode folder.
back to the top of the page
To define preprocessor symbols using/define
Although the C # compiler does not have real preprocessing code, the language does allow us to use a preprocessor symbol similar to C to define the compiler and interact with it. Using the #define syntax of C #, you can create tokens that control the execution path within an application.
Note You must list the defined symbols before using any statements or other C # type definitions.
To take advantage of common examples, suppose you want to define a symbol named DEBUG. To do this, create a new file named FinalEx.cs and save it in the mycsharpcode\finalexample directory:
Define a ' preprocessor ' symbol named DEBUG.
#define DEBUG
using System;
public class Finalexample
{public
static void Main ()
{
#if debug
Console.WriteLine ("Debug Symbol defined ");
#else
Console.WriteLine ("DEBUG Not Defined");
#endif
}
}
Note that after we have defined the symbols using the #define, we can conditionally examine and respond to the symbol using #if, #else, and #endif keywords. If you compile the program now, you should see that the message "DEBUG symbol defined" is displayed to the console when FinalEx.exe executes:
CSC *.cs
However, if you comment out the symbol definition:
#define DEBUG
The output will be as you would expect ("DEBUG not Defined").
Defining symbols at the command line can be helpful during the development and testing of. NET assemblies. Doing so allows you to quickly specify symbols immediately without having to update the code base. For instructions, let's say you want to define the DEBUG symbol on the command line, use the/define option:
Csc/define:debug *.cs
When you run the application again, you should see the "DEBUG symbol defined" displayed-even if #define statement has been commented out.
back to the top of the page
Debug-centric options for csc.exe
Even the best programmers can sometimes find the need to debug their code base. Although I assume that most readers prefer to use Visual Studio. NET for debugging activities, it is worthwhile to illustrate some of the debugging-centric options of csc.exe (table 6).
table 6. Debug-centric options for csc.exe
Debug-centric options for csc.exe |
Defined |
/debug |
Instructs Csc.exe to emit a *.pdb file for use by debugging tools, such as Cordbg.exe, DbgCLR.exe, or Visual Studio. |
/warnaserror |
Treat all warnings as critical errors. |
/warn |
Allows you to specify the warning level (0, 1, 2, 3, or 4) of the current compilation. |
/nowarn |
Enables you to disable specific C # compiler warnings. |
/bugreport |
This option generates an error log if the application fails at run time. This option prompts you to enter corrective information to send to wherever you wish (for example, QA team). |
To illustrate the use of the/debug option, we first need to insert some coding errors in our FinalEx.cs code file. Please add the following code to the current Main () method:
Create an array.
String[] mystrings = {"Csc.exe is cool"};
Go out of bounds.
Console.WriteLine (Mystrings[1]);
As you can see, we are trying to access the contents of our array using a transboundary index. If you recompile and run the program, you will get indexoutofrangeexception. Although we can clearly point out the error, what if it is a less obvious and more complex error?
To debug an assembly created using csc.exe, the first step is to build a *.pdb file that contains the information you need for the various. NET debugging utilities. To do this, enter one of the following commands (which are functionally equivalent):
Csc/debug *.cs
csc/debug+ *.cs
At this point, you should see a new file named Finalex.pdb in the application directory, as shown in Figure 12.
Figure 12. New finalex.pdb in the application directory
/DEBUG flags can be qualified with full or pdbonly tags as appropriate. When you specify/debug:full (which is the default tag), the assembly is modified in the appropriate way so that it can be attached to the currently executing debugger. Now that this option can affect the size and speed of the resulting. NET Assembly, make sure that you specify this option only during debugging. Because full is the default behavior of the/DEBUG flag, all of the above options are functionally equivalent:
Csc/debug *.cs
csc/debug+ *.cs
csc/debug:full *.cs
On the other hand, specifies that/debug:pdbonly can generate a *.pdb file and an assembly that can only be debugged when the program is started directly by the Debugging tools:
Csc/debug:pdbonly *.cs
In any case, now that you have the necessary *.pdb files, you can debug your application with many debugging tools (Cordbg.exe, DbgCLR.exe, or Visual Studio). In order not to deviate from this article's emphasis on the command line feature, we will use the Cordbg.exe utility to debug the program:
CorDbg FinalEx.exe
After the debugging session has started, you can step through each line of code using the SO (single-step) command. When you click on a line of code that is wrong, you can find the code dump as shown in Figure 13.
Figure 13. Step into a command code dump
To terminate the Cordbg.exe utility, type exit and press the return key.
note The focus of this article is not to explain the use of the. NET Debugging Tools. If you want more information about the process of debugging at the command line, look for "Cordbg.exe" in the Visual Studio Help system.
back to the top of the page
Miscellaneous
At this point, you have learned the details behind the core options of the C # command line compiler. To make this article more complete, table 7 briefly describes the remaining flags that I have not yet discussed.
table 7. Remaining options for csc.exe
Csc.exe the rest of the options |
Defined |
/baseaddress |
This option allows you to specify the expected base address for loading *.dll. By default, the base address is selected by the CLR. |
/checked |
Specifies whether an integer operation that overflows the bounds of the data type will cause an exception at run time. |
/codepage |
Specifies the code page to use for all source code files in the compilation. |
/filealign |
This option controls the section sizing (512, 1024, 2048, 4096, or 8192 bytes) inside the output assembly. If the target device is a handheld device (for example, a Pocket PC), you can use/filealign to specify the most possible section. |
/langversion |
This option instructs the compiler to use only the ISO-1 C # language feature, which basically boils down to the C # 1.0 language feature. |
/main |
If the current project has more than one main () method defined (which might help during a unit test), you can use this flag to specify which Main () method to execute when an assembly is loaded. |
/nostdlib |
By default, an assembly manifest automatically references mscorlib.dll. Specify this option to prohibit this behavior. |
/optimize |
When enabled (/optimize+), instructs the compiler to generate the smallest and fastest assemblies possible. This option emits metadata that also instructs the CLR to optimize code at run time. |
/platform |
The flag tells the compiler to optimize the assembly for a 32-bit or 64-bit processor. In general, this option is useful only if the C # code base uses P/invoke and/or unsafe code structures. The default value is "AnyCPU". |
/unsafe |
When enabled, this option enables C # files to declare unsafe scopes, which are often used to manipulate C + + style pointers. |
/utf8output |
This option tells the compiler to use UTF-8 encoding to output data. |
It is important to understand that for the vast majority of. NET projects, the options listed in table 7 provide only very small benefits. In view of this, if you need further details, please refer to MSDN.
back to the top of the page
Summary
This article introduces you to the process of generating assemblies using the C # command-line compiler. As you already know, most of the work can be done using two flags-/target and/reference. In addition to analyzing the core flags of csc.exe, this article explains the benefits of responding to files and the structure of a multiple-file assembly.
Although this article does not provide full details about each option for csc.exe, I hope you can easily use the Visual Studio 2005 documentation to learn about the remaining flags.
Wish you a happy coding!
Andrew Troelsen is a Microsoft MVP who serves as a consultant and trainer at Intertech Training . Andrew wrote many books, including the award-winning C # and the. NET Platform Second Edition (Apress 2002). He writes a monthly column forMacTech , in which he studies how to use the SSCLI, portible.net, and Mono CLI to distribute. NET Development on unix-based systems.