2011-03-10 8 views
7

특정 공급 업체의 일부 타사 어셈블리를 참조하고 사용하는 응용 프로그램을 개발 중입니다. 개발 상자에서 내 소스 트리의 참조 폴더에이 3 가지 어셈블리가 있고이를 참조하고 응용 프로그램을 빌드 할 수 있지만 응용 프로그램 빌드는 실행되지만 전체 서버 응용 프로그램이 설치되어 있지 않기 때문에 실행되지 않습니다. 나는이 사용자 지정 응용 프로그램을 복사하여 내가 참조하고 모든 어셈블리가 같은 폴더 무언가에 실행할 서버에다른 폴더에서 어셈블리 참조 해결

:

D:\ProgramFiles\VendorName\ProductName\Support\API\Bin64 

및 그 폴더에 내 작은 실행 파일을 복사하고, 그것을 실행하는 경우 완벽하게 작동하지만 원하는대로 더 적절한 폴더에 내 .exe를 넣으면 다음과 같습니다.

D:\ProgramFiles\MyCompanyName\MyProduct\bin\... 

이러한 어셈블리를 해결할 수 없기 때문에 작동하지 않습니다.

app.config에서 프로빙을 사용하여 내 exe가 참조를 찾는 폴더를 지정하지만 imy의 경우 어셈블리가 완전히 다른 위치에있는 하위 폴더에없는 것을 지정할 수 있음을 알고 있습니다.

내 응용 프로그램 폴더에있는 모든 공급 업체 어셈블리를 복사하고 싶지 않으며 참조하는 3 개의 부품 만 넣을 수 없습니다. 다른 어셈블리를로드하고 있기 때문에 참조하는 중입니다. , 작동하지 않습니다.

응용 프로그램 도메인을 만들지 않고 리플렉션을 통해 어셈블리를로드하지 않고 특별한 작업을 수행하지 않고 CLR이 응용 프로그램 시작 또는 실행에 필요한 참조를 확인하기 만하면됩니다.

감사합니다.

편집 : 여기에 최종 작업 코드

static System.Reflection.Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
{ 
    Logger logger = new Logger(); 

    try 
    { 
     string RMSAssemblyFolder = ConfigurationManager.AppSettings["RMSAssemblyFolder"]; 

     Assembly MyAssembly = null; 
     string strTempAssmbPath = string.Empty; 

     Assembly objExecutingAssemblies = Assembly.GetExecutingAssembly(); 
     AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies(); 

     AssemblyName myAssemblyName = Array.Find<AssemblyName>(arrReferencedAssmbNames, a => a.Name == args.Name); 

     if (myAssemblyName != null) 
     { 
      MyAssembly = Assembly.LoadFrom(myAssemblyName.CodeBase); 
     } 
     else 
     { 
      strTempAssmbPath = Path.Combine(RMSAssemblyFolder, args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll"); 

      if (!string.IsNullOrEmpty(strTempAssmbPath)) 
      { 
       if (File.Exists(strTempAssmbPath)) 
       { 
        logger.Information("Assembly to load: {0} - File was found in: {1}", args.Name, strTempAssmbPath); 

        // Loads the assembly from the specified path.     
        MyAssembly = Assembly.LoadFrom(strTempAssmbPath); 
       } 
      } 
     } 

     // Returns the loaded assembly. 
     return MyAssembly; 
    } 
    catch (Exception exc) 
    { 
     logger.Error(exc); 
     return null; 
    } 
} 
+0

의 중복 가능성 HTTP : /을 /stackoverflow.com/questions/1373100/how-to-add-folder-to-assembly-search-path-at-runtime-in-net – nawfal

답변

12

DLL을가 조립 해상도 후크 AppDomain.AssemblyResolve를 사용하고이 폴더에서 요청 된 어셈블리를로드하려고 후 설치 논제 경우 먼저 폴더를 찾아야한다.

이 같은 것을 볼 것이다 (테스트하지를, 당신은 버전 및 유형 이름과 함께 강력한 이름을 포함 할 수있다, args.Name 정확히 포함 된 것을 확인해야합니다) :

var otherCompanyDlls = new DirectoryInfo(companyFolder).GetFiles("*.dll"); 

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => 
{ 
    var dll = otherCompanyDlls.FirstOrDefault(fi => fi.Name == args.Name); 
    if (dll == null) 
    { 
     return null; 
    } 

    return Assembly.Load(dll.FullName); 
}; 
+0

고마워, 사용하여 수정했습니다. 귀하의 아이디어와 내 코드에 edi ted 질문 및 이제 잘 작동합니다. –

+0

확실하게 내 솔루션을 최적화 할 수 있습니다,이 메서드는 사용자 지정 폴더에서 어셈블리를 찾을 수없는 경우 null을 반환 할 경우 확실하지 및 CLR 여전히 찾습니다. GAC, 예를 들어이 메소드가 System.XML.Serializer와 같은 어셈블리에도 호출 되었기 때문에 ...지금 netTcp 바운드 WCF 서비스를 호스팅하는 콘솔 응용 프로그램에서이 테스트를하고 있습니다. 이제는 작동하고 모든 폴더에서 응용 프로그램을 실행할 수 있습니다. 결국 WCF를 호스팅 할 WindowsService를 만듭니다. 감사합니다.)) –

+0

Coo, thanks. 며칠 안에 이것을 시도 할 것입니다. – Tarion

0

사용 SN.exe : SN-T VendorAssembly.dll, 이것은 공개 키 토큰이있는 16 진수를 반환합니다, 다음, 응용 프로그램에서 어셈블리를 참조 .config. 버전을 얻으려면 공급 업체 어셈블리를 마우스 오른쪽 버튼으로 클릭하고 코드베이스 버전 값에 대해 사용하는 href = 경로를 사용하십시오.

<configuration> 
     <runtime> 
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
      <dependentAssembly> 
       <assemblyIdentity name="VendorAssembly" culture="neutral" publicKeyToken="307041694a995978"/> 
       <codeBase version="1.1.1.1" href="FILE://D:/ProgramFiles/VendorName/ProductName/Support/API/Bin64/VendorAssembly.dll"/> 
      </dependentAssembly> 
      </assemblyBinding> 
     </runtime> 
    </configuration> 
+0

안녕하세요, 그것이 효과가 좋겠어, 난 여전히 FileNotFound 예외가 ... 어셈블리 나는 참조가 필요합니다 강하게 명명 된 것 같아, SN -t 작동하지 않지만 거기에서 그 값을 복사 할 수 있도록 예외 메시지 PublicKeyToken 본, 여전히 해결할 수 없습니다 ... :( –