diff --git a/build/AzurePipelineTemplates/CsWinRT-Build-Steps.yml b/build/AzurePipelineTemplates/CsWinRT-Build-Steps.yml
index 17314a9c0..a7f21658b 100644
--- a/build/AzurePipelineTemplates/CsWinRT-Build-Steps.yml
+++ b/build/AzurePipelineTemplates/CsWinRT-Build-Steps.yml
@@ -211,7 +211,7 @@ steps:
condition: and(succeeded(), and(eq(variables['BuildPlatform'], 'x86'), eq(variables['BuildConfiguration'], 'release')))
continueOnError: True
inputs:
- SourceFolder: $(Build.SourcesDirectory)\src\_build\$(BuildPlatform)\$(BuildConfiguration)\cswinrt\bin
+ SourceFolder: $(Build.SourcesDirectory)\src\WinRT.Internal\bin\$(BuildConfiguration)\net10.0-windows10.0.26100.1
Contents: WindowsRuntime.Internal.winmd
TargetFolder: $(StagingFolder)\native
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 14e54d26e..d615e4804 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -52,13 +52,37 @@
0.0.0.0
0.0.0-private.0
+
+
+ 3.0.0.0
$(Platform)
x86
$([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)_build', '$(BuildPlatform)', '$(Configuration)'))
+
+
$([MSBuild]::NormalizeDirectory('$(BuildOutDir)', 'cswinrt', 'bin'))
$([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)_build', 'x86', '$(Configuration)', 'cswinrt', 'bin'))
$(CsWinRTPath)cswinrt.exe
- $(CsWinRTPath)WindowsRuntime.Internal.winmd
+
+
+ net10.0-windows10.0.26100.1
+ $([MSBuild]::NormalizePath('$(MSBuildThisFileDirectory)', 'WinRT.Internal', 'bin', '$(Configuration)', '$(CsWinRTInternalTargetFramework)', 'WindowsRuntime.Internal.winmd'))
diff --git a/src/WinRT.Internal/HWND.cs b/src/WinRT.Internal/HWND.cs
new file mode 100644
index 000000000..5834ac998
--- /dev/null
+++ b/src/WinRT.Internal/HWND.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#pragma warning disable IDE1006
+
+namespace WindowsRuntime.Internal;
+
+///
+/// Windows Runtime metadata representation of the Win32 HWND type.
+///
+///
+/// CsWinRT applies a custom mapping that projects to
+/// in generated C# code, so that interop methods on the runtime classes appear with normal handle
+/// parameters. The field exists only to give the struct a representable layout
+/// in the Windows Runtime type system.
+///
+///
+public struct HWND
+{
+ ///
+ /// Reserved field. Not used by callers: the type is mapped to at the projection layer.
+ ///
+ public int __Reserved;
+}
diff --git a/src/WinRT.Internal/IAccountsSettingsPaneInterop.cs b/src/WinRT.Internal/IAccountsSettingsPaneInterop.cs
new file mode 100644
index 000000000..c41a32fb2
--- /dev/null
+++ b/src/WinRT.Internal/IAccountsSettingsPaneInterop.cs
@@ -0,0 +1,41 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.Foundation;
+using Windows.UI.ApplicationSettings;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for retrieving an bound to a Win32 window.
+///
+///
+/// See accountssettingspaneinterop.idl.
+///
+[ProjectionInternal]
+[Guid("D3EE12AD-3865-4362-9746-B75A682DF0E6")]
+public interface IAccountsSettingsPaneInterop
+{
+ ///
+ /// Gets the associated with the specified window.
+ ///
+ AccountsSettingsPane GetForWindow(
+ HWND appWindow,
+ ref Guid riid);
+
+ ///
+ /// Shows the manage-accounts UI for the specified window.
+ ///
+ IAsyncAction ShowManageAccountsForWindowAsync(
+ HWND appWindow,
+ ref Guid riid);
+
+ ///
+ /// Shows the add-account UI for the specified window.
+ ///
+ IAsyncAction ShowAddAccountForWindowAsync(
+ HWND appWindow,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/IDisplayInformationStaticsInterop.cs b/src/WinRT.Internal/IDisplayInformationStaticsInterop.cs
new file mode 100644
index 000000000..2d3922142
--- /dev/null
+++ b/src/WinRT.Internal/IDisplayInformationStaticsInterop.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.Graphics.Display;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for retrieving bound to a Win32 window or monitor handle.
+///
+///
+/// See WindowsGraphicsDisplayInterop.idl.
+///
+[ProjectionInternal]
+[Guid("7449121C-382B-4705-8DA7-A795BA482013")]
+public interface IDisplayInformationStaticsInterop
+{
+ ///
+ /// Gets the associated with the specified window.
+ ///
+ DisplayInformation GetForWindow(
+ HWND window,
+ ref Guid riid);
+
+ ///
+ /// Gets the associated with the specified monitor.
+ ///
+ DisplayInformation GetForMonitor(
+ HWND monitor,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/IDragDropManagerInterop.cs b/src/WinRT.Internal/IDragDropManagerInterop.cs
new file mode 100644
index 000000000..12cdcb150
--- /dev/null
+++ b/src/WinRT.Internal/IDragDropManagerInterop.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.ApplicationModel.DataTransfer.DragDrop.Core;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for retrieving a bound to a Win32 window.
+///
+///
+/// See dragdropinterop.idl.
+///
+[ProjectionInternal]
+[Guid("5AD8CBA7-4C01-4DAC-9074-827894292D63")]
+public interface IDragDropManagerInterop
+{
+ ///
+ /// Gets the associated with the specified window.
+ ///
+ CoreDragDropManager GetForWindow(
+ HWND hwnd,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/IInputPaneInterop.cs b/src/WinRT.Internal/IInputPaneInterop.cs
new file mode 100644
index 000000000..6a1569a96
--- /dev/null
+++ b/src/WinRT.Internal/IInputPaneInterop.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.UI.ViewManagement;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for retrieving an bound to a Win32 window.
+///
+///
+/// See inputpaneinterop.idl.
+///
+[ProjectionInternal]
+[Guid("75CF2C57-9195-4931-8332-F0B409E916AF")]
+public interface IInputPaneInterop
+{
+ ///
+ /// Gets the associated with the specified window.
+ ///
+ InputPane GetForWindow(
+ HWND appWindow,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/IPlayToManagerInterop.cs b/src/WinRT.Internal/IPlayToManagerInterop.cs
new file mode 100644
index 000000000..f79d9fec2
--- /dev/null
+++ b/src/WinRT.Internal/IPlayToManagerInterop.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.Media.PlayTo;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for retrieving a bound to a Win32 window.
+///
+///
+/// See PlayToManagerInterop.idl.
+///
+[ProjectionInternal]
+[Guid("24394699-1F2C-4EB3-8CD7-0EC1DA42A540")]
+public interface IPlayToManagerInterop
+{
+ ///
+ /// Gets the associated with the specified window.
+ ///
+ PlayToManager GetForWindow(
+ HWND appWindow,
+ ref Guid riid);
+
+ ///
+ /// Shows the Play To UI for the specified window.
+ ///
+ void ShowPlayToUIForWindow(
+ HWND appWindow);
+}
diff --git a/src/WinRT.Internal/IPrintManagerInterop.cs b/src/WinRT.Internal/IPrintManagerInterop.cs
new file mode 100644
index 000000000..9cdbdf9c8
--- /dev/null
+++ b/src/WinRT.Internal/IPrintManagerInterop.cs
@@ -0,0 +1,34 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.Foundation;
+using Windows.Graphics.Printing;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for retrieving a bound to a Win32 window.
+///
+///
+/// See PrintManagerInterop.idl.
+///
+[ProjectionInternal]
+[Guid("C5435A42-8D43-4E7B-A68A-EF311E392087")]
+public interface IPrintManagerInterop
+{
+ ///
+ /// Gets the associated with the specified window.
+ ///
+ PrintManager GetForWindow(
+ HWND appWindow,
+ ref Guid riid);
+
+ ///
+ /// Shows the print UI for the specified window.
+ ///
+ IAsyncOperation ShowPrintUIForWindowAsync(
+ HWND appWindow,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/IRadialControllerConfigurationInterop.cs b/src/WinRT.Internal/IRadialControllerConfigurationInterop.cs
new file mode 100644
index 000000000..5588703c0
--- /dev/null
+++ b/src/WinRT.Internal/IRadialControllerConfigurationInterop.cs
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.UI.Input;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for retrieving a bound to a Win32 window.
+///
+[ProjectionInternal]
+[Guid("787CDAAC-3186-476D-87E4-B9374A7B9970")]
+public interface IRadialControllerConfigurationInterop
+{
+ ///
+ /// Gets the associated with the specified window.
+ ///
+ RadialControllerConfiguration GetForWindow(
+ HWND hwnd,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/IRadialControllerIndependentInputSourceInterop.cs b/src/WinRT.Internal/IRadialControllerIndependentInputSourceInterop.cs
new file mode 100644
index 000000000..c5a6a6a7c
--- /dev/null
+++ b/src/WinRT.Internal/IRadialControllerIndependentInputSourceInterop.cs
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.UI.Input.Core;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for creating a bound to a Win32 window.
+///
+[ProjectionInternal]
+[Guid("3D577EFF-4CEE-11E6-B535-001BDC06AB3B")]
+public interface IRadialControllerIndependentInputSourceInterop
+{
+ ///
+ /// Creates a for the specified window.
+ ///
+ RadialControllerIndependentInputSource CreateForWindow(
+ HWND hwnd,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/IRadialControllerInterop.cs b/src/WinRT.Internal/IRadialControllerInterop.cs
new file mode 100644
index 000000000..88fedd737
--- /dev/null
+++ b/src/WinRT.Internal/IRadialControllerInterop.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.UI.Input;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for creating a bound to a Win32 window.
+///
+///
+/// See RadialControllerInterop.idl.
+///
+[ProjectionInternal]
+[Guid("1B0535C9-57AD-45C1-9D79-AD5C34360513")]
+public interface IRadialControllerInterop
+{
+ ///
+ /// Creates a for the specified window.
+ ///
+ RadialController CreateForWindow(
+ HWND hwnd,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/ISpatialInteractionManagerInterop.cs b/src/WinRT.Internal/ISpatialInteractionManagerInterop.cs
new file mode 100644
index 000000000..1c2c33c0b
--- /dev/null
+++ b/src/WinRT.Internal/ISpatialInteractionManagerInterop.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.UI.Input.Spatial;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for retrieving a bound to a Win32 window.
+///
+///
+/// See SpatialInteractionManagerInterop.idl.
+/// This interop interface is duplicated by IHolographicSpaceInterop, which has the same IID.
+///
+[ProjectionInternal]
+[Guid("5C4EE536-6A98-4B86-A170-587013D6FD4B")]
+public interface ISpatialInteractionManagerInterop
+{
+ ///
+ /// Gets the associated with the specified window.
+ ///
+ SpatialInteractionManager GetForWindow(
+ HWND window,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/ISystemMediaTransportControlsInterop.cs b/src/WinRT.Internal/ISystemMediaTransportControlsInterop.cs
new file mode 100644
index 000000000..9b0592905
--- /dev/null
+++ b/src/WinRT.Internal/ISystemMediaTransportControlsInterop.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.Media;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for retrieving a bound to a Win32 window.
+///
+///
+/// See SystemMediaTransportControlsInterop.idl.
+///
+[ProjectionInternal]
+[Guid("DDB0472D-C911-4A1F-86D9-DC3D71A95F5A")]
+public interface ISystemMediaTransportControlsInterop
+{
+ ///
+ /// Gets the associated with the specified window.
+ ///
+ SystemMediaTransportControls GetForWindow(
+ HWND appWindow,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/IUIViewSettingsInterop.cs b/src/WinRT.Internal/IUIViewSettingsInterop.cs
new file mode 100644
index 000000000..9a186f0d2
--- /dev/null
+++ b/src/WinRT.Internal/IUIViewSettingsInterop.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.UI.ViewManagement;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for retrieving bound to a Win32 window.
+///
+///
+/// See UIViewSettingsInterop.idl.
+///
+[ProjectionInternal]
+[Guid("3694DBF9-8F68-44BE-8FF5-195C98EDE8A6")]
+public interface IUIViewSettingsInterop
+{
+ ///
+ /// Gets the associated with the specified window.
+ ///
+ UIViewSettings GetForWindow(
+ HWND hwnd,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/IUserConsentVerifierInterop.cs b/src/WinRT.Internal/IUserConsentVerifierInterop.cs
new file mode 100644
index 000000000..f14240807
--- /dev/null
+++ b/src/WinRT.Internal/IUserConsentVerifierInterop.cs
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.Foundation;
+using Windows.Security.Credentials.UI;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for requesting user consent verification bound to a Win32 window.
+///
+///
+/// See UserConsentVerifierInterop.idl.
+///
+[ProjectionInternal]
+[Guid("39E050C3-4E74-441A-8DC0-B81104DF949C")]
+public interface IUserConsentVerifierInterop
+{
+ ///
+ /// Asynchronously requests user consent verification for the specified window.
+ ///
+ IAsyncOperation RequestVerificationForWindowAsync(
+ HWND appWindow,
+ string message,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/IWebAuthenticationCoreManagerInterop.cs b/src/WinRT.Internal/IWebAuthenticationCoreManagerInterop.cs
new file mode 100644
index 000000000..35d3cbbb9
--- /dev/null
+++ b/src/WinRT.Internal/IWebAuthenticationCoreManagerInterop.cs
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Runtime.InteropServices;
+using Windows.Foundation;
+using Windows.Security.Authentication.Web.Core;
+using Windows.Security.Credentials;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// COM interop interface for requesting web authentication tokens bound to a Win32 window.
+///
+///
+/// See WebAuthenticationCoreManagerInterop.idl.
+///
+[ProjectionInternal]
+[Guid("F4B8E804-811E-4436-B69C-44CB67B72084")]
+public interface IWebAuthenticationCoreManagerInterop
+{
+ ///
+ /// Asynchronously requests a token for the specified window.
+ ///
+ IAsyncOperation RequestTokenForWindowAsync(
+ HWND appWindow,
+ WebTokenRequest request,
+ ref Guid riid);
+
+ ///
+ /// Asynchronously requests a token for the specified window using the specified web account.
+ ///
+ IAsyncOperation RequestTokenWithWebAccountForWindowAsync(
+ HWND appWindow,
+ WebTokenRequest request,
+ WebAccount webAccount,
+ ref Guid riid);
+}
diff --git a/src/WinRT.Internal/ProjectionInternalAttribute.cs b/src/WinRT.Internal/ProjectionInternalAttribute.cs
new file mode 100644
index 000000000..21980be46
--- /dev/null
+++ b/src/WinRT.Internal/ProjectionInternalAttribute.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+
+namespace WindowsRuntime.Internal;
+
+///
+/// Marks a Windows Runtime interface as having an "internal" projection in CsWinRT.
+///
+///
+///
+/// CsWinRT generates an projection for any interface marked with this attribute
+/// (rather than the default projection). User-friendly wrappers over the internal
+/// projection are exposed via hand-authored extension methods (see e.g. ComInteropExtensions).
+///
+[AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
+public sealed class ProjectionInternalAttribute : Attribute;
diff --git a/src/WinRT.Internal/WinRT.Internal.csproj b/src/WinRT.Internal/WinRT.Internal.csproj
new file mode 100644
index 000000000..791fd5955
--- /dev/null
+++ b/src/WinRT.Internal/WinRT.Internal.csproj
@@ -0,0 +1,162 @@
+
+
+
+
+ net10.0-windows10.0.26100.1
+ 10.0.17763.0
+
+
+ 10.0.26100.85-preview
+
+
+ disable
+
+
+ false
+ false
+ false
+ false
+
+
+ false
+
+
+ $(NoWarn);CS1591;1701;CS1702;NETSDK1229
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_CsWinRTWinMDGenExePath>$([MSBuild]::NormalizePath('$(MSBuildThisFileDirectory)', '..', 'WinRT.WinMD.Generator', 'bin', '$(Configuration)', 'net10.0', 'cswinrtwinmdgen.exe'))
+ <_CsWinRTInternalWinMDOutputPath>$([MSBuild]::NormalizePath('$(TargetDir)', '$(AssemblyName).winmd'))
+ <_CsWinRTInternalWinMDResponseFile>$([MSBuild]::NormalizePath('$(IntermediateOutputPath)', 'cswinrtwinmdgen.rsp'))
+
+
+
+
+ <_CsWinRTInternalWinMDInputAssemblyPath>@(IntermediateAssembly->'%(FullPath)')
+ <_CsWinRTInternalWinMDReferenceAssemblyPaths>@(ReferencePathWithRefAssemblies->'%(FullPath)', ',')
+
+
+
+
+ <_CsWinRTInternalWinMDResponseLines Include="--input-assembly-path $(_CsWinRTInternalWinMDInputAssemblyPath)" />
+ <_CsWinRTInternalWinMDResponseLines Include="--reference-assembly-paths $(_CsWinRTInternalWinMDReferenceAssemblyPaths)" />
+ <_CsWinRTInternalWinMDResponseLines Include="--output-winmd-path $(_CsWinRTInternalWinMDOutputPath)" />
+ <_CsWinRTInternalWinMDResponseLines Include="--assembly-version $(AssemblyVersion)" />
+ <_CsWinRTInternalWinMDResponseLines Include="--use-windows-ui-xaml-projections false" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/WinRT.WinMD.Generator/References/WinMDValues.cs b/src/WinRT.WinMD.Generator/References/WinMDValues.cs
index f81936a04..844e65db0 100644
--- a/src/WinRT.WinMD.Generator/References/WinMDValues.cs
+++ b/src/WinRT.WinMD.Generator/References/WinMDValues.cs
@@ -19,4 +19,11 @@ internal static class WinMDValues
/// Gets the version of the mscorlib reference for .winmd files.
///
public static Version MSCorLibVersion { get; } = new(0xFF, 0xFF, 0xFF, 0xFF);
+
+ ///
+ /// Gets the assembly version stamped onto every authored .winmd, matching
+ /// the Windows Runtime convention of 255.255.255.255 (the "unbound"
+ /// version used by all Windows Runtime metadata).
+ ///
+ public static Version AssemblyVersion { get; } = new(0xFF, 0xFF, 0xFF, 0xFF);
}
\ No newline at end of file
diff --git a/src/WinRT.WinMD.Generator/Writers/WinMDWriter.Members.cs b/src/WinRT.WinMD.Generator/Writers/WinMDWriter.Members.cs
index 328fda948..283f6ef41 100644
--- a/src/WinRT.WinMD.Generator/Writers/WinMDWriter.Members.cs
+++ b/src/WinRT.WinMD.Generator/Writers/WinMDWriter.Members.cs
@@ -125,12 +125,23 @@ private void AddMethodToClass(TypeDefinition outputType, MethodDefinition inputM
///
/// Adds parameter definitions to an output method with correct Windows Runtime attributes.
- /// Handles Span/ReadOnlySpan → array parameter attribute mapping:
- /// - ReadOnlySpan<T> → [in] T[] (PassArray)
- /// - Span<T> → [out] T[] without BYREF (FillArray)
- /// - out T[] → [out] T[] with BYREF (ReceiveArray)
- /// - All other params → [in]
///
+ ///
+ ///
+ /// The In/Out flags on the input parameters are honored as-is when present. This allows
+ /// authors to opt-in or opt-out of the WinRT defaults explicitly (e.g. [In] ref T
+ /// preserves the In flag, [Out] ref T preserves the Out flag). When
+ /// no In/Out flag is set on the input parameter, the WinRT default is inferred from the
+ /// parameter type:
+ ///
+ ///
+ /// - → [in] T[] (PassArray)
+ /// - → [out] T[] without BYREF (FillArray)
+ /// - out T[] (byref to SzArray) → [out] T[] with BYREF (ReceiveArray); already captured by the input's Out flag.
+ /// - Any other by-reference type (e.g. ref Guid on a COM interop interface) → [in], matching the MIDL convention for ref const T parameters.
+ /// - All other params → [in].
+ ///
+ ///
private static void AddParameterDefinitions(MethodDefinition outputMethod, MethodDefinition inputMethod)
{
int paramIndex = 1;
@@ -143,7 +154,7 @@ private static void AddParameterDefinitions(MethodDefinition outputMethod, Metho
if (sigIndex < inputParamTypes.Count)
{
- paramattributes = GetWinRTParameterAttributes(inputParamTypes[sigIndex]);
+ paramattributes = GetWinRTParameterAttributes(inputParam, inputParamTypes[sigIndex]);
}
outputMethod.ParameterDefinitions.Add(new ParameterDefinition(
@@ -154,28 +165,33 @@ private static void AddParameterDefinitions(MethodDefinition outputMethod, Metho
}
///
- /// Determines the Windows Runtime parameter attributes based on the input parameter type.
+ /// Determines the Windows Runtime parameter attributes based on the input parameter and its type.
///
- private static ParameterAttributes GetWinRTParameterAttributes(TypeSignature inputParamType)
+ ///
+ /// If the input parameter already has or
+ /// set, those flags are preserved unchanged. Otherwise,
+ /// the type drives the default per the rules documented on .
+ ///
+ private static ParameterAttributes GetWinRTParameterAttributes(ParameterDefinition inputParam, TypeSignature inputParamType)
{
- // out parameters (ByRef) stay as Out
- if (inputParamType is ByReferenceTypeSignature)
+ // Preserve any 'In'/'Out' direction flags the input parameter already carries
+ ParameterAttributes inputDirectionFlags = inputParam.Attributes & (ParameterAttributes.In | ParameterAttributes.Out);
+
+ if (inputDirectionFlags != 0)
{
- return ParameterAttributes.Out;
+ return inputDirectionFlags;
}
- // Span → FillArray pattern: [out] without BYREF
- if (inputParamType is GenericInstanceTypeSignature genericInstanceSignature)
+ // 'Span' → 'FillArray' pattern: '[out]' without 'BYREF'
+ if (inputParamType is GenericInstanceTypeSignature genericInstanceSignature &&
+ genericInstanceSignature.GenericType.FullName == "System.Span`1")
{
- string typeName = genericInstanceSignature.GenericType.FullName;
-
- if (typeName == "System.Span`1")
- {
- return ParameterAttributes.Out;
- }
+ return ParameterAttributes.Out;
}
- // ReadOnlySpan and everything else → [in]
+ // By-reference parameters with no explicit direction flag (e.g. 'ref Guid riid'
+ // on a COM interop interface) default to '[in]', matching the MIDL convention for
+ // 'ref const T' parameters. 'ReadOnlySpan' and everything else also default to '[in]'.
return ParameterAttributes.In;
}
diff --git a/src/WinRT.WinMD.Generator/Writers/WinMDWriter.Types.cs b/src/WinRT.WinMD.Generator/Writers/WinMDWriter.Types.cs
index 6a0541599..15854de6b 100644
--- a/src/WinRT.WinMD.Generator/Writers/WinMDWriter.Types.cs
+++ b/src/WinRT.WinMD.Generator/Writers/WinMDWriter.Types.cs
@@ -712,8 +712,8 @@ private void AddExplicitInterfaceImplementations(TypeDefinition inputType, TypeD
for (int i = 0; i < paramNames.Length; i++)
{
- ParameterAttributes paramAttr = i < parameterTypes.Length
- ? GetWinRTParameterAttributes(method.Signature!.ParameterTypes[i])
+ ParameterAttributes paramAttr = i < parameterTypes.Length && i < method.ParameterDefinitions.Count
+ ? GetWinRTParameterAttributes(method.ParameterDefinitions[i], method.Signature!.ParameterTypes[i])
: ParameterAttributes.In;
outputMethod.ParameterDefinitions.Add(new ParameterDefinition(
diff --git a/src/WinRT.WinMD.Generator/Writers/WinMDWriter.cs b/src/WinRT.WinMD.Generator/Writers/WinMDWriter.cs
index 3de9dc331..bd6ee8f52 100644
--- a/src/WinRT.WinMD.Generator/Writers/WinMDWriter.cs
+++ b/src/WinRT.WinMD.Generator/Writers/WinMDWriter.cs
@@ -110,8 +110,11 @@ public WinMDWriter(
_assemblyReferenceCache["mscorlib"] = defaultCorLib;
- // Create the output assembly with WindowsRuntime flag (keep reference alive via module)
- _ = new AssemblyDefinition(assemblyName, new Version(version))
+ // Create the output assembly with 'WindowsRuntime' flag (keep reference alive via module).
+ // Per Windows Runtime convention, the assembly identity always uses version '255.255.255.255'
+ // (the "unbound" version). The 'version' parameter is only used for the type-level
+ // '[Windows.Foundation.Metadata.Version]' attribute applied to each authored type.
+ _ = new AssemblyDefinition(assemblyName, WinMDValues.AssemblyVersion)
{
Modules = { _outputModule },
Attributes = AssemblyAttributes.ContentWindowsRuntime,
diff --git a/src/build.cmd b/src/build.cmd
index 983e22e47..e37bb39a6 100644
--- a/src/build.cmd
+++ b/src/build.cmd
@@ -251,7 +251,7 @@ if "%cswinrt_label%"=="functionaltest" exit /b 0
rem We set the properties of the CsWinRT.nuspec here, and pass them as the -Properties option when we call `nuget pack`
set cswinrt_bin_dir=%this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\cswinrt\bin\
set cswinrt_exe=%cswinrt_bin_dir%cswinrt.exe
-set interop_winmd=%cswinrt_bin_dir%WindowsRuntime.Internal.winmd
+set interop_winmd=%this_dir%WinRT.Internal\bin\%cswinrt_configuration%\net10.0-windows10.0.26100.1\WindowsRuntime.Internal.winmd
set net10_runtime=%this_dir%WinRT.Runtime2\bin\%cswinrt_configuration%\net10.0\WinRT.Runtime.dll
set net10_runtime_xml=%this_dir%WinRT.Runtime2\bin\%cswinrt_configuration%\net10.0\WinRT.Runtime.xml
set source_generator_roslyn4120=%this_dir%Authoring\WinRT.SourceGenerator.Roslyn4120\bin\%cswinrt_configuration%\netstandard2.0\WinRT.SourceGenerator.dll
diff --git a/src/cswinrt.slnx b/src/cswinrt.slnx
index 8416f9f3e..721a971c1 100644
--- a/src/cswinrt.slnx
+++ b/src/cswinrt.slnx
@@ -425,6 +425,7 @@
+