Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSBuild AssemblyVersion property should always have 4 integer components #26

Closed
adrianvmsft opened this issue Oct 1, 2015 · 4 comments
Assignees
Labels
Milestone

Comments

@adrianvmsft
Copy link
Contributor

GitVersioning may interfere with Markup Compilation for WPF applications and cause assembly load exception at runtime

This may not be a common scenario, and it has a simple workaround, so may not need a fix. I am logging it here in case other people encounter it.

Symptom: System.IO.FileLoadException thrown when wpf is trying to load resources in InitializeComponent

Background:

  • GitVersioning sets the AssemblyVersion property to something like "14.1"
  • MarkupCompilePass1 WPF target picks up the AssemblyVersion property and inserts it into the generated .g.cs based on the XAML:
        public void InitializeComponent() {
            // ...
            System.Uri resourceLocater = new System.Uri("/foo;V14.1;component/bar.xaml", System.UriKind.Relative);
            // ...
        }
  • At runtime, when this method gets called, it first tries to match the assembly against loaded assemblies; however that fails in this case as it tries to match against the full version (14.1.0.0)
  • Because it couldn't find the assembly (even it if was already in memory), it tries to load it. Most of the times that will succeed, but in some cases (e.g. the assembly is located somewhere else, not under the probing path) you will encounter this problem

Workaround: Insert the following snippet in the affected projects

  <Target Name="ClearAssemblyVersionBeforeMarkupCompilePass1" BeforeTargets="MarkupCompilePass1">
    <PropertyGroup>
      <AssemblyVersion />
    </PropertyGroup>
  </Target>

This will clear up the AssemblyVersion right before the MarkupCompilePass1 target gets executed. This will cause the version not to be specified in the generated file, and it will successfully match the assembly against the version already loaded in memory

@AArnott
Copy link
Collaborator

AArnott commented Oct 3, 2015

Thanks for reporting this, @adrianvmsft. We only just started setting the AssemblyVersion MSBuild property, and we could use a property by a different name if that avoids this problem. I'd like to understand it a bit better though. What makes specifying the assembly version problematic? If it is indeed the assembly version of the compiled assembly, shouldn't WPF still be able to find it?

@AArnott AArnott added this to the 1.2.0 milestone Oct 3, 2015
@adrianvmsft
Copy link
Contributor Author

It doesn't find the assembly in memory (it is already loaded) because it ends up comparing "14.1" against "14.1.0.0". I know, perhaps the comparison should succeed but it doesn't.
So it tries to load it using Assembly.Load. Usually that works, but in some cases it may fail (e.g. if the assembly is located somewhere else on the disk).

In that case you end up in a situation where the assembly is already loaded, but it tries to load it anyways and if that fails it throws exception.

I think it is a corner case - I encountered it with a VS extension that has WPF UI.

@AArnott
Copy link
Collaborator

AArnott commented Oct 3, 2015

I see. I suspect that .NET considers versions to always have 4 components, but this project initializes the MSBuild property with only 2. If we force it to always be 4 components long, in effect like this:

<AssemblyVersion>14.1.0.0</AssemblyVersion>

Then that should resolve it. Do you agree?

@AArnott
Copy link
Collaborator

AArnott commented Oct 3, 2015

I have confirmed that the CLR always considers that an AssemblyVersion has 4 integer components to it, regardless of how it is formatted in the AssemblyVersionAttribute constructor. So I'm preparing a fix so that the AssemblyVersion property in MSBuild always have four integer components in it as well.

@AArnott AArnott self-assigned this Oct 3, 2015
AArnott added a commit that referenced this issue Oct 3, 2015
@AArnott AArnott changed the title GitVersioning may interfere with Markup Compilation for WPF applications and cause assembly load exception at runtime MSBuild AssemblyVersion property should always have 4 integer components Oct 3, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants