Различают COM dll из сборки .NET в пакетных файлах - PullRequest
0 голосов
/ 06 ноября 2018

У меня в папке куча 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-библиотек это работает нормально, но для сборок .NET это не удается. В качестве обходного пути я мог бы заменить regsvr32 на regasm и запустить его снова. Это при втором запуске зарегистрирует сборки .NET. Мне было интересно, если бы был способ, которым пакетный файл мог бы отличить два случая здесь. Я понимаю, что COM-библиотеки должны иметь заголовок PE или COFF, в то время как сборки .NET не будут (?). Глядя на MSDN, я вижу ImageHlp API, который может иметь что-то для этого. Есть ли более простой способ добиться того же?

1 Ответ

0 голосов
/ 06 ноября 2018

Я вполне уверен, что вы ничего не можете сделать с помощью необработанного пакетного сценария, чтобы обнаружить это. (Или, если вы сможете найти способ, он будет невероятно уродливым.) Но вы можете сделать это несколькими другими способами.

Вот один из вариантов: используйте 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

В качестве альтернативы, вы можете написать свою собственную программу, которая ищет наличие точки входа DllRegisterServer в DLL, которой нет в .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
...