Command line compile with csc

  • Thread starter Thread starter Andrew Warren
  • Start date Start date
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.
 
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?
 
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.
 
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.
 
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.
 
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?
 
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.
 
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.
 
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.
 
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 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!
 
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.
 
Back
Top