2009-12-28 32 views
8

Chúng tôi có nhiều sản phẩm và có một số DLL phổ biến trên ứng dụng của mỗi sản phẩm. Ngay bây giờ chúng ta sao chép từng DLL thông thường vào thư mục bin của mỗi sản phẩm và coi chúng là một assembly riêng. Điều này không cần thiết tăng kích thước msi của mỗi sản phẩm và khi một vấn đề xảy ra trong một DLL, chúng tôi phải xây dựng msi của từng sản phẩm bao gồm DLL và triển khai nó.Cách tải DLL từ kho trung tâm

Có cách nào để hướng dẫn ứng dụng sản phẩm sử dụng một thư mục riêng chung được sử dụng để tải DLL [sử dụng lược đồ biểu hiện ..] không? [Lưu ý: Tạo thư mục riêng để PATH env sẽ không cung cấp một giải pháp như nếu có một DLL với cùng một tên tồn tại trong thư mục hệ thống, mà sẽ có được những đặc quyền trên thư mục riêng của chúng tôi]

-Kartlee

Trả lời

1

Nếu bạn đang nói về .NET, bạn có thể:

  • Tải DLL của bạn trực tiếp từ một cơ sở dữ liệu bằng cách sử dụng Assembly.Load(byte[])
  • bằng cách sử dụng Assembly.TypeResolve kiện
  • bằng sử dụng TypeProvider lớp
  • Bằng việc xác định một thư mục thăm dò trong tập tin cấu hình của bạn

Giống như:

<configuration> 
    <runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
      <probing privatePath="bin"/> 
     </assemblyBinding> 
    </runtime> 
</configuration> 
+0

Cảm ơn bạn đã trả lời. Thật không may tôi đang tìm kiếm ứng dụng C/C++ mà không sử dụng bất kỳ phương pháp liên kết động thời gian chạy nào (ví dụ như Loadlibrary (..)). Có anyway để hướng dẫn thông qua biểu hiện như thế nào 'thăm dò' khái niệm hoạt động? – Kartlee

+0

@Kartlee, xin lỗi tôi không biết về C/C++; nhưng tôi đã chỉnh sửa câu hỏi của bạn để phản ánh các từ khóa đó –

0

Tôi không chắc chắn nếu điều này là những gì bạn đang tìm kiếm nhưng nơi tôi làm việc bây giờ chúng tôi sử dụng một đường dẫn UNC chung cho tất cả các DLL của chúng tôi.

Chúng tôi có một cái gì đó giống như ...

\\ server01 \ productionLibrary phục vụ sản xuất đọc DLL, mỗi trong thư mục riêng của nó.

\\ server01 \ developmentLibrary phản ánh thư viện sản xuất và đây là những gì các nhà phát triển sử dụng khi phát triển.

Khi chúng tôi hợp nhất mã sau khi thử nghiệm đã được hoàn thành, chúng tôi triển khai vào thư viện sản xuất. Tất cả các dự án đều tham khảo thư viện sản xuất khi chúng được xây dựng thành các tệp MSI để triển khai. Hệ thống tự động của chúng tôi xây dựng các dự án thành MSIs và nó xác minh rằng tất cả các DLL đang trỏ đến thư viện sản xuất, vì vậy không có cơ hội nào nó sẽ sử dụng một bản sao phát triển một cách vô tình.

Hy vọng điều này sẽ hữu ích.

0

Tôi không chắc chắn tôi hiểu câu hỏi một cách chính xác, nhưng nếu bạn đang ở trong Net, có một Global Assembly Cache (GAC): http://en.wikipedia.org/wiki/Global_Assembly_Cache

này lưu trữ các hội đồng và cho phép tái sử dụng chúng bằng cách ứng dụng (giống như với .net framework). Bạn chỉ cần đăng ký assembly với GAC trong tiến trình cài đặt, ví dụ cung cấp một "khung cài đặt của bạn" với tất cả các assembly chung, và điều này có thể được triển khai chỉ một lần.

+0

Cảm ơn bạn đã trả lời. Xin vui lòng xem bình luận của tôi để 'Rubens Farias'. – Kartlee

7

Bạn không chỉ định môi trường của mình là .NET hay Win32 thẳng.

Tôi giả định Win32 của nó bởi vì nếu .NET của nó, các công nghệ để thực hiện điều này gần như tương đương với những thứ như Global Assembly Cache.

Về Win32 có thể tải các file DLL từ một địa điểm được chia sẻ trong một trong hai cách:

  • Sử dụng LoadLibrary với đường dẫn đầy đủ rõ ràng. Điều này có nghĩa là bạn không thể sử dụng liên kết tĩnh - tất cả các chức năng dll được sử dụng trong tất cả các sản phẩm sẽ phải được truy cập thông qua GetProcAddress. Bạn không thể nhập các lớp C++ từ dll được tải thông qua LoadLibrary - chúng phải được liên kết tĩnh để làm việc để cách tiếp cận này có thể hoặc không thể thực hiện được. Nó không khó khăn để viết các tập tin tiêu đề shim mà giả mạo như giao diện của dll và làm một chỉ trong thời gian tải dll và GetProcAddress khi cần thiết cho mỗi cuộc gọi.

  • Tùy chọn khác là chuyển dll thành những gì được gọi là "cạnh nhau hội đồng" và cài đặt chúng vào cửa hàng WinSxS. Đừng sợ tên lớn. "bên cạnh lắp ráp" có nghĩa là "Một tập tin dll cộng với tập tin manifest với thông tin phiên bản". Mỗi ứng dụng khác nhau sau đó sẽ đặt 'tên mạnh' - bao gồm thông tin phiên bản - vào tệp kê khai ứng dụng cho mỗi dll nó sử dụng và trình tải xuống Win32 Dll sẽ sử dụng tùy chọn này để chọn đúng dll chung từ cửa hàng WinSxS . Quá trình cơ bản được mô tả trong bài viết MSDN Guidelines for Creating Side-by-side Assemblies


Mở phiên bản Windows 6.1 và lên (Windows Server 2008 và Windows 7 trớ trêu thay tên) file cấu hình ứng dụng làm gì bây giờ hỗ trợ các yếu tố thăm dò trong Application Configuration Files

Điều này có nghĩa là bạn sẽ có thể cung cấp một đường dẫn (liên quan đến ứng dụng của bạn) đến một thư mục chứa các hội đồng dll mà bạn muốn tải.


Ok, Ive thực hiện một số thử nghiệm trên Windows 7, và các công trình này:

Giả sử bạn có một app1.exe ứng dụng được cài đặt trong \ Program Files \ App1, mà phụ thuộc vào một số dll chung "thedll. dll"

Trong thư mục ứng dụng (\ Program Files \ App1) tạo ra một tập tin App1.exe.config và cung cấp cho nó các nội dung sau: -

<configuration> 
    <windows> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <probing privatePath="..\AcmeCommon"/> 
    </assemblyBinding> 
    </windows> 
</configuration> 

Bây giờ, tạo một thư mục có tên \ Program F ile \ AcmeCommon, và trong đó một thư mục acme.thedll, và sao chép thedll.dll vào \ Program Files \ AcmeCommon \ acme.thedll

Cũng tạo một tệp trong AcmeCommon \ acme.thedll gọi là acme.thedll.manifest - this sẽ là biểu hiện lắp ráp mô tả việc lắp ráp gọi là 'acme.thedll'

Nội dung acme.thedll.manifest sẽ là: -

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <assemblyIdentity name="acme.thedll" version="1.2.3.4" processorArchitecture="x86" type="win32"/> 
    <file name="thedll.dll"/> 
</assembly> 

Bây giờ chúng ta có dll chung, ở một vị trí thông thường, như một sxs bản địa lắp ráp. Chúng tôi có các ứng dụng, với một tập tin cấu hình mà sẽ, trên Windows 7 và 2008 máy chủ (và lên) nói với nó để tìm kiếm các hội đồng ở vị trí chung. Nhưng ứng dụng vẫn đang cố gắng liên kết với dll dưới dạng dll, thay vì thông qua một hội đồng.

Để tải ứng dụng, chúng tôi cần thêm tệp kê khai vào ứng dụng. Nếu bạn đang sử dụng studio trực quan, các ứng dụng của bạn có thể đã được định cấu hình để tạo và nhúng tệp kê khai thông qua cài đặt dự án công cụ liên kết và tệp kê khai.Trong trường hợp này, cách dễ nhất để nói với các ứng dụng về lắp ráp là để xây dựng lại nó sau khi thêm đoạn mã sau vào ít nhất một tập tin header hoặc c/cpp trong dự án: -

#pragma comment(linker,"/manifestdependency:\"type='win32' name='acme.thedll' version='1.2.3.4' processorArchitecture='x86' language='*'\"") 

Nếu bạn đang sử dụng một cũ xây dựng môi trường nơi mà các biểu hiện được làm bằng tay, bạn sẽ cần phải hợp nhất xml sau đây với app1.exe.manifest trong thư mục App1:

<dependency> 
    <dependentassembly> 
    <assemblyidentity type="win32" name="acme.thedll" version="1.2.3.4" processorArchitecture="x86" language="*"/> 
    </dependentassembly> 
</dependency> 

này nên đóng hình tròn: Khi ứng dụng tải nạp win32 sẽ được tải tệp kê khai ứng dụng (app1.exe.manifest hoặc được nhúng dưới dạng tài nguyên RT_MANIFEST) và tìm hiểu về assembly "acme.thedll". Nó cũng sẽ tải tệp cấu hình ứng dụng (app1.exe.config) và tìm hiểu về đường dẫn riêng để tìm kiếm các hội đồng. Và sau đó nó sẽ tải và thêm "acme.thedll.manifest" vào ngữ cảnh kích hoạt "ứng dụng". Sau đó, khi trình tải cố gắng tải "thedll.dll", nó sẽ tìm kiếm trong bối cảnh kích hoạt db, tìm thấy nó trong assembly acme.thedll và tải nó từ vị trí assembly.

+0

Cảm ơn nhận xét của bạn. Tôi nghĩ rằng tôi đã trả lời trong bài trước của tôi rằng thời gian chạy DLL liên kết không phải là một giải pháp tôi đang tìm kiếm. Side by side assmebly khái niệm là tốt nhưng điều đó đòi hỏi một để đưa DLL tùy chỉnh của chúng tôi vào thư mục WinSXS và requies đặc quyền quản trị. Có cách nào để duy trì cửa hàng riêng trong cài đặt cục bộ và yêu cầu tất cả ứng dụng sản phẩm của tôi sử dụng nó từ cửa hàng không? Có cách nào để chỉ định một thư mục được sử dụng theo cách này trong tệp kê khai? -Kartlee – Kartlee

+0

Thật không may là không. Các cài đặt lắp ráp riêng lẻ bên cạnh được * chỉ * tìm kiếm trong thư mục của exe. Tôi đã thử đặt một đường dẫn tương đối vào dll trong nút tập tin của bản kê khai lắp ráp nhưng sau đó nó không tải được. tệp cấu hình Windows không hỗ trợ phần tử thăm dò của tệp cấu hình kiểu .NET. –

+0

Trên thực tế, miễn là hệ điều hành của bạn lựa chọn là Windows 7 hoặc Sever 2008, bạn có thể. Xem phần ammeded trong trả lời của tôi. –

0

Điều này có thể không giúp bạn, nhưng ... bạn CÓ THỂ tải dll từ các thư mục tùy ý VÀ vẫn dựa vào liên kết động bình thường với chúng miễn là bạn có thể kiểm soát khi các dll được tải qua liên kết động và đảm bảo rằng bạn đã đã tải dll một cách rõ ràng bằng cách sử dụng một đường dẫn đầy đủ trước khi nó được nạp động.

Điều này chỉ có thể trợ giúp nếu bạn đang viết một hệ thống plugin nơi plugin của bạn được liên kết động với các dll mà bạn muốn giữ trong một thư mục không chuẩn. Nếu sau đó bạn biết tất cả về các dll chúng được liên kết với bạn một cách rõ ràng có thể tải các dlls trực tiếp bằng cách sử dụng đường dẫn đầy đủ của họ trước khi bạn tải các dll (plugins) mà phụ thuộc vào chúng tự động. Kể từ khi dll đã có trong bộ nhớ khi plugin của bạn cần phải xác định vị trí nó sẽ sử dụng phiên bản trong bộ nhớ. Bạn có thể bỏ tải trọng rõ ràng mà bạn đã làm trước khi tải các plugin và bạn tốt để đi.

Thật không may điều này sẽ không hoạt động nếu exe chính của bạn cần tải dll từ các vị trí tùy ý khi bạn không thể đi trước tiến trình tải dll bình thường.

1

Tôi đang theo dõi câu trả lời của Chris. Hãy chắc chắn rằng các trường hợp là chính xác trên các biểu hiện và cấu hình. Nếu không, họ sẽ thất bại. Tôi đã có thể nhận được lắp ráp để được nạp, nhưng DLL sẽ không được chọn. Trong trường hợp của tôi một DLL Windows trong system32 đang được chọn thay vì của riêng tôi với cùng một tên. Trong Dependency Walker, DLL của tôi được tải, nhưng khi chạy, với Process Explorer, bản sao Windows được nạp. Bất kỳ ý tưởng?

Các vấn đề liên quan