From b782a2392f385916786ecde29ce949fda3a7a8d8 Mon Sep 17 00:00:00 2001 From: ionoy Date: Tue, 15 Aug 2017 12:21:24 +0300 Subject: [PATCH] fixed UWP (Xamarin Forms) crash on startup --- Ammy.Tests.sln | 26 +----- build/{1.2.77.version => 1.2.83.version} | 0 build/ammy-host.nuspec | 2 +- build/ammy-uwp.nuspec | 4 +- build/ammy-wpf.nuspec | 4 +- build/ammy-xamarinforms.nuspec | 4 +- build/ammy.nuspec | 2 +- release-notes.md | 4 +- .../ExpressionBuilder.cs | 8 ++ .../Ammy.Sidekick.XamarinForms/KnownTypes.cs | 93 ++++++++++++++++--- 10 files changed, 100 insertions(+), 47 deletions(-) rename build/{1.2.77.version => 1.2.83.version} (100%) diff --git a/Ammy.Tests.sln b/Ammy.Tests.sln index ef606e5..362a73a 100644 --- a/Ammy.Tests.sln +++ b/Ammy.Tests.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26403.3 +VisualStudioVersion = 15.0.26430.15 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ammy.Test.Wpf", "test\Ammy.Test.Wpf\Ammy.Test.Wpf.csproj", "{1E37D588-ECDB-48A0-9658-9DF5BA5F5AC1}" EndProject @@ -9,8 +9,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ammy.Test.Workbench", "test EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ammy.Test.Host", "test\Ammy.Test.Host\Ammy.Test.Host.csproj", "{6157E904-A45F-45C6-BC79-D57C284318DA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ammy.Test.Uwp", "test\Ammy.Test.Uwp\Ammy.Test.Uwp.csproj", "{98301D94-7BBC-4953-B66F-EC761EF2EFBA}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AmmysStackExchangeAggregator", "src\Samples\AmmysStackExchangeAggregator\AmmysStackExchangeAggregator.csproj", "{B9CD4210-E8E4-463E-9CD0-93A63E84D6AB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataGridSample", "src\Samples\DataGridSample\DataGridSample.csproj", "{5B915277-BF63-4431-B1DC-C094158E2BC2}" @@ -77,28 +75,6 @@ Global {6157E904-A45F-45C6-BC79-D57C284318DA}.Release|x64.Build.0 = Release|Any CPU {6157E904-A45F-45C6-BC79-D57C284318DA}.Release|x86.ActiveCfg = Release|Any CPU {6157E904-A45F-45C6-BC79-D57C284318DA}.Release|x86.Build.0 = Release|Any CPU - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Debug|Any CPU.ActiveCfg = Debug|x86 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Debug|Any CPU.Build.0 = Debug|x86 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Debug|Any CPU.Deploy.0 = Debug|x86 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Debug|ARM.ActiveCfg = Debug|ARM - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Debug|ARM.Build.0 = Debug|ARM - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Debug|ARM.Deploy.0 = Debug|ARM - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Debug|x64.ActiveCfg = Debug|x64 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Debug|x64.Build.0 = Debug|x64 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Debug|x64.Deploy.0 = Debug|x64 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Debug|x86.ActiveCfg = Debug|x86 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Debug|x86.Build.0 = Debug|x86 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Debug|x86.Deploy.0 = Debug|x86 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Release|Any CPU.ActiveCfg = Release|x86 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Release|ARM.ActiveCfg = Release|ARM - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Release|ARM.Build.0 = Release|ARM - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Release|ARM.Deploy.0 = Release|ARM - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Release|x64.ActiveCfg = Release|x64 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Release|x64.Build.0 = Release|x64 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Release|x64.Deploy.0 = Release|x64 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Release|x86.ActiveCfg = Release|x86 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Release|x86.Build.0 = Release|x86 - {98301D94-7BBC-4953-B66F-EC761EF2EFBA}.Release|x86.Deploy.0 = Release|x86 {B9CD4210-E8E4-463E-9CD0-93A63E84D6AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B9CD4210-E8E4-463E-9CD0-93A63E84D6AB}.Debug|Any CPU.Build.0 = Debug|Any CPU {B9CD4210-E8E4-463E-9CD0-93A63E84D6AB}.Debug|ARM.ActiveCfg = Debug|Any CPU diff --git a/build/1.2.77.version b/build/1.2.83.version similarity index 100% rename from build/1.2.77.version rename to build/1.2.83.version diff --git a/build/ammy-host.nuspec b/build/ammy-host.nuspec index a2343d7..d260766 100644 --- a/build/ammy-host.nuspec +++ b/build/ammy-host.nuspec @@ -2,7 +2,7 @@ Ammy.Host - 1.2.77 + 1.2.83 Ion OÜ Ion OÜ https://creativecommons.org/licenses/by-nc/3.0/ diff --git a/build/ammy-uwp.nuspec b/build/ammy-uwp.nuspec index 83ba8a2..3869437 100644 --- a/build/ammy-uwp.nuspec +++ b/build/ammy-uwp.nuspec @@ -2,7 +2,7 @@ Ammy.UWP - 1.2.77 + 1.2.83 Ion OÜ Ion OÜ https://creativecommons.org/licenses/by-nc/3.0/ @@ -13,7 +13,7 @@ Copyright 2017 xaml uwp - + diff --git a/build/ammy-wpf.nuspec b/build/ammy-wpf.nuspec index dce0a69..f8f4cf9 100644 --- a/build/ammy-wpf.nuspec +++ b/build/ammy-wpf.nuspec @@ -2,7 +2,7 @@ Ammy.WPF - 1.2.77 + 1.2.83 Ion OÜ Ion OÜ https://creativecommons.org/licenses/by-nc/3.0/ @@ -13,7 +13,7 @@ Copyright 2017 xaml wpf - + diff --git a/build/ammy-xamarinforms.nuspec b/build/ammy-xamarinforms.nuspec index ce8b62c..786378d 100644 --- a/build/ammy-xamarinforms.nuspec +++ b/build/ammy-xamarinforms.nuspec @@ -2,7 +2,7 @@ Ammy.XamarinForms - 1.2.77 + 1.2.83 Ion OÜ Ion OÜ https://creativecommons.org/licenses/by-nc/3.0/ @@ -13,7 +13,7 @@ Copyright 2017 xaml xamarin - + diff --git a/build/ammy.nuspec b/build/ammy.nuspec index d33f9ca..9d9c743 100644 --- a/build/ammy.nuspec +++ b/build/ammy.nuspec @@ -2,7 +2,7 @@ Ammy - 1.2.77 + 1.2.83 Ion OÜ Ion OÜ https://creativecommons.org/licenses/by-nc/3.0/ diff --git a/release-notes.md b/release-notes.md index 9bd8b54..a095b3b 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,6 +1,6 @@ -## +## [1.2.83] - 14.06.2017 -* fixed bug #91 (combine not working) +* Fixed UWP startup crash issue for Xamarin Forms ## [1.2.74] - 14.06.2017 diff --git a/src/Platforms/Ammy.Sidekick.XamarinForms/ExpressionBuilder.cs b/src/Platforms/Ammy.Sidekick.XamarinForms/ExpressionBuilder.cs index 773440f..1ef82e6 100644 --- a/src/Platforms/Ammy.Sidekick.XamarinForms/ExpressionBuilder.cs +++ b/src/Platforms/Ammy.Sidekick.XamarinForms/ExpressionBuilder.cs @@ -503,10 +503,18 @@ public static class ReflectionExtensions { public static MethodInfo GetMethod(this Type type, string name, bool isInstance, Type[] parameterTypes = null) { + // Search for public methods only var method = type.GetTypeInfo() .GetDeclaredMethods(name) .FirstOrDefault(mi => mi.IsPublic && (isInstance ? !mi.IsStatic : mi.IsStatic) && HasMatchingParameterTypes(mi, parameterTypes)); + // Search for any methods + if (method == null) { + method = type.GetTypeInfo() + .GetDeclaredMethods(name) + .FirstOrDefault(mi => isInstance ? !mi.IsStatic : mi.IsStatic && HasMatchingParameterTypes(mi, parameterTypes)); + } + if (method == null) throw new Exception("Method `" + name + "` on type `" + type.Name + "` not found"); diff --git a/src/Platforms/Ammy.Sidekick.XamarinForms/KnownTypes.cs b/src/Platforms/Ammy.Sidekick.XamarinForms/KnownTypes.cs index 523981d..b362cde 100644 --- a/src/Platforms/Ammy.Sidekick.XamarinForms/KnownTypes.cs +++ b/src/Platforms/Ammy.Sidekick.XamarinForms/KnownTypes.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; +using Xamarin.Forms; namespace AmmySidekick { @@ -12,32 +14,99 @@ public static class KnownTypes static KnownTypes() { - Assemblies = GetAssemblies(); + try { + Assemblies = GetAssemblies(); + } catch { + Debug.WriteLine("Failed to load assemblies"); + + Assemblies = new Assembly[] { + typeof(Element).GetTypeInfo().Assembly, + typeof(string).GetTypeInfo().Assembly + }; + } } - public static Type FindType() + public static Tuple FindShortTypeWithProperty(string typeName, string property) { - return typeof(T); + EnsureTypesLoaded(); + + foreach (var kvp in TypesByFullName) { + if (kvp.Key.EndsWith("." + typeName)) { + var foundProperty = FindBindablePropertyField(kvp.Value, property); + if (foundProperty != null) + return Tuple.Create(kvp.Value, foundProperty); + } + } + + return null; } public static Type FindType(string typeName) { - if (TypesByFullName.Count == 0) - { + EnsureTypesLoaded(); + + Type ret; + if (TypesByFullName.TryGetValue(typeName, out ret)) + return ret; + + // If searching assemblies failed, try to resolve type manually + return ManualFindType(typeName); + } + + private static void EnsureTypesLoaded() + { + if (TypesByFullName.Count == 0) { var allTypes = Assemblies.Where(a => a != null) .SelectMany(a => a.DefinedTypes); foreach (var type in allTypes) TypesByFullName[type.FullName] = type.AsType(); } + } - Type ret; - if (TypesByFullName.TryGetValue(typeName, out ret)) return ret; + private static Type ManualFindType(string typeName) + { + var uwpNetAssemblies = new[] { + "System.Net.Sockets, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", + "System.Net.Sockets, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", + "System.Net.Primitives, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", + "System.Net.Primitives, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", + "System.Net.Primitives, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", + }; + + if (string.IsNullOrWhiteSpace(typeName)) + throw new InvalidOperationException("Type name shouldn't be empty or null"); + + if (typeName.StartsWith("System.Net", StringComparison.OrdinalIgnoreCase)) { + foreach (var netAssembly in uwpNetAssemblies) { + try { + var type = Type.GetType(typeName + ", " + netAssembly); + if (type != null) + return type; + } catch { + // do nothing if load failed + } + } + } + + return null; + } + + public static FieldInfo FindBindablePropertyField(Type type, string propertyName) + { + var typeInfo = type.GetTypeInfo(); + + foreach (var declaredField in typeInfo.DeclaredFields) + if (declaredField.IsStatic && declaredField.Name == propertyName + "Property") + return declaredField; + + if (typeInfo.BaseType == null) + return null; - throw new InvalidOperationException("Couldn't find type: " + typeName); + return FindBindablePropertyField(typeInfo.BaseType, propertyName); } - public static ConstructorInfo GetConstructor(Type type, Type[] parameters) + public static ConstructorInfo GetConstructor(Type type, params Type[] parameters) { var ctor = type.GetConstructors() .FirstOrDefault(ci => { @@ -49,8 +118,8 @@ public static ConstructorInfo GetConstructor(Type type, Type[] parameters) }); if (ctor == null) - throw new InvalidOperationException("Couldn't find constructor for " + type + - " with parameters: " + + throw new InvalidOperationException("Couldn't find constructor for " + type + + " with parameters: " + string.Join(", ", parameters.Select(t => t.Name))); return ctor; @@ -63,7 +132,7 @@ private static Assembly[] GetAssemblies() var type = assembly.GetType("System.AppDomain"); var currentDomainProp = type.GetRuntimeProperty("CurrentDomain"); var getMethod = currentDomainProp.GetMethod; - var currentdomain = getMethod.Invoke(null, new object[] {}); + var currentdomain = getMethod.Invoke(null, new object[] { }); var getassemblies = currentdomain.GetType().GetRuntimeMethod("GetAssemblies", new Type[] { }); return getassemblies.Invoke(currentdomain, new object[] { }) as Assembly[]; }