The subtitle is taken from that great Neil Sedaka song,
They say that breaking up is hard to do
Now I know, I know that it's true!
This article discusses the two tools that are used to create executable programs from different files. Just to make it interesting, we're even going to use different languages. By the time we're finished, you may be singing along with Neil.
If you're just getting started with VB.NET, you probably create "single-file" assemblies using the simple two step process in Visual Studio:
- Create the source
- Compile using the Build menu
(or perhaps just by clicking the start icon in the Visual Studio toolbar)
But when projects get more complicated, and especially when they're created by teams of programmers instead of just one lone coder, they consist of many individual code modules. Sometimes, these modules are even in different .NET languages. One of the big advantages of .NET is that all Common Language Specification (CLS) languages are equal after they're compiled into IL code. You can link VB.NET, C#, or maybe even something written in Cobol, Fortran or Perl into a single assembly.
To move to this next stage of development, you need to know about the .NET Framework tools. In this case, AL.EXE, the Assembly Linker tool.
We'll look at AL.EXE by itself in a DOS box (that is, Command Prompt window, of course) but in a production environment, you would probably see it as part of a longer script that to ensure that everything works right and all the right modules are part of the resulting build.
Another point to keep in mind is that you may not always want to combine individual modules into one big file. Keeping them separate can have advantages too.
In contrast to the earlier Framework tools that have been featured in this series, AL.EXE just isn't that easy to use. In fact, some gurus recommend just forgetting about it and using the VBC command line compiler instead. It does most of the same things and is a bit easier to get your head around. We're going to have to use it anyway just to create the inputs to AL.
To demonstrate the point, we first need two program assemblies. I wrote a simple C# program that will return a string value from one method. (Don't worry. I only use bad language like "C#" when I have a really good reason.) The C# program is referenced and instantiated in a VB program and the string is retrieved using a method in the C# program.
**Click Here to See VB Source - Click back button to return**
**Click Here to See C# Source - Click back button to return**
This works just great ... as long as the DLL for the C# program is actually in the same directory with the VB program. (The DLL is actually copied by Visual Studio when a reference to the C# program is added to the VB.NET program.)
But let's assume that we need to create a combined executable for both programs. Step 1 is to create a .NET module. You may have thought you knew what a module was before this. You may have been wrong. To quote the Microsoft AL.EXE documentation, "A module is a Microsoft intermediate language (MSIL) file that does not have an assembly manifest."
So how do you create one of those? You use the command line compiler with the /target:module flag.
First, let's create the C# module. Use the C Sharp Compiler (csc) command to do this. (Again, keep in mind that you also have to set the path with the Microsoft supplied batch file, sdkvars.bat. See the first article for more.)
csc /t:module csgetstring.cs
This creates a file named CSGetString.netmodule. It's an IL file (Intermediate Language) so you can examine it with our old friend ILDASM. You'll see that there is no .assembly statement in the IL code for the manifest.
The command to create the module for the Visual Basic program is similar, but since you need to reference the instantiated C# program, you have to add a reference for it in the command.
vbc /t:module writestring.vb /r:csgetstring.dll
(It's easiest to simply copy the files to the same directory while you're doing these commands.)

