References to "System.String, mscorlib 2.0" in resources

Topics: For MSBee Users
Aug 16, 2006 at 9:31 PM
migrated from power toy forums
originally posted by Gildas Garcia
------------------------------------------------------

Hi,

I need to compile my projects for the FX 1.1. I use VS 2005 and have installed MSBee. Everything is ok, my dlls all reference MSCorlib 1.0.5000.0.

I only have a problem with the resources. For each string in my resources file, the type referenced is "System.String, mscorlib, 2.0.0.0, ....". So when I deploy it on a machine which don't have the FX2.0, I got a nice exception...

Any advices ? Thanks.
Aug 16, 2006 at 9:31 PM
originally posted by Gildas Garcia
------------------------------------------------------

After a closer look, I found this :

The resources file *.resources generated by ResGen is good. My strings all reference "System.String, mscorlib, 1.0.5000.0, ...".

It's the AL tool which replace the references to target the mscorlib 2.0.0.0.

So it looks like if the AL tool always take the later version of the framework.
Aug 16, 2006 at 9:31 PM
originally posted by Craig Lichtenstein - MSFT
------------------------------------------------------

My understanding of the problem is that resgen generated .resources files that refer to MSCorlib 1.0.5000.0 but you believe AL.exe is changing that reference to MSCorlib 2.0.0.0, hence why you're receiving an exception. Please correct me if I'm wrong.

I re-ran our tests that verify AL 1.1 works with MSBee. I used ildasm to look at the manifest of one of the resource DLLs built with AL.exe when using MSBee, and confirmed the metadata version is 1.1.4322 and the version of mscorlib being referenced is 1.0.5000.0. You can try this as well on your DLLs to see if AL.exe is really the culprit.

It may also help if you could add '/v:diag' to the end of the MSBuild command line and run it again. The /v switch controls the verbosity of build output that's generated by MSBuild and 'diag' produces diagnostic output. Thus, if you could add this flag to obtain the output and then post the output, I could review it and that may also reveal some clues.
Aug 16, 2006 at 9:32 PM
originally posted by Gildas Garcia
------------------------------------------------------

Hi Craig, thanks for answering,

I should be more precise :

You're right, all my dlls (main and satellites) reference the FX 1.1.4322 and mscorlib 1.0.500.0. The problem is not in the assembly references but in the type of each resource.

In my project, I have only one resx file which contains only strings. After a ResGen, each string element of the resx refere to the type string in mscorlib 1.0.500.0 (I took a look in Hexa). After the AL tool, each string refere to the type string in mscorlib 2.0 (at least, it is what I saw via Reflector).

I also have tried to call manually the FX 1.1.4322 AL.exe with the resource file and I got the same result.

Can you check your resurces adn tell me if you reproduce this behaviour ?

Here is the output from MSBuild (sorry, it's very long...) :
Aug 16, 2006 at 9:32 PM
originally posted by Craig Lichtenstein - MSFT
------------------------------------------------------

I was able to reproduce what you saw in .NET Reflector. Afterwards, I downloaded .NET Resourcer and used it to view the .resources files in the obj\FX1_1 directory. According to .NET Resourcer, the types in these files were all System.String, mscorlib, version 1.0.5000.0, which confirms the .resources aren't the problem.

I then took one of the sample apps we test MSBee with and found its VS .NET 2003 solution. I rebuilt it in VS 2003 and then opened it in Reflector. Interestingly, when I viewed its resources, their types were all System.String, mscorlib, v2.0.0.0. Note that I don't have VS 2005 installed on the machine I tried this on, although .NET 2.0 is present. This leaves me wondering if something funky is going on in Reflector where having .NET 2.0 present causes it to assume that the type always comes from mscorlib 2.0.

Can you reproduce this behavior with a VS 2003 app in Reflector? Also, was there anywhere else where you saw the .NET 2.0 mscorlib type for the resources?
Aug 16, 2006 at 9:32 PM
originally posted by Gildas Garcia
------------------------------------------------------

Hi Craig, sorry to have bothered you with this.

I don't have the problem anymore but I can't say what I have done exactly. I agree with you on the Reflector funky behaviour, I reproduced it and on a system with only FX1.1 installed, the same resources are String, 1.0.5000.0...

Btw, here is my version of the CrossCompile.CSharp.targets file which allow me to run MSBuild from VS and target the FX 1.1 :-). After this file, a sample of a project.

The only thing to do is to add a new platform "NET 1.1".

------------------------------------------------------------------

<!--
Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm
Written by Jomo Fisher
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup Condition=" '$(Platform)' == '.NET 1.1' ">
<!-- Modify the version number depending on what version you are compiling for. -->
<CscToolPath>$(WINDIR)\Microsoft.NET\Framework\v1.1.4322</CscToolPath>
<TargetFrameworkDirectory>$(WINDIR)\Microsoft.NET\Framework\v1.1.4322</TargetFrameworkDirectory>
<TargetFrameworkVersion>v1.1</TargetFrameworkVersion>
<BuildingInsideVisualStudio>false</BuildingInsideVisualStudio>
<UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable>
<ReferencePath>$(ReferencePath);$(WINDIR)\Microsoft.NET\Framework\v1.1.4322</ReferencePath>
<DisabledWarnings>$(NoWarn)</DisabledWarnings>
<CreateSatelliteAssembliesDependsOn>ComputeIntermediateSatelliteAssemblies</CreateSatelliteAssembliesDependsOn>
</PropertyGroup>

<Target Name="GetFrameworkPaths" DependsOnTargets="$(GetFrameworkPathsDependsOn)" >
<CreateProperty Value="$(WINDIR)\Microsoft.NET\Framework\v1.1.4322" Condition=" '$(Platform)' == '.NET 1.1' ">
<Output PropertyName="TargetFrameworkDirectory" TaskParameter="Value" />
</CreateProperty>

<!-- Get the path to the target .NET framework directory. -->
<GetFrameworkPath Condition=" '$(Platform)' != '.NET 1.1' ">
<Output TaskParameter="Path" PropertyName="TargetFrameworkDirectory"/>
</GetFrameworkPath>

<!-- Get the path to the target .NET framework SDK directory. -->
<GetFrameworkSDKPath >
<Output TaskParameter="Path" PropertyName="TargetFrameworkSDKDirectory"/>
</GetFrameworkSDKPath>
</Target>

<Target
Name="CreateSatelliteAssemblies"
Condition="'@(ManifestResourceWithCulture)'!='' or '@(ManifestNonResxWithCultureOnDisk)'!=''"
DependsOnTargets="$(CreateSatelliteAssembliesDependsOn)"
Inputs="$(MSBuildAllProjects);@(ManifestResourceWithCulture);@(ManifestNonResxWithCultureOnDisk);$(IntermediateOutputPath)$(TargetName)$(TargetExt)"
Outputs="$(IntermediateOutputPath)%(Culture)\$(TargetName).resources.dll">

<MakeDir
Directories="$(IntermediateOutputPath)%(ManifestResourceWithCulture.Culture)"
Condition=" '@(ManifestResourceWithCulture)' != '' "/>

<MakeDir
Directories="$(IntermediateOutputPath)%(ManifestNonResxWithCultureOnDisk.Culture)"
Condition=" '@(ManifestNonResxWithCultureOnDisk)' != '' "/>

<!--
This target still uses the AL task that comes with MSBuild. The AL element below has been modified
from the standard version to exclude the Property attribute and to set ToolPath to
$(TargetFrameworkDirectory). If you want to use the AL task in another target, and want to target
.NET 1.1, copy/paste the AL element below into your target.
-->
<AL
AlgorithmId="$(Satellite_AlgorithmId)"
BaseAddress="$(Satellite_BaseAddress)"
CompanyName="$(Satellite_CompanyName)"
Configuration="$(Satellite_Configuration)"
Copyright="$(Satellite_Copyright)"
Culture="%(Culture)"
DelaySign="$(DelaySign)"
Description="$(Satellite_Description)"
EmbedResources="@(ManifestResourceWithCulture);@(ManifestNonResxWithCultureOnDisk)"
EvidenceFile="$(Satellite_EvidenceFile)"
FileVersion="$(Satellite_FileVersion)"
Flags="$(Satellite_Flags)"
GenerateFullPaths="$(Satellite_GenerateFullPaths)"
KeyContainer="$(KeyContainerName)"
KeyFile="$(KeyOriginatorFile)"
LinkResources="@(Satellite_LinkResource)"
MainEntryPoint="$(Satellite_MainEntryPoint)"
OutputAssembly="$(IntermediateOutputPath)%(Culture)\$(TargetName).resources.dll"
ProductName="$(Satellite_ProductName)"
ProductVersion="$(Satellite_ProductVersion)"
ResponseFiles="@(AlResponseFile)"
SourceModules="@(Satellite_SourceModule)"
TargetType="$(Satellite_TargetType)"
TemplateFile="$(IntermediateOutputPath)$(TargetName)$(TargetExt)"
Title="$(Satellite_Title)"
ToolPath="$(TargetFrameworkDirectory)"
Trademark="$(Satellite_Trademark)"
Version="$(Satellite_Version)"
Win32Icon="$(Satellite_Win32Icon)"
Win32Resource="$(Satellite_Win32Resource)">

<!--
The Platform property only applies to al.exe 2.0 and is filtered for the al task above.
Thus, if you set this flag, it will be ignored when targeting .NET 1.1.
You can uncomment this property and add it to the al task if you wish.
You will then receive a warning or error if you set this property because al.exe 1.1
won't recognize the corresponding switch.
-->
<!--
Platform="$(PlatformTarget)"
-->

<Output TaskParameter="OutputAssembly" ItemName="FileWrites"/>
</AL>
</Target>

</Project>
---------------------------------------------------------------------------

Sample Project file :

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{1AEFEDF5-CF67-4A4A-97FF-2B2DE976E164}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MyProject</RootNamespace>
<AssemblyName>MyProject</AssemblyName>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>bin\Debug\</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>bin\Release\</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|.NET 1.1' ">
<DefineConstants>DEBUG;TRACE;TARGETTINGFX1_1</DefineConstants>
<RunCodeAnalysis>false</RunCodeAnalysis>
<OutputPath>bin\.NET 1.1\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|.NET 1.1' ">
<DefineConstants>TRACE;TARGETTINGFX1_1</DefineConstants>
<RunCodeAnalysis>false</RunCodeAnalysis>
<OutputPath>bin\.NET 1.1\Release\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Web" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<Compile Include="Resources\Strings.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\CrossCompile.CSharp.targets" />
</Project>

Hope this help :) Thanks again.