Skip to content

Commit ef7b0fc

Browse files
authored
Move WinRT usage in PresentationFramework to use modified C#/WinRT source embedded in. (#3094)
Port InputPane away from using System.Runtime.InteropServices.WindowsRuntime. Do a platform check before trying to access the WinRT apis. Remove the MS.Internal.WindowsRuntime. prefix when creating the activation factory. Refactor the namespace prefix removal and also apply it to GuidGenerator. Fix typo. Start handling specific runtime class names for WPF. Remove event handler support since none of the projected code uses event handlers. Remove some of the unused projected types. Remove temp file that accidentally got committed. Remove more unused types from the Windows.Data.Text projection. Remove unused IWeakReferenceSource support. Add license headers. PR Feedback. Add explicit calling convention. Be more careful with checking exceptions from RoGetActivationFactory and cover more specific HResults to ensure that we fall back gracefully.
1 parent 21e4b0e commit ef7b0fc

34 files changed

+7530
-707
lines changed

src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/WindowsRuntime/Windows/UI/ViewManagement/InputPane.cs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
using System.IO;
1111
using System.Reflection;
1212
using System.Runtime.InteropServices;
13-
using System.Runtime.InteropServices.WindowsRuntime;
1413
using System.Security;
1514
using System.Windows;
1615
using System.Windows.Interop;
@@ -33,19 +32,15 @@ internal class InputPane : IDisposable
3332
#region Fields
3433

3534
/// <summary>
36-
/// The name of the InputPane WinRT runtime class
35+
/// Bool to check if the WinRT input pane is supported
3736
/// </summary>
38-
private static readonly string s_TypeName = "Windows.UI.ViewManagement.InputPane, Windows, ContentType=WindowsRuntime";
37+
private static readonly bool _isSupported;
3938

40-
/// <summary>
41-
/// The InputPane Type
42-
/// </summary>
43-
private static Type s_WinRTType;
4439

4540
/// <summary>
4641
/// Activation factory to instantiate InputPane RCWs
4742
/// </summary>
48-
private static IActivationFactory _winRtActivationFactory;
43+
private static object _winRtActivationFactory;
4944

5045
/// <summary>
5146
/// The appropriate RCW for calling TryShow/Hide
@@ -65,18 +60,17 @@ static InputPane()
6560
// We don't want to throw here - so wrap in try..catch
6661
try
6762
{
68-
s_WinRTType = Type.GetType(s_TypeName);
69-
7063
// If we cannot get a new activation factory, then we cannot support
7164
// this platform. As such, null out the type to guard instantiations.
7265
if (GetWinRtActivationFactory(forceInitialization: true) == null)
7366
{
74-
s_WinRTType = null;
67+
_isSupported = false;
7568
}
69+
_isSupported = true;
7670
}
7771
catch
7872
{
79-
s_WinRTType = null;
73+
_isSupported = false;
8074
}
8175
}
8276

@@ -86,7 +80,7 @@ static InputPane()
8680
/// <exception cref="PlatformNotSupportedException"></exception>
8781
private InputPane(IntPtr? hwnd)
8882
{
89-
if (s_WinRTType == null)
83+
if (!_isSupported)
9084
{
9185
throw new PlatformNotSupportedException();
9286
}
@@ -196,23 +190,30 @@ internal bool TryHide()
196190
/// <param name="forceInitialization">If true, will create a new IActivationFactory. If false will
197191
/// only create a new IActivationFactory if there is no valid cached instance available.</param>
198192
/// <returns>An IActivationFactory of InputPane or null if it fails to instantiate.</returns>
199-
private static IActivationFactory GetWinRtActivationFactory(bool forceInitialization = false)
193+
private static object GetWinRtActivationFactory(bool forceInitialization = false)
200194
{
201195
if (forceInitialization || _winRtActivationFactory == null)
202196
{
203197
try
204198
{
205-
_winRtActivationFactory = WindowsRuntimeMarshal.GetActivationFactory(s_WinRTType);
199+
_winRtActivationFactory = InputPaneRcw.GetInputPaneActivationFactory();
206200
}
207-
catch (Exception e) when (e is TypeLoadException || e is FileNotFoundException)
201+
catch (Exception e) when (e is TypeLoadException
202+
|| e is FileNotFoundException
203+
|| e is EntryPointNotFoundException
204+
|| e is DllNotFoundException
205+
|| e.HResult == NativeMethods.E_NOINTERFACE
206+
|| e.HResult == NativeMethods.REGDB_E_CLASSNOTREG)
208207
{
209-
// Catch the set of exceptions that are considered activation exceptions as per the public
210-
// contract on WindowsRuntimeMarshal.GetActivationFactory.
208+
// Catch the set of exceptions that are considered activation exceptions,
209+
// as well as exception with HResults that can be returned from DllGetActivationFactory when it fails.
211210
// <see cref="https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.windowsruntime.windowsruntimemarshal.getactivationfactory(v=vs.110).aspx"/>
212211
// On some Windows SKUs, notably ServerCore, a failing static dependency in InputPane seems to cause a
213212
// FileNotFoundException during acquisition of the activation factory. We explicitly catch this exception
214213
// here to alleviate this issue. This is not an ideal solution to the platform bug, but keeps WPF applications
215214
// from being exposed to the issue.
215+
216+
// We also catch an EntryPointNotFoundException and DllNotFoundExceptions for when WinRT isn't supported on the platform.
216217
_winRtActivationFactory = null;
217218
}
218219
}

src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/WindowsRuntime/Windows/UI/ViewManagement/InputPaneRcw.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,25 @@ namespace Windows.UI.ViewManagement
1919
/// </summary>
2020
internal static class InputPaneRcw
2121
{
22+
private static readonly Guid IID_IActivationFactory = Guid.Parse("00000035-0000-0000-C000-000000000046");
23+
24+
public static object GetInputPaneActivationFactory()
25+
{
26+
const string typeName = "Windows.UI.ViewManagement.InputPane";
27+
IntPtr hstring = IntPtr.Zero;
28+
Marshal.ThrowExceptionForHR(NativeMethods.WindowsCreateString(typeName, typeName.Length, out hstring));
29+
try
30+
{
31+
Guid iid = IID_IActivationFactory;
32+
Marshal.ThrowExceptionForHR(NativeMethods.RoGetActivationFactory(hstring, ref iid, out object factory));
33+
return factory;
34+
}
35+
finally
36+
{
37+
Marshal.ThrowExceptionForHR(NativeMethods.WindowsDeleteString(hstring));
38+
}
39+
}
40+
2241
internal enum TrustLevel
2342
{
2443
BaseTrust,
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
//
6+
//
7+
8+
using System;
9+
using System.Runtime.CompilerServices;
10+
using System.Runtime.InteropServices;
11+
using System.Security;
12+
using MS.Internal.PresentationCore;
13+
14+
namespace MS.Internal.WindowsRuntime
15+
{
16+
namespace Windows.UI.ViewManagement
17+
{
18+
/// <summary>
19+
/// Contains internal RCWs for invoking the InputPane (tiptsf touch keyboard)
20+
/// </summary>
21+
internal static class NativeMethods
22+
{
23+
[DllImport(DllImport.ApiSetWinRTString, CallingConvention = CallingConvention.StdCall)]
24+
internal static extern unsafe int WindowsCreateString([MarshalAs(UnmanagedType.LPWStr)] string sourceString,
25+
int length,
26+
out IntPtr hstring);
27+
28+
[DllImport(DllImport.ApiSetWinRTString, CallingConvention = CallingConvention.StdCall)]
29+
internal static extern int WindowsDeleteString(IntPtr hstring);
30+
31+
[DllImport(DllImport.ApiSetWinRT, CallingConvention = CallingConvention.StdCall)]
32+
internal static extern unsafe int RoGetActivationFactory(IntPtr runtimeClassId, ref Guid iid, [MarshalAs(UnmanagedType.Interface)] out object factory);
33+
34+
internal const int E_NOINTERFACE = unchecked((int)0x80004002);
35+
36+
internal const int REGDB_E_CLASSNOTREG = unchecked((int)0x80040154);
37+
}
38+
}
39+
}

src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@
295295
<Compile Include="MS\Internal\TextFormatting\ThousandthOfEmRealPoints.cs" />
296296
<Compile Include="MS\Internal\WindowsRuntime\Windows\UI\ViewManagement\InputPane.cs" />
297297
<Compile Include="MS\Internal\WindowsRuntime\Windows\UI\ViewManagement\InputPaneRcw.cs" />
298+
<Compile Include="MS\Internal\WindowsRuntime\Windows\UI\ViewManagement\NativeMethods.cs" />
298299
<Compile Include="MS\Win32\UnsafeNativeMethodsPenimc.cs" />
299300
<Compile Include="MS\Win32\UnsafeNativeMethodsPointer.cs" />
300301
<Compile Include="MS\Win32\UnsafeNativeMethodsTablet.cs" />
@@ -1390,7 +1391,6 @@
13901391
<NetCoreReference Include="System.Resources.ResourceManager" />
13911392
<NetCoreReference Include="System.Runtime.CompilerServices.VisualC" />
13921393
<NetCoreReference Include="System.Runtime.Extensions" />
1393-
<NetCoreReference Include="System.Runtime.InteropServices.WindowsRuntime" />
13941394
<NetCoreReference Include="System.Runtime.InteropServices" />
13951395
<NetCoreReference Include="System.Runtime.Serialization.Formatters" />
13961396
<NetCoreReference Include="System.Threading" />

src/Microsoft.DotNet.Wpf/src/PresentationCore/ref/PresentationCore-ref.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
<NetCoreReference Include="System.Resources.ResourceManager" />
5050
<NetCoreReference Include="System.Runtime.CompilerServices.VisualC" />
5151
<NetCoreReference Include="System.Runtime.Extensions" />
52-
<NetCoreReference Include="System.Runtime.InteropServices.WindowsRuntime" />
5352
<NetCoreReference Include="System.Runtime.InteropServices" />
5453
<NetCoreReference Include="System.Runtime.Serialization.Formatters" />
5554
<NetCoreReference Include="System.Threading" />

0 commit comments

Comments
 (0)