Satellite resource .dll's compiles to wrong .net framework?
Asked Answered
E

1

6

The program below is supposed to get a resource string from a satellite resourcefile. It works fine when compiled with target framework='NET Framework 4.5.2' using VS2015. However, setting target framework='NET Framework 3.5' makes it unable to find the satellite resource file and fall back to the default resources.

I peeked in the .exe and satellite .dll files and found that they are compiled to different .net versions (Eventhough it was the same compilation that generated them):

Main exe got:                  .Net Framework v3.5
Satellite resource dll got:    .Net Framework v4.0 

It seams like the satellite dlls gets the wrong .Net version. Has anyone experienced this and is there a solution? (Other than upgrading the project to the newest .Net version)

class Program
{
    static void Main(string[] args)
    {

        CultureInfo newCultureInfo = new System.Globalization.CultureInfo("da-DK");
        Thread.CurrentThread.CurrentUICulture = newCultureInfo;

        Console.WriteLine("Resource test");
        ResourceManager rm = new ResourceManager("ResourceTest.Resources.MyResources", Assembly.GetExecutingAssembly());

        Console.WriteLine(rm.GetString("hello"));

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

EDIT: Seams like I got a bad update to my development enviroment. A reinstall of the whole computer helped, but simply reinstalling .Net and Visual Studio didn't! (I wonder if there is something in the registry database that doesn't get reset by a simple reinstall)

Exciter answered 10/9, 2015 at 11:29 Comment(5)
Not a common complaint, the only obvious reason is that the satellite dll didn't get rebuilt. The much more common problem is that the .resx file still contains 4.0 type references. They only get rewritten when you make a change to them and that's easy to overlook after you changed the framework target. Have a look-see at the file(s) with a text editor.Plaided
No, this is not the case. It crossed my mind too, so to ensure that its not the case I deleted the whole bin dir and then recompiled. The problem is still there.Exciter
I also have this problemSid
For me it was the opposite, it worked until I did the clean install of windows then it began generating .net 4.0 resources for a .net 3.5 program. So a clean install is sadly not the solution/workaround.Eba
Try this solution, although it's talking about VS2017 the fix should work for similar situations.Eba
T
1

I know this question is almost six years old but this is again an issue today, with Visual Studio 2019. I have confirmed it with 16.10.2 and 16.10.3 (may be more). Building a .Net 3.5 application left me with non-working resource dll's, which puzzled me until I found your question that hinted to investigate the resource dll .Net version, discovering that these were indeed linked to .Net 4 mscorlib instead of 3.5.

Problem confirmation

First confirm the issue.

  1. In Visual Studio, go to Tools / Options / Projects and Solutions /
    Build and Run and set MS Build project build output verbosity to at least Normal (default is Minimal).

  2. Rebuild your .Net 3.5 project.

  3. In the Output / Build window look for the task GenerateSatelliteAssemblies:. The command line below shows C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\al.exe, which is the .Net 4.8 version of the assembly linker. On an unaffected system, that should have been C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\al.exe.

So far the same problem as mentioned in the link by hultqvist's comment on the question. The cause and solution is different, however. The registry keys that are mentioned there, were perfectly fine on my system.

TL;DR - Solution (Workaround)

  1. Go to C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets (exact path may differ a bit on your system, e.g. Professional instead of Enterprise).
  2. Create a backup copy of this file.
  3. Edit the file, and find a line containing the text _ALExeToolPath. It should be around line 3739. Looks like this:
    <PropertyGroup>
      <_ALExeToolPath>$(TargetFrameworkSDKToolsDirectory)</_ALExeToolPath>
      <_ALExeToolPath Condition="'$(PlatformTarget)' == 'x64'">$(TargetFrameworkSDKToolsDirectory)$(PlatformTarget)\</_ALExeToolPath>
    </PropertyGroup>
  1. Now scroll a bit down into the AL tag below and find the SdkToolsPath attribute.
    <AL AlgorithmId="$(Satellite_AlgorithmId)"
        BaseAddress="$(Satellite_BaseAddress)"
    ...
        SdkToolsPath="$(SdkToolsPathMaybeWithx64Architecture)"  <!-- this is incorrect -->
  1. Change the value of the attribute from $(SdkToolsPathMaybeWithx64Architecture) to $(_ALExeToolPath)
  2. Save the file (needs elevation, probably)
  3. Rebuild your project, the correct linker is used and your resource dll's will work again.

Cause

This issue was introduced here to fix a minor issue with the assembly linker when targeting x64 vs x86. If you follow the comment thread with that PR you will spot the mistake: the actual variable in the fix is renamed after discussion, but they forgot to update that in the AL attribute before the PR was merged.

Because of this, the sdk tools path for al.exe is empty (it mentions a non-existing variable) and that causes msbuild to always call the default, which is usually the x86 version of the newest installed framework sdk on your system -- instead of a version that matches the version of your project.

That version of the .targets file has been rolled out with a VS update.

They have since then spotted the mistake and fixed it. That fix has not rolled out as of today. If I understand the discussion correctly it is targeted for publish with v16.11.

If you cannot wait for that, follow the workaround I described above.

Transferor answered 20/7, 2021 at 7:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.