2011-09-18 4 views
9

우리는 몇 가지 COM 라이브러리 (예 : AutoIT)를 참조하는 C# 응용 프로그램을 개발 중입니다.빌드 서버에 COM 참조 된 DLL 등록

소스 제어하에 참조 된 모든 구성 요소를 타사 "Libs"폴더에 포함합니다.

문제는 COM dll에 .csproj 파일에 HintPath 속성이 없기 때문에 regsvr32 (또는 일종의 스크립트 사용)를 사용하여 수동으로 등록해야한다고 가정합니다.

현재 모든 빌드 전에 실행되는 MSBuild 스크립트를 만드는 중입니다. 그러나 수동으로 regsvr32.exe를 호출해야하는지 또는 미리 정의 된 MSBuild 작업을 사용해야하는지 알 수 없습니까?

현재이 내가 테스트로 attmpted 한 것입니다 :

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build"> 
    <ItemGroup> 
    <MyAssemblies Include="D:\*.dll" /> 
    </ItemGroup> 
    <Target Name="Build"> 
    <RegisterAssembly 
     Assemblies="@(MyAssemblies)" > 
    </RegisterAssembly> 
    </Target> 
</Project> 

이 내가 지정한 폴더에 저장 한 DLL을 유효 DLL을하지 않은 것으로 오류를 생성합니다.

이 문제를 해결하는 좋은 방법은 무엇입니까?

편집 : COM DLL을가 .csproj 파일에이 비슷한이 참조

프로젝트 :

<COMReference Include="AutoItX3Lib"> 
     <Guid>{F8937E53-D444-4E71-9275-35B64210CC3B}</Guid> 
     <VersionMajor>1</VersionMajor> 
     <VersionMinor>0</VersionMinor> 
     <Lcid>0</Lcid> 
     <WrapperTool>tlbimp</WrapperTool> 
     <Isolated>False</Isolated> 
    </COMReference> 

이 다른 관리되는 어셈블리와 같은 힌트 경로를 포함하지 않습니다 빌드 서버에 이렇게 , 참조 된 COM DLL을 찾을 수 없습니다.

REGSVR32를 사용하여 빌드 서버에 COM dll을 등록하면 빌드가 성공합니다.

답변

10

빌드 서버에는 COM 서버를 등록하지 않는다. 이는 실제로 에 컴파일 된 코드 인을 실행하려는 경우에만 필요합니다. 필요한 것은 COM 서버용 형식 라이브러리이므로 interop 어셈블리를 얻을 수 있습니다. Tlbimp.exe로 생성합니다.

Tlbimp를 빌드 서버에서 실행할지 아니면 dev 컴퓨터에서 실행 시킬지는 이러한 COM 서버를 배포하는 방법에 따라 크게 달라집니다. COM 실행 파일과 .tlb 파일의 복사본을 interop 라이브러리와 매우 가깝게 유지하는 것이 좋습니다. 다른 말로, 그들을 체크인하십시오.이제 설치 관리자는 COM 서버의 알려진 버전을 검색 할 수 있습니다.

+0

형식 라이브러리와 interop 어셈블리가 모두 내 소스 제어 (Git)에 체크되어 있습니다. interop을 참조하는 것만으로는 충분하지 않습니다. Tlbimp의 결과는 무엇입니까? 내가 대신 빌드 프로세스의 일부로 오히려 정면보다 빌드 env를 업그레이 드하기 때문에, 나는 모든 스크립트를 복사하고 더 많은 서버로 확장 할 수 있으며, 모든 로직을 전제 조건 단계없이 저장할 수 있습니다. –

+0

Tlbimp의 출력은 다음과 같습니다. interop 어셈블리 나는 "충분하지 않다"로 무엇이든 할 수 없다. 당신이 더 잘하는 빌드 오류를 설명해야 할 것이다. –

+0

원래 질문을 업데이트했습니다. Interop dll은 "dependencies"폴더에 있지만 .csproj와이 파일을 연결하지 않으므로 빌드가이 파일을 선택하지 않습니다. 내 dev envinronment에,이 원래 설치되어있는 소프트웨어 패키지 (AutoIt 예를 들어),하지만이 서버에 설치되어 있지 않습니다 및 그래서 빌드 전에 몇 가지 추가 단계를 수행하지 않고 실패합니다. –

0

1) COM 라이브러리를 참조로 csproj를 참조하십시오. 아직 수행하지 않은 경우 참조하십시오.

2) csproj 파일에 추가하려고 :

<Project ... > 
    ... 
    <Target Name="BeforeBuild"> 
     <Exec Command="regsvr32.exe yourComponent.dll" /> 
    </Target> 
</Project> 

PS를 : 당신이 csproj하지만 서버에서 빌드에 사용되는 스크립트를 수정해서는 안 빌드 서버 소프트웨어의 일종을 사용하는 경우.

+0

답변 해 주셔서 감사합니다. .csproj 파일을 변경하지 않고 오히려이 작업을 수행 할 "준비"스크립트가 하나있는 것을 선호합니다. 모든 어셈블리에 regsvr32.exe를 실행하고 싶습니다 (아마 모든 COM 참조를 단일 폴더 아래에두고 실행시킬 수 있습니다). 어떻게 MSBuild에서 하나씩 모두 반복 할 수 있습니까? –

+0

나는 해결책을 찾았다 고 믿는다 - % (MyAssemblies.Identity) 표기법을 사용하면 * .dll을 사용할 때 확장 된 파일마다 명령이 한 번씩 실행됩니다. 이것이 정확하고 일반적인 사용법입니까? –

+0

COM dll을 사용하려고 할 때 % (MyAssemblies.Identity)를 사용하는 솔루션을 정말로 이해하지 못합니다. 그러나 목록 파일을 반복 할 때 명령 행에서 'for'를 사용할 수 있습니다 : 사용 방법을 알아 내려면 'for/for'를 입력하십시오. > yourTargetPath \ help_for_for.txt '그리고 생성 된 txt 파일을 읽습니다. –

0

MSBuild에서 작업이 regsvr32를 호출하는 경우 확실하지 않지만 REgisterAssembly가 regasm.exe를 호출합니다. 즉, COM interop 용 .NET 구성 요소를 등록합니다.

나는 regsvr32를 수동으로 호출하는 것이 원하는 결과를 얻는 가장 빠른 방법 일 것이라고 확신한다.

COM DLL이 이전 빌드에서 이미 등록되어 있고 빌드 스크립트를 다시 실행하면 어떻게됩니까? (나는 정말로 regsvr32가 어떻게 반응 할 것인지, 단지 여기에 대한 생각을 알지 못한다.)

+0

낭비 된 X 밀리 초를 제외하고 regsvr32를 다시 호출해도 무해합니다 (AFAIK). –

11

비슷한 질문에 내 원래의 대답은 참조하십시오 : 빌드 서버에 대한 TFS Build server and COM references - does this work?

더 나은 옵션은 프로젝트 파일 대신 COMReferenceCOMFileReference 항목을 사용할 수 있습니다. 예는 다음과 같습니다.

<ItemGroup> 
    <COMFileReference Include="MyComLibrary.dll"> 
    <EmbedInteropTypes>True</EmbedInteropTypes> 
    </COMFileReference> 
</ItemGroup> 

COM dll이 작동하려면 컴퓨터에 등록 할 필요가 없습니다.

각 COMFileReference 항목에는 WrapperTool 특성이있을 수도 있지만 기본값은 정상적으로 작동하는 것 같습니다. EmbedInteropTypes 특성은 COMFileReference에 적용 가능한 것으로 문서화되어 있지 않지만 의도 한대로 작동하는 것 같습니다.

좀 더 자세한 내용은 http://msdn.microsoft.com/en-us/library/bb629388.aspx을 참조하십시오. 이 MSBuild 항목은 .NET 3.5부터 사용할 수 있습니다.

+0

BTW, HintPath는 COMReference 작업에 대해 문서화되어 있지는 않지만 작업하는 것처럼 보입니다. – jpierson

+0

COMReference에서 HintPath가 작동하지 않지만 COMFileReference의 Include 특성에 경로를 사용할 수 있습니다. – kristianp