11

Tôi vừa nâng cấp giải pháp VS 2008 chứa WinForms, thư viện sử dụng chung và ứng dụng web lên VS 2010, nhưng tất cả dự án vẫn nhắm mục tiêu .NET 3.5 SP 1. Tôi sử dụng this technique để tạo XmlSerializers cho các thư viện sử dụng chung của tôi. Ứng dụng WinForms chạy tốt. Khi ứng dụng web của tôi cố gắng chạy sử dụng các thư viện tham khảo các XmlSerializers cùng, nó ném như sau:VS.NET 2010/MSBUILD có thể tạo XmlSerializers cho .NET 3.5 SP1 không?

Server Error in '/ WebSubscribers' Application. Không thể tải tệp hoặc lắp ráp 'Ceoimage.Basecamp.XmlSerializers' hoặc một trong các phụ thuộc của nó. Bản lắp ráp này được tạo bởi thời gian chạy mới hơn thời gian chạy hiện được tải và không thể được tải . Mô tả: Một ngoại lệ không được giải quyết xảy ra trong khi thực hiện yêu cầu web hiện tại là . Vui lòng xem lại dấu vết ngăn xếp để biết thêm thông tin về số lỗi và địa chỉ có nguồn gốc từ mã.

Chi tiết ngoại lệ: System.BadImageFormatException: Không thể tải tệp hoặc lắp ráp 'Ceoimage.Basecamp.XmlSerializers' hoặc một trong các phụ thuộc của nó. Hội đồng này được xây dựng bởi một thời gian chạy mới hơn thời gian chạy hiện đang được tải và không thể tải được.

Tôi đã xem xét tài liệu tham khảo của XmlSerializer sử dụng NET Reflector và xem nó tham chiếu cả 2.0 và 4.0 phiên bản của mscorlib cũng như 3.5 và 4.0 phiên bản của System.Data.Linq. Kỳ lạ thay, nó chỉ sử dụng phiên bản 4.0 System.Xml. Đó có lẽ là vấn đề của tôi ngay tại đó.

Làm cách nào để ứng dụng web chạy bằng các XmlSerializers này? Khi tôi chỉ đơn giản xóa các XmlSerializers, ứng dụng web chạy tốt. Đây là một tùy chọn, nhưng làm thế nào tôi có thể buộc MSBUILD để tạo serializers cho một phiên bản cụ thể của CLR?

Dưới đây là nhiệm vụ MSBuild tôi thêm vào file đó buộc việc tạo ra các XmlSerializers dự án:

<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)"> 
<Delete Files="$(TargetDir)$(TargetName).XmlSerializers.dll" ContinueOnError="true" /> 
<SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)" References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(SGenToolPath)"> 
    <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" /> 
</SGen> 
</Target> 
+1

bạn nên thêm rằng chỉnh sửa như một câu trả lời vì vậy chúng tôi có thể bỏ phiếu nó lên, nó dường như là giải pháp tốt nhất :) – Lucas

Trả lời

2

tôi thấy tôi rõ ràng có thể chỉ định các công cụ con đường nhiệm vụ sgen để sử dụng phiên bản 3.5, như vậy:

<SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)" References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin"> 
+0

Bạn có thay đổi các tập tin mục tiêu hoặc là bạn sửa đổi các tập tin dự án của bạn một số như thế nào? Tôi không biết cách áp dụng điều này cho môi trường của mình ... –

+0

Đây là một thời gian dài trước đây, nhưng tôi khá chắc chắn rằng tôi đã chỉnh sửa trực tiếp tệp CSPROJ. – flipdoubt

2

Bạn có phụ thuộc vào bất cứ điều gì 4.0 cụ thể?

Nếu bạn gọi MSBuild 4.0, bạn sẽ nhận được 4.0 công cụ. Nếu bạn gọi MSBuild 3.5, bạn sẽ nhận được 3.5 công cụ (đó là những gì bạn muốn khi bạn đang lưu trữ rõ ràng trong một 2.0 CLR).

Tùy chọn khác là đặt 4.0 CLR trên máy chủ web của bạn. Nếu điều đó không mở, bạn không nên có bất kỳ thứ gì được nhắm mục tiêu 4.0 trong luồng của mình.

+0

Tôi chỉ cần kiểm tra một trong các dự án của tôi và tìm thấy nó chỉ tham khảo 2,0 và 3,5 khung hội đồng. Tuy nhiên, một điều tôi nhận thấy là thuộc tính 'Specific Version' của mỗi khung tham chiếu đến' false'. Khi tôi dỡ một dự án và nhìn vào tệp .CSPROJ, thẻ thuộc tính không đề cập đến các công cụ 4.0 như sau: '' Khi tôi thay đổi 'ToolsVersion' thành' 3.5', VS 2010 chuyển đổi dự án và trả về giá trị thành '4.0'. – flipdoubt

+0

@flipdoubt: VS2010 buộc phải chuyển đổi 4.0 công cụ là một vấn đề đã biết (có tìm kiếm). vấn đề ở đây là nhiệm vụ SGen đang được nhập là nhiệm vụ 4.0 sgen sẽ mặc định là 4.0 SGen.exe Có lẽ đặt một toolPath ghi đè lên công việc 3,5 SGen mioght. –

+0

Và sau đó tôi đã xem bản chỉnh sửa của bạn. Tôi nghĩ rằng đó là sửa chữa tốt nhất cho rằng chạy các dự án ToolsVersion 4.0 của bạn thông qua MSBuild 3.5 không phải là một giải pháp lâu dài –

8

MSBuild 4 sẽ (nên ...) sử dụng 3,5 công cụ để xây dựng 3,5 dự án. Tuy nhiên, có vẻ như nó không thể làm việc ra nơi mà các công cụ 3,5 và đang sử dụng các công cụ 4.0. Kết quả là nó đang xây dựng đúng dự án 3.5 của bạn (với các hội đồng CLR 2.0.50727), nhưng công cụ 4.0 sgen.exe đang tạo ra Ceoimage.Basecamp.XmlSerializers.dll như một assembly CLR 4.0.30319.

MSBuild sử dụng đăng ký để nhận đường dẫn đến công cụ v3.5. Các tác vụ MSBuild yêu cầu công cụ v3.5 SDK sẽ rơi trở lại đường dẫn v4.0 nếu đường dẫn đến 3.5 công cụ không thể được xác định - nhìn vào logic được sử dụng để thiết lập thuộc tính TargetFrameworkSDKToolsDirectory trong C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ Microsoft.NETFramework.props nếu bạn thực sự quan tâm.

Bạn có thể chẩn đoán và sửa chữa các vấn đề registry có thể như sau:

Cài đặt Process Monitor và thiết lập một bộ lọc để giám sát truy xuất registry bởi msbuild (lớp tổ chức sự kiện: Registry, Process Name: msbuild.exe, tất cả các loại kết quả)

Chạy xây dựng của bạn

Process Monitor Tìm kiếm cho một kết hợp truy cập RegQueryValue "MSBuild \ ToolsVersions \ 4.0 \ SDK35ToolsPath". Lưu ý rằng điều này có thể nằm trong "HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft" hoặc "HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft"

Nếu bạn nhìn vào khóa này trong sổ đăng ký, bạn sẽ thấy rằng nó bí danh một đăng ký khác giá trị, ví dụ "$ (Registry: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Microsoft SDK \ Windows \ v7.1 \ WinSDK-NetFx35Tools-x86 @ InstallationFolder)" Ngay sau đó, bạn có thể sẽ thấy kết quả "NAME NOT FOUND" khi msbuild cố gắng tải giá trị từ khóa được chỉ định.

Cần phải rõ ràng những phím nào bạn cần thêm/sửa đổi từ đây.

Có một vài lý do có thể khiến giá trị đăng ký sai. Trong trường hợp của tôi, một vấn đề với quá trình cài đặt v7.1 Microsoft SDK có nghĩa là các khóa registry được đặt tên không đúng, mà đã được xác định là một lỗi ở đây:

http://connect.microsoft.com/VisualStudio/feedback/details/594338/tfs-2010-build-agent-and-windows-7-1-sdk-targeting-net-3-5-generates-wrong-embedded-resources

+0

+1 để được giải thích –

+0

Cảm ơn câu trả lời này. Tôi đang kết hợp điều này với http://stackoverflow.com/a/2739132/281084 để giải quyết vấn đề của mình –

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