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 @@ +