Posted By: JScript | Aug 5th, 2005 @ 12:22 AM
page 1 of 1
Comments: 6 | Views: 1914
JScript
JScript
Way to go.

Considering that the /target option "Specifies the format of the output file"...

/target:exe
/target:library
/target:winexe


What besides ".exe" or ".dll" would be used that causes /out to require a file extension?

Slightly oblique answer: CreateProcess and LoadLibrary do not care about file extensions. They examine the file header to work out what to do with the contents. Therefore you can have executable files with any extension you like. An example of a liar is more.com - it's actually a Win32 PE format executable.

Extensions are used by ShellExecute and the command interpreter cmd.exe (and command.com, the DOS command interpreter) to determine what to do with a file. The extension information in the registry is used by ShellExecute to set up the command line it passes to CreateProcess. For .exe, the default registry points to 'exefile'. Under that, shell\open\command is "%1" %*. The %s indicate parameters: %1 is replaced by the name of the file the operation was performed on, while %* is replaced by the remaining command line (this may happen if a file is dropped on a .EXE file).

There are a number of extensions set up like this: .BAT, .CMD, .COM, .EXE (obviously), .PIF. That last is normally used to set up the DOS emulation environment for a DOS application. But by the time CreateProcess gets hold of it, the extension is no longer considered - you could rename a program built with /t:exe or /t:winexe to a .pif extension and it would still run.

There's an additional value for /target: module. By convention the extension for a module is .netmodule. A module can contain code, data and resources, but cannot be loaded directly. It's loaded as part of an assembly, whether that assembly is an executable or a library. Physically it's still a PE-format executable but the Windows XP loader recognises that it's not actually loadable. Modules are useful in .NET 1.0 and 1.1 for building a single assembly in more than one language, but you have to ship a multi-file assembly; IIRC .NET 2.0 will have a way of linking modules together to produce a single-file assembly.

W3bbo
W3bbo
The Master of Baiters
Mike Dimmick wrote:
There's an additional value for /target: module. By convention the extension for a module is .netmodule. A module can contain code, data and resources, but cannot be loaded directly. It's loaded as part of an assembly, whether that assembly is an executable or a library. Physically it's still a PE-format executable but the Windows XP loader recognises that it's not actually loadable. Modules are useful in .NET 1.0 and 1.1 for building a single assembly in more than one language, but you have to ship a multi-file assembly; IIRC .NET 2.0 will have a way of linking modules together to produce a single-file assembly.


...but I was under the impression .NET Application Assemblies (.exes) were portable, the only thing that mattered being the JIT-C program on the client.

But if the .exe is in PE format, how do you run these under MONO on UNIX or Mac?

...unless MONO recognises the header or something?
W3bbo wrote:

...unless MONO recognises the header or something?


bingo!

W3bbo wrote:
...but I was under the impression .NET Application Assemblies (.exes) were portable, the only thing that mattered being the JIT-C program on the client.

They are. It's just that, for backwards compatibility with Windows 9x, NT 4.0 and 2000, Microsoft chose to reuse the existing executable format, making it very easy for existing programs to naively load .NET programs. The way the loading works is a kludge: the executable's import table refers to _CorExeMain in mscoree.dll (_CorDllMain for /t:library), then the start address in the executable header is set to point to that address in the import address table. At launch time, the loader loads mscoree.dll, fills in the address of _CorExeMain in the IAT, then jumps to the start address - which is now just a jump instruction to the start of _CorExeMain.

There are some clever tricks in .NET 2.0 to ensure that, if appropriate, the executable ends up loaded in a 64-bit process.

For Compact Framework, an executable is still marked as being for the x86 processor family and using the Windows GUI (or console) subsystem. I'm not quite sure how that works. Presumably the loader's been patched to anticipate it and recognise the executable properly.

W3bbo wrote:
But if the .exe is in PE format, how do you run these under MONO on UNIX or Mac?

By running the mono executable, passing the .exe as the first command line argument. Presumably the OS loaders and shells have not been modified to recognise PE format executables natively.

W3bbo wrote:
...unless MONO recognises the header or something?

You could, of course, register the .exe extension with whatever shell you're using, to make it launch mono passing the .exe name as a command line argument.

footballism
footballism
I've been avalonized!
Mike Dimmick wrote:

   There's an additional value for /target: module. By convention the extension for a module is .netmodule. A module can contain code, data and resources, but cannot be loaded directly. It's loaded as part of an assembly, whether that assembly is an executable or a library. Physically it's still a PE-format executable but the Windows XP loader recognises that it's not actually loadable.

   To add more explanation to your post:If you compile your source code files with switch /target:module turn on, you actually told the compiler not to produce manifest information for this file, and assembly loader can only load the file which has manifest information associated with, that's why you have to use AL to link your manifestless modules together into an assembly, so every single module in this assembly can be loadable,because what manifest actually does is to describe what kinda modules you assembly has, and where the file associated with this module can be found etc...
Mike Dimmick wrote:

Modules are useful in .NET 1.0 and 1.1 for building a single assembly in more than one language, but you have to ship a multi-file assembly; IIRC .NET 2.0 will have a way of linking modules together to produce a single-file assembly.

   Multi-file assembly can be quite useful in the internet download scenario where bandwidth is limited, if you have a large assembly need to be downloaded, you can seperate this assmebly into multiple files, multiple modules.you can put all those frequently accessed types into one module called FAT.netmodule, and put the other infrequently accessed types into another module called IAT.netmodule, then every time you are prompted to download this assembly, you only have to download this manifestful module FAT.netmodule, if your application gonna access the extra types defined in the IAF.netmodule, you can download the other modules accordingly, this can heavily reduce the assembly file size, and markedly reduce the download time:P