在批处理文件中区分 COM dll 和 .NET 程序集
Distinguish COM dll from .NET assembly in batch files
我的一个文件夹里有一堆dll,要么是COM dlls
,要么是.NET assemblies
。现在,我正在使用下面这样的东西来注册二进制文件:
@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
这里的问题是,虽然对于 COM dll,它工作正常,但对于 .NET 程序集它失败了。作为解决方法,我可以将 regsvr32
替换为 regasm
并再次 运行 。这将在第二个 运行 中注册 .NET 程序集。我想知道,批处理文件是否有办法区分这两种情况。我知道,COM dll 必须有 PE
或 COFF
header 而 .NET 程序集不会(?)。查看 MSDN,我看到 ImageHlp API 可能对此有所帮助。有没有更简单的方法来实现同样的目标?
我相当确定您无法使用原始批处理脚本来检测此问题。 (或者,如果你能想出办法,那将是非常丑陋的。)但你可以通过许多其他方式来做到这一点。
这是一个选项:使用 corflags.exe
,它随 Windows SDK 一起提供。要在您的系统上查找副本,请尝试 attrib /s C:\corflags.exe
。要使用它,请尝试这样的操作:
corflags.exe your.dll
if %ERRORLEVEL% equ 0 goto :IS_DOT_NET
goto :IS_NOT_DOT_NET
或者,您可以编写自己的程序来查找 DLL 中是否存在 DllRegisterServer
入口点,而 .NET DLL 没有。只需使用任何语言的几行代码即可完成此检查。这是 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;
}
当然,这是 regsvr32.exe
已经做的事情的一半,所以你可以做类似的事情:
regsvr32.exe /s your.dll
if %errorlevel% neq 0 regasm.exe your.dll
我的一个文件夹里有一堆dll,要么是COM dlls
,要么是.NET assemblies
。现在,我正在使用下面这样的东西来注册二进制文件:
@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
这里的问题是,虽然对于 COM dll,它工作正常,但对于 .NET 程序集它失败了。作为解决方法,我可以将 regsvr32
替换为 regasm
并再次 运行 。这将在第二个 运行 中注册 .NET 程序集。我想知道,批处理文件是否有办法区分这两种情况。我知道,COM dll 必须有 PE
或 COFF
header 而 .NET 程序集不会(?)。查看 MSDN,我看到 ImageHlp API 可能对此有所帮助。有没有更简单的方法来实现同样的目标?
我相当确定您无法使用原始批处理脚本来检测此问题。 (或者,如果你能想出办法,那将是非常丑陋的。)但你可以通过许多其他方式来做到这一点。
这是一个选项:使用 corflags.exe
,它随 Windows SDK 一起提供。要在您的系统上查找副本,请尝试 attrib /s C:\corflags.exe
。要使用它,请尝试这样的操作:
corflags.exe your.dll
if %ERRORLEVEL% equ 0 goto :IS_DOT_NET
goto :IS_NOT_DOT_NET
或者,您可以编写自己的程序来查找 DLL 中是否存在 DllRegisterServer
入口点,而 .NET DLL 没有。只需使用任何语言的几行代码即可完成此检查。这是 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;
}
当然,这是 regsvr32.exe
已经做的事情的一半,所以你可以做类似的事情:
regsvr32.exe /s your.dll
if %errorlevel% neq 0 regasm.exe your.dll