Command line compile with csc

A

Andrew Warren

When I build my winforms exe using the IDE I have a
perfectly functioning exe. If I try to build the same
project using the .Net Framework csc compiler I get a
seemingly valid exe produced (although it's only 44 Kb
instead of 76 Kb).

When I then run the csc-compiled exe I immediately get
a "System.TypeInitializationException".

What am I missing? I'm guessing there may be some batch
file that sets an environment for csc but my installation
of the Framework (v1.1.4322) contains no batch or command
files of any description. I need to get this compiling
in an environment without the full SDK or VS.Net - only
the .Net Framework will be available in the target
environment (should be enough...).

I'd appreciate replies copied to andrew dot warren at
mincom dot com.

Thanks.
 
J

Jon Skeet [C# MVP]

Andrew Warren said:
When I build my winforms exe using the IDE I have a
perfectly functioning exe. If I try to build the same
project using the .Net Framework csc compiler I get a
seemingly valid exe produced (although it's only 44 Kb
instead of 76 Kb).

When I then run the csc-compiled exe I immediately get
a "System.TypeInitializationException".

What am I missing? I'm guessing there may be some batch
file that sets an environment for csc but my installation
of the Framework (v1.1.4322) contains no batch or command
files of any description. I need to get this compiling
in an environment without the full SDK or VS.Net - only
the .Net Framework will be available in the target
environment (should be enough...).

Do you have a short but complete example which demonstrates the
problem? It sounds very odd to me. Are you referencing any assemblies
other than the "built-in" ones?
 
A

Andrew Warren

Do you have a short but complete example which demonstrates the
problem? It sounds very odd to me. Are you referencing any assemblies
other than the "built-in" ones?

--
Jon Skeet - <[email protected]>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
.

I am using the following "built-ins" across various
classes:

Microsoft.Win32
System
System.Collections
System.ComponentModel
System.Data
System.Diagnostics
System.Drawing
System.IO
System.Runtime.InteropServices
System.Security
System.Security.Permissions
System.Text
System.Text.RegularExpressions
System.Threading
System.Windows.Forms
System.Xml

It just occurred to me that one of my classes makes a
call to an unmanaged Windows API that is not available in
the .Net Framework - could this be a factor?

Here is the declaration:
----------------------------------------------------------
[DllImport("kernel32.dll",CharSet=CharSet.Auto,
SetLastError=true)]

[return:MarshalAs(UnmanagedType.Bool)]

private static extern bool SetEnvironmentVariable(string
lpName, string lpValue);
----------------------------------------------------------

I compile with the following command line:
csc /out:myapp.exe /win32icon:myicon.ico /target:winexe
*.cs

The .cs files in the current directory include all forms
and classes for the app as well as the AssemblyInfo.cs
created by the IDE.

I can't really give you a complete example that would
also be short! Suffice to say though that apart from that
API call everything else is bog standard - no funny
stuff, just calls to Framework objects. My main form
uses a TreeView control, a DataGrid, and a couple of
buttons - pretty simple. It parses some XML and
populates the TreeView with node objects of my own class
that inherits from TreeNode. Once the tree is built you
can launch command-line sessions based on parameters
supplied by the selected tree node.
 
J

Jon Skeet [C# MVP]

Andrew Warren said:
I am using the following "built-ins" across various
classes:

<snip>

Hmm... they all look okay.
It just occurred to me that one of my classes makes a
call to an unmanaged Windows API that is not available in
the .Net Framework - could this be a factor?

I wouldn't have thought so...
I can't really give you a complete example that would
also be short!

Have you tried? For instance, have you tried writing an app that pretty
much *just* does the unmanaged API call? If that works, you can rule
that out as a reason for the failure.

The other thing you could try is wrapping the Application.Run call in a
try/catch block, and logging more details of the exception to a file.
 
P

Philip Rieck

Andrew : when you compile via the command line, you must include references
yourself.. For example, your application references Microsoft.Win32 ... so
make sure on your "csc" line, you include
"/r:Microsoft.Win32.dll" or whatever the assembly name is that that's
defined in. Do this for all assemblies you're referencing.



Andrew Warren said:
Do you have a short but complete example which demonstrates the
problem? It sounds very odd to me. Are you referencing any assemblies
other than the "built-in" ones?

--
Jon Skeet - <[email protected]>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
.

I am using the following "built-ins" across various
classes:

Microsoft.Win32
System
System.Collections
System.ComponentModel
System.Data
System.Diagnostics
System.Drawing
System.IO
System.Runtime.InteropServices
System.Security
System.Security.Permissions
System.Text
System.Text.RegularExpressions
System.Threading
System.Windows.Forms
System.Xml

It just occurred to me that one of my classes makes a
call to an unmanaged Windows API that is not available in
the .Net Framework - could this be a factor?

Here is the declaration:
----------------------------------------------------------
[DllImport("kernel32.dll",CharSet=CharSet.Auto,
SetLastError=true)]

[return:MarshalAs(UnmanagedType.Bool)]

private static extern bool SetEnvironmentVariable(string
lpName, string lpValue);
----------------------------------------------------------

I compile with the following command line:
csc /out:myapp.exe /win32icon:myicon.ico /target:winexe
*.cs

The .cs files in the current directory include all forms
and classes for the app as well as the AssemblyInfo.cs
created by the IDE.

I can't really give you a complete example that would
also be short! Suffice to say though that apart from that
API call everything else is bog standard - no funny
stuff, just calls to Framework objects. My main form
uses a TreeView control, a DataGrid, and a couple of
buttons - pretty simple. It parses some XML and
populates the TreeView with node objects of my own class
that inherits from TreeNode. Once the tree is built you
can launch command-line sessions based on parameters
supplied by the selected tree node.
 
J

Jon Skeet [C# MVP]

Jon Skeet said:
<snip>

Hmm... they all look okay.

I've just looked at them again - they look like namespaces, not
assemblies. What do you have under the References section of your
project?
 
J

Jon Skeet [C# MVP]

Philip Rieck said:
Andrew : when you compile via the command line, you must include references
yourself.. For example, your application references Microsoft.Win32 ... so
make sure on your "csc" line, you include
"/r:Microsoft.Win32.dll" or whatever the assembly name is that that's
defined in. Do this for all assemblies you're referencing.

Microsoft.Win32 is actually a namespace, not an assembly. The default
response file for csc automatically adds references for all these
assemblies:

Accessibility.dll
Microsoft.Vsa.dll
System.Configuration.Install.dll
System.Data.dll
System.Design.dll
System.DirectoryServices.dll
System.dll
System.Drawing.Design.dll
System.Drawing.dll
System.EnterpriseServices.dll
System.Management.dll
System.Messaging.dll
System.Runtime.Remoting.dll
System.Runtime.Serialization.Formatters.Soap.dll
System.Security.dll
System.ServiceProcess.dll
System.Web.dll
System.Web.Mobile.dll
System.Web.RegularExpressions.dll
System.Web.Services.dll
System.Windows.Forms.Dll
System.XML.dll

Only assemblies not in the above list need to be explicitly referenced.
 
P

Philip Rieck

Sorry - by "whatever that's defined in" -- I should have said "The assembly
that that namespace is defined in"

Since Andrew said that he's trying to do this without installing the SDK,
I'm wondering if he has no default response file, and so will have to
manually add references to all the referenced assemblies when he does a
compile.
 
J

Jon Skeet [C# MVP]

Philip Rieck said:
Sorry - by "whatever that's defined in" -- I should have said "The assembly
that that namespace is defined in"

Since Andrew said that he's trying to do this without installing the SDK,
I'm wondering if he has no default response file, and so will have to
manually add references to all the referenced assemblies when he does a
compile.

I wouldn't think so. Bear in mind that he *is* managing to compile it.
It's *running* it that is causing problems. Missing an assembly
reference would mean a failure to compile, not to run.
 
A

Andrew Warren

I ended up logging a call with Microsoft to resolve this
and it turns out that the problem lies with attaching
custom icons to the forms... as soon as the icons are
removed it compiles fine with csc!

There is a workaround - the .resx files for the forms can
be compiled to .resource files using resgen.exe and then
compiled with csc. The downside of this is that it does
not meet my requirement of being able to compile the app
using only the .Net Framework - resgen is part of Visual
Studio.

Still, at least I know what the problem is now!

Thanks for your responses and suggestions. I'll let you
know when I hit on the final solution.
 
A

Andrew Warren

A good thought, but the csc.rsp default response file is
actually part of the .Net Framework rather than the SDK -
it's in the same directory as csc.exe.

See my earlier response today for the answer!
 
M

mikeb

Andrew said:
I ended up logging a call with Microsoft to resolve this
and it turns out that the problem lies with attaching
custom icons to the forms... as soon as the icons are
removed it compiles fine with csc!

There is a workaround - the .resx files for the forms can
be compiled to .resource files using resgen.exe and then
compiled with csc. The downside of this is that it does
not meet my requirement of being able to compile the app
using only the .Net Framework - resgen is part of Visual
Studio.

Still, at least I know what the problem is now!

Thanks for your responses and suggestions. I'll let you
know when I hit on the final solution.

Just to make things clear - resgen.exe is included in the .NET Framework
SDK, which is available for free as a download from MS.

While it's not included in the .NET Framework Runtime, it is not
necessary to have Visual Studio to use resgen.exe.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top