I have a bunch of dlls in a folder, which are either COM dlls
, or .NET assemblies
. Now, I'm using something like this below to register the binaries:
@echo off
set argCount=0
for %%x in (%*) do (
set /A argCount+=1
)
if not %argCount% == 1 (
echo Usage:
echo %0 ^<filename^>
echo Example:
echo %0 path\to\the\file.ext
goto end
)
for /F "tokens=*" %%A in (%1) do (
echo Registering %%A ...
regsvr32 "%%A"
)
:end
The issue here is that although for COM dlls, it works fine, but for .NET assemblies it fails. As a workaround, I could replace the regsvr32
with regasm
and run it again. This would, in the second run register the .NET assemblies. I was wondering, if there was a way the batch file might be able to distinguish between the two cases here. I understand, COM dlls must have the PE
or COFF
header while .NET assemblies would not (?). Looking at MSDN, I see ImageHlp API which might have something for this. Is there an easier way to achieve the same?
I'm fairly certain there is nothing you can do with raw batch script to detect this. (Or if you can figure out a way, it's going to be incredibly ugly.) But you can do this a number of other ways.
Here's one option: Use corflags.exe
, which ships with the Windows SDK. To find a copy on your system, try something like attrib /s C:\corflags.exe
. To use it, try something like this:
corflags.exe your.dll
if %ERRORLEVEL% equ 0 goto :IS_DOT_NET
goto :IS_NOT_DOT_NET
Alternatively, you could write your own program that looks for the existence of a DllRegisterServer
entry point in the DLL, which .NET DLLs do not have. It would only take a handful of lines of code in any language to do this check. Here's the C++:
// returns:
// 1 if the dll can be used with regsvr32
// 0 if the dll cannot be used with regsvr32
// -1 if the dll cannot be loaded
int main(int argc, LPCSTR* argv)
{
if (argc != 2)
return -1;
HMODULE hModule = LoadLibraryA(argv[1]);
if (!hModule)
return -1;
FARPROC dllRegisterServer = GetProcAddress(hModule, "DllRegisterServer");
FreeLibrary(hModule);
if (dllRegisterServer)
return 1;
return 0;
}
Of course, this is half of what regsvr32.exe
already does, so you could just do something like:
regsvr32.exe /s your.dll
if %errorlevel% neq 0 regasm.exe your.dll