閱讀:http://www.cnblogs.com/hans_gis/archive/2011/07/22/2114013.html
轉載:http://resources.arcgis.com/zh-cn/content/kbase?fa=articleShow&d=37879
Error: ArcGIS Engine Controls fail to build using Visual Studio 2010 on a 64-bit OS
| Article ID: | 37879 |
|---|---|
| Software: | ArcGIS Engine Developer Kit 10 |
| Platforms: | Windows 2003Server, 2008Server, Win 7 |
Error Message
When building ArcGIS Engine Controls-based applications on a supported 64-bit Operating System (OS) targeting the Microsoft .NET 3.5 framework in Visual Studio 2010, the following error may occur:
當在64位操作系統上,Vs2010中編譯AE控件程序,目標平台.net3.5,可能出現如下錯誤:
"Could not load file or assembly 'file:///C:/Program Files (x86)/ArcGIS/DeveloperKit10.0/DotNet/ESRI.ArcGIS.3DAnalyst.dll' or one of its dependencies. An attempt was made to load a program with an incorrect format.
Line 162, position 5. C:\temp\Projects\MyArcGISControlApp\Form1.resx"
The error message may differ from the above error message depending on how the project is set up, what assemblies are referenced, and the install location of the ArcObjects .NET SDK on the machine being used.
Microsoft is aware of this problem and has provided the following knowledge base article as a solution to this problem:
Article ID: 2028833: "MSBuild 4.0 or Visual Studio 2010 may fail to compile a 32-bit application targeted for .Net Framework 3.5, 3.0 or 2.0 on x64 machine."
當在64位操作系統上,Vs2010中編譯AE控件程序,目標平台.net3.5,可能出現如下錯誤:
"Could not load file or assembly 'file:///C:/Program Files (x86)/ArcGIS/DeveloperKit10.0/DotNet/ESRI.ArcGIS.3DAnalyst.dll' or one of its dependencies. An attempt was made to load a program with an incorrect format.
Line 162, position 5. C:\temp\Projects\MyArcGISControlApp\Form1.resx"
The error message may differ from the above error message depending on how the project is set up, what assemblies are referenced, and the install location of the ArcObjects .NET SDK on the machine being used.
Microsoft is aware of this problem and has provided the following knowledge base article as a solution to this problem:
Article ID: 2028833: "MSBuild 4.0 or Visual Studio 2010 may fail to compile a 32-bit application targeted for .Net Framework 3.5, 3.0 or 2.0 on x64 machine."
微軟發現了這個問題,並且在Article ID: 2028833文章中提出了解決方法。
Cause
This issue occurs when a Visual Studio project contains a resource file (.resx) that is referencing a 32-bit (x86) assembly and is compiled against .NET 3.5 in Visual Studio 2010. Visual Studio uses an executable called 'ResGen.exe' during the build process. This executable is marked as MSIL (Any CPU) and runs as a 64-bit (x64) process on a 64-bit OS. Since the Esri Controls are 32-bit and marked as such, it attempts to load the 32-bit assembly and fails.
問題發生在Vs2010中, vs項目包含一個.resx文件引用了一個32位程序集 並且不(compiled against)是用.net3.5編譯的。vs在創建過程中使用一個稱作'ResGen.exe'的可執行程序。這個可執行被標記為MSIL(Any CPU)並作為一個64位進程運行在64bit系統上。當Esri的32bit控件被標記為64位時,ResGen.exe試圖加載32位程序集結果報錯。
Solution or Workaround
The instructions provided in the Microsoft article (Article ID: 2028833) are sufficient to correct the problem. It involves changing the CorFlags section of the header of the executable to force it to run as a 32-bit application.
引言中提供的微軟的文章可以解決這個問題,他需要改變可執行程序頭的CorFlags部分強制可執行程序以32位方式運行。
To understand what this is doing refer to the following scenario. If a developer creates .NET executable and sets the target platform to 'Any CPU', this essentially creates a header file in the executable that tells the Common Language Runtime (CLR) to load and run the executable in the same process space it was run in. When running the executable on a 32-bit machine, it would run as a 32-bit application; and on a 64-bit machine, it would run as a 64-bit application.
為了理解都發生了什么參考下面的腳本。如果開發者創建了一個.net可執行文件,並設置目標平台Any CPU,必不可少的創建了一個頭文件在可執行文件中來告訴CLR來加載和運行在同樣的程序空間。當運行在32位的機器,他以32位程序運行,在64位以64bit運行。
When creating an executable that references assemblies of a particular process's space, such as an ArcGIS Engine ArcObjects application, the process space should always be set to x86. Because the ArcObjects’ assemblies are only 32-bit, this forces the executable to always run as a 32-bit process regardless of the target machine and allows it to load the assemblies that are only 32-bit.
當創建一個可執行文件引用一個特定程序空間的程序集,比如AE或者AO,進程空間應該一直被設置為X86,因為AO程序集只是32位的,這要求可執行程序一直以32位運行而不管目標機器,允許可執行程序加載的程序集只能是32位的。
The workaround uses CorFlags.exe to change the header file of ResGen.exe so that it runs as a 32-bit application and allows it to correctly load the Esri 32-bit assemblies.
運用CorFlags改變ResGen的頭文件,這樣就可以以32位的方式運行,並且保證了正確的加載Esri32bit程序集。
The steps detailed in the Microsoft article (Article ID: 2028833) can be automated within the project itself. For this to work correctly Visual Studio must and should be run as Administrator.
注意以管理員方式運行。
The following solution adds a custom build step to the Visual Studio project that temporarily changes the CorFlags section of the 'Resgen.exe' header file, so that the application compiles and then changes it back when finished.
接下來的方案給VS項目增加自定義build步驟,臨時改變‘Resgen.exe’的頭文件的CorFlags部分,這樣程序編譯成功后改回原來的頭文件。
引言中提供的微軟的文章可以解決這個問題,他需要改變可執行程序頭的CorFlags部分強制可執行程序以32位方式運行。
To understand what this is doing refer to the following scenario. If a developer creates .NET executable and sets the target platform to 'Any CPU', this essentially creates a header file in the executable that tells the Common Language Runtime (CLR) to load and run the executable in the same process space it was run in. When running the executable on a 32-bit machine, it would run as a 32-bit application; and on a 64-bit machine, it would run as a 64-bit application.
為了理解都發生了什么參考下面的腳本。如果開發者創建了一個.net可執行文件,並設置目標平台Any CPU,必不可少的創建了一個頭文件在可執行文件中來告訴CLR來加載和運行在同樣的程序空間。當運行在32位的機器,他以32位程序運行,在64位以64bit運行。
When creating an executable that references assemblies of a particular process's space, such as an ArcGIS Engine ArcObjects application, the process space should always be set to x86. Because the ArcObjects’ assemblies are only 32-bit, this forces the executable to always run as a 32-bit process regardless of the target machine and allows it to load the assemblies that are only 32-bit.
當創建一個可執行文件引用一個特定程序空間的程序集,比如AE或者AO,進程空間應該一直被設置為X86,因為AO程序集只是32位的,這要求可執行程序一直以32位運行而不管目標機器,允許可執行程序加載的程序集只能是32位的。
The workaround uses CorFlags.exe to change the header file of ResGen.exe so that it runs as a 32-bit application and allows it to correctly load the Esri 32-bit assemblies.
運用CorFlags改變ResGen的頭文件,這樣就可以以32位的方式運行,並且保證了正確的加載Esri32bit程序集。
The steps detailed in the Microsoft article (Article ID: 2028833) can be automated within the project itself. For this to work correctly Visual Studio must and should be run as Administrator.
注意以管理員方式運行。
The following solution adds a custom build step to the Visual Studio project that temporarily changes the CorFlags section of the 'Resgen.exe' header file, so that the application compiles and then changes it back when finished.
接下來的方案給VS項目增加自定義build步驟,臨時改變‘Resgen.exe’的頭文件的CorFlags部分,這樣程序編譯成功后改回原來的頭文件。
The following instructions will make changes to essential Microsoft Visual Studio files and may potentially contain a security risk. Continue at your own risk!
These instructions are an adaptation of a solution provided by Microsoft. Esri is not responsible for any damage that this may cause to your Visual Studio install. It is recommended that you back up the <install location>\Microsoft SDKs\Windows\v7.0A\bin\ResGen.exe before proceeding.
警告: 備份<install location>\Microsoft SDKS...
- In Visual Studio 2010 right-click on the project and select 'Unload Project'.
- Right-click the project again and select 'Edit <project name>'. The XML for the project file can be edited from this location.
- Add the following XML anywhere in the project. Preferably at the end, just above the closing '</Project>' tag, where it is easy to find.
關閉項目。右擊xxx.csproj,用記事本打開。將下面的XML文本粘貼到 '</Project>' tag結束標簽之前,保存,重新加載。
<!--
Workaround for VS2010 .NET 3.5 application referencing x86 assembly in resx file on 64-bit OS
http://social.msdn.microsoft.com/Forums/en-US/msbuild/thread/e5900710-9849-4d10-aa28-48b734d06bf2
-->
<PropertyGroup>
<ForceResGen32Bit Condition="'$(MSBuildToolsVersion)'=='4.0' And '$(PROCESSOR_ARCHITEW6432)'!='' And '$(TargetingClr2Framework)'=='true' And '$(PlatformTarget)'=='x86'">true</ForceResGen32Bit>
</PropertyGroup>
<Target Name="BeforeResGen" Condition="'$(ForceResGen32Bit)' == 'true'">
<PropertyGroup>
<ResGenSdkToolsPath>$(IntermediateOutputPath)ResGenForced32Bit\</ResGenSdkToolsPath>
</PropertyGroup> <!-- Copy resgen.exe to intermediate working directory for UAC settings -->
<Copy SourceFiles="$(TargetFrameworkSDKToolsDirectory)ResGen.exe"
DestinationFiles="$(ResGenSdkToolsPath)ResGen.exe" /> <!-- corflags.exe resgen.exe /32BIT+ /Force-->
<Exec WorkingDirectory="$(ResGenSdkToolsPath)"
Command=""$(TargetFrameworkSDKToolsDirectory)corflags.exe" ResGen.exe /32BIT+ /Force" />
<!-- GenerateResource Task parameters
Using the non-64bit Tracker.exe and indicate resgen.exe has been forced to x86 -->
<PropertyGroup>
<ResGenTrackerSdkPath>$(SDK40ToolsPath)</ResGenTrackerSdkPath>
<ResGenToolArchitecture>Managed32Bit</ResGenToolArchitecture>
<CacheTargetFrameworkSDKToolsDirectory>$(TargetFrameworkSDKToolsDirectory)</CacheTargetFrameworkSDKToolsDirectory>
<TargetFrameworkSDKToolsDirectory>$(ResGenSdkToolsPath)</TargetFrameworkSDKToolsDirectory>
</PropertyGroup>
</Target>
<Target Name="AfterResGen" Condition="'$(ForceResGen32Bit)' == 'true'">
<PropertyGroup>
<TargetFrameworkSDKToolsDirectory>$(CacheTargetFrameworkSDKToolsDirectory)</TargetFrameworkSDKToolsDirectory>
</PropertyGroup>
<RemoveDir Directories="$(ResGenSdkToolsPath)" Condition="Exists('$(ResGenSdkToolsPath)')" />
</Target>
4. Right-click the project and select 'Reload Project'.
5. Build the project.
Related Information
Created: 6/15/2010
Last Modified: 7/2/2010
