Patch WPF Toolkit-specific code

Let's hope there aren't any other libs that
do this weird and non-standard thing.
This commit is contained in:
Timotei Dolean 2015-05-22 13:47:37 +03:00
Родитель f11f51fc99
Коммит c10dca19fe
6 изменённых файлов: 86 добавлений и 13 удалений

11
.gitignore поставляемый
Просмотреть файл

@ -7,10 +7,11 @@ _ReSharper*
.classpath
.project
.gradle
build
bin
obj
packages
build/
buildSrc/
bin/
obj/
packages/
*.suo
*.user
*.pidb
@ -27,3 +28,5 @@ glob:Backup
_NCrunch*
*.ncrunchsolution
*.ncrunchproject
*.sln.cache
*.DotSettings

Просмотреть файл

@ -4,6 +4,7 @@
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:wpfSampleApplication="clr-namespace:WPFSampleApplication"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
Style="{DynamicResource WindowStyle}" Height="350" Width="525" Loaded="MainWindowOnLoaded">
<controls:MetroWindow.Resources>
<ResourceDictionary>
@ -20,5 +21,7 @@
<i:Interaction.Behaviors>
<wpfSampleApplication:CloseWindowOnAttachBehaviour />
</i:Interaction.Behaviors>
<wpfSampleApplication:MyUserControl x:Name="MyUserControl" />
<xctk:BusyIndicator BusyContent="Pretending to be busy..." IsBusy="True">
<wpfSampleApplication:MyUserControl x:Name="MyUserControl" />
</xctk:BusyIndicator>
</controls:MetroWindow>

Просмотреть файл

@ -65,6 +65,30 @@
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="Xceed.Wpf.AvalonDock, Version=2.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Extended.Wpf.Toolkit.2.4\lib\net40\Xceed.Wpf.AvalonDock.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xceed.Wpf.AvalonDock.Themes.Aero, Version=2.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Extended.Wpf.Toolkit.2.4\lib\net40\Xceed.Wpf.AvalonDock.Themes.Aero.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xceed.Wpf.AvalonDock.Themes.Metro, Version=2.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Extended.Wpf.Toolkit.2.4\lib\net40\Xceed.Wpf.AvalonDock.Themes.Metro.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xceed.Wpf.AvalonDock.Themes.VS2010, Version=2.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Extended.Wpf.Toolkit.2.4\lib\net40\Xceed.Wpf.AvalonDock.Themes.VS2010.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xceed.Wpf.DataGrid, Version=2.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Extended.Wpf.Toolkit.2.4\lib\net40\Xceed.Wpf.DataGrid.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xceed.Wpf.Toolkit, Version=2.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Extended.Wpf.Toolkit.2.4\lib\net40\Xceed.Wpf.Toolkit.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Page Include="MainWindow.xaml">
@ -117,7 +141,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>mkdir $(TargetDir)\merged
$(TargetDir)ILRepack.exe /verbose /log /out:$(TargetDir)\merged\$(TargetFileName) $(TargetPath) $(TargetDir)Microsoft.Expression.Interactions.dll $(TargetDir)MahApps.Metro.dll $(TargetDir)System.Windows.Interactivity.dll
$(TargetDir)ILRepack.exe /verbose /log /out:$(TargetDir)\merged\$(TargetFileName) $(TargetPath) $(TargetDir)Microsoft.Expression.Interactions.dll $(TargetDir)MahApps.Metro.dll $(TargetDir)System.Windows.Interactivity.dll $(TargetDir)Xceed.Wpf.Toolkit.dll $(TargetDir)Xceed.Wpf.DataGrid.dll
set SAVED_ERROR_LEVEL=%25ERRORLEVEL%25
REM Ensure re-build is done every time to use latest built ILRepack version
del /q $(ProjectDir)\obj\$(ConfigurationName)\*.*

Просмотреть файл

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Extended.Wpf.Toolkit" version="2.4" targetFramework="net40" />
<package id="MahApps.Metro" version="1.1.2.0" targetFramework="net40" />
<package id="MahApps.Metro.Resources" version="0.4.0.0" targetFramework="net40" />
<package id="System.Windows.Interactivity.WPF" version="2.0.20525" targetFramework="net40" />

Просмотреть файл

@ -56,9 +56,9 @@ namespace ILRepack.IntegrationTests
Assert.NotNull(process);
bool processEnded = process.WaitForExit(ScenarioProcessWaitTimeInMs);
Assert.That(processEnded, Is.True, "Process has not ended.");
Console.WriteLine("\nScenario '{0}' STDOUT: {1}", scenarioName, process.StandardOutput.ReadToEnd());
Assert.That(processEnded, Is.True, "Process has not ended.");
Assert.That(process.ExitCode, Is.EqualTo(0), "Process exited with error");
}

Просмотреть файл

@ -39,14 +39,56 @@ namespace ILRepacking.Steps
_logger.VERBOSE("Processing XAML resource paths ...");
foreach (var type in types)
{
var initializeMethod = type.Methods.FirstOrDefault(m =>
m.Name == "InitializeComponent" && m.Parameters.Count == 0);
PatchInitializeComponentMethod(type);
PatchWpfToolkitVersionResourceDictionary(type);
}
}
if (initializeMethod == null || !initializeMethod.HasBody)
private void PatchWpfToolkitVersionResourceDictionary(TypeDefinition type)
{
// Extended WPF toolkit has a nasty way of including the xamls in the generic.xaml
// Instead of a simple ResourceDictionary they use a custom one which hardcodes
// the assembly name and version:
// <core:VersionResourceDictionary AssemblyName="Xceed.Wpf.Toolkit" SourcePath="Calculator/Themes/Generic.xaml" />
if (!"Xceed.Wpf.Toolkit.Core.VersionResourceDictionary".Equals(type.FullName))
return;
var endInitMethod = type.Methods.FirstOrDefault(m =>
m.Name == "System.ComponentModel.ISupportInitialize.EndInit");
if (endInitMethod == null)
{
_logger.WARN("Could not find a proper 'EndInit' method for Xceed.Wpf.Toolkit to patch!");
return;
}
PatchWpfToolkitEndInitMethod(endInitMethod);
}
private void PatchInitializeComponentMethod(TypeDefinition type)
{
var initializeMethod = type.Methods.FirstOrDefault(m =>
m.Name == "InitializeComponent" && m.Parameters.Count == 0);
if (initializeMethod == null || !initializeMethod.HasBody)
return;
_logger.VERBOSE(" - Patching type " + type.FullName);
PatchMethod(initializeMethod);
}
private void PatchWpfToolkitEndInitMethod(MethodDefinition method)
{
const string ComponentPathString = "{0};v{1};component/{2}";
foreach (var stringInstruction in method.Body.Instructions.Where(i => i.OpCode == OpCodes.Ldstr))
{
if (!ComponentPathString.Equals(stringInstruction.Operand as string))
continue;
_logger.VERBOSE(" - Patching type " + type.FullName);
PatchMethod(initializeMethod);
stringInstruction.Operand =
string.Format(
"/{0};component/Xceed.Wpf.Toolkit/{{2}}",
_repackContext.PrimaryAssemblyDefinition.Name.Name);
}
}