Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
93fc33c
Add MSBuild target for stub .exe-s
Sergio0694 Jan 11, 2025
3faa5ae
Tweak stub .exe creation
Sergio0694 Jan 12, 2025
01e38c0
Automatically enable stub .exe creation
Sergio0694 Jan 12, 2025
bb97375
Update Microsoft.Windows.CsWinRT.nuspec
Sergio0694 Jan 12, 2025
f63a977
Use 'cl.exe' path from Native AOT
Sergio0694 Jan 12, 2025
00e4ed0
Improve MSVC args handling
Sergio0694 Jan 12, 2025
5cb2852
Dynamically link UCRT, remove unsafe options
Sergio0694 Jan 12, 2025
729d7de
Add more options (CFG, CET, etc.)
Sergio0694 Jan 12, 2025
51c1a5b
Fix linker warning for UCRT
Sergio0694 Jan 13, 2025
c0f65b5
Fix ordering for stub .exe target
Sergio0694 Jan 13, 2025
aa3a893
Remove relative paths
Sergio0694 Jan 13, 2025
75fe71d
Add stub .exe to 'ResolvedFileToPublish'
Sergio0694 Jan 13, 2025
95d92d7
Fix entry point for 'WinExe' projects
Sergio0694 Jan 13, 2025
5c09485
Tweak output folder for stub .exe
Sergio0694 Jan 13, 2025
9441727
Fix build errors in native exports
Sergio0694 Jan 14, 2025
e854801
Fix '_CsWinRTGenerateStubExe' condition
Sergio0694 Jan 14, 2025
34cca2d
Add 'CsWinRTUseEnvironmentalTools' property
Sergio0694 Jan 14, 2025
eeed7ad
Remove unnecessary leading spaces
Sergio0694 Jan 14, 2025
13c8ecb
Document 'CsWinRTUseEnvironmentalTools'
Sergio0694 Jan 14, 2025
373c4da
Fix stub .exe outside of VS Dev Command Prompt
Sergio0694 Jan 15, 2025
8af23ef
Move stub .exe to packaged source file
Sergio0694 Jan 17, 2025
c6caaca
Don't exclude 'StubExe.c' from git
Sergio0694 Jan 17, 2025
13ac7d3
Use environment tools automatically if available
Sergio0694 Jan 20, 2025
7545b95
Handle debug libs
Sergio0694 Jan 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*_i.c
*_p.c
*.c
!nuget/sources/*.c
*.winmd
*test*.xml
obj
Expand Down
27 changes: 27 additions & 0 deletions nuget/Microsoft.Windows.CsWinRT.BeforeMicrosoftNetSdk.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!--
***********************************************************************************************
Copyright (C) Microsoft Corporation. All rights reserved.
***********************************************************************************************
-->
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>

<!-- We need to set the final value of this property here, as if that's set, we need to do additional work before the .NET SDK .targets -->
<CsWinRTMergeReferencedActivationFactories Condition="'$(CsWinRTMergeReferencedActivationFactories)' == ''">false</CsWinRTMergeReferencedActivationFactories>
</PropertyGroup>

<!--
If we need to merge activation factories and the project is an executable, we need to emit a stub .exe,
so in order to do that we need to tell the .NET SDK to export a custom main, and compile to a .dll instead.
These two properties have to be set before the Native AOT toolchain runs, that's why it's done from here.
-->
<PropertyGroup Condition="'$(CsWinRTMergeReferencedActivationFactories)' == 'true' AND ('$(OutputType)' == 'Exe' OR '$(OutputType)' == 'WinExe')">
<NativeLib>Shared</NativeLib>
<CustomNativeMain>true</CustomNativeMain>

<!-- Activate our custom target to produce the stub .exe after the publish step -->
<_CsWinRTEnableStubExeGeneration>true</_CsWinRTEnableStubExeGeneration>
</PropertyGroup>

</Project>
5 changes: 4 additions & 1 deletion nuget/Microsoft.Windows.CsWinRT.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<file src="NOTICE.txt"/>
<file src="$cswinrt_exe$"/>
<file src="Microsoft.Windows.CsWinRT.props" target="build"/>
<file src="Microsoft.Windows.CsWinRT.BeforeMicrosoftNetSdk.targets" target="build"/>
<file src="Microsoft.Windows.CsWinRT.targets" target="build"/>
<file src="Microsoft.Windows.CsWinRT.Authoring.targets" target="build"/>
<file src="Microsoft.Windows.CsWinRT.Embedded.targets" target="build"/>
Expand Down Expand Up @@ -68,6 +69,8 @@

<file src="..\src\WinRT.Runtime\Configuration\*.cs" exclude="..\src\WinRT.Runtime\Configuration\*.net*.cs" target="embedded\any\" />

<file src="$guid_patch$" target ="build\tools\IIDOptimizer"/>
<file src="sources\StubExe.c" target="build\sources"/>

<file src="$guid_patch$" target="build\tools\IIDOptimizer"/>
</files>
</package>
3 changes: 3 additions & 0 deletions nuget/Microsoft.Windows.CsWinRT.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<PropertyGroup>
<CsWinRTPath Condition="'$(CsWinRTPath)'==''">$([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', '..'))</CsWinRTPath>
<CsWinRTExe>$(CsWinRTPath)cswinrt.exe</CsWinRTExe>

<!-- Wire up the .targets that should be imported before the .NET SDK -->
<BeforeMicrosoftNETSdkTargets>$(BeforeMicrosoftNETSdkTargets);$(MSBuildThisFileDirectory)Microsoft.Windows.CsWinRT.BeforeMicrosoftNetSdk.targets</BeforeMicrosoftNETSdkTargets>
</PropertyGroup>

</Project>
238 changes: 231 additions & 7 deletions nuget/Microsoft.Windows.CsWinRT.targets

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions nuget/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ C#/WinRT behavior can be customized with these project properties:
| CsWinRTMergeReferencedActivationFactories | true \| *false | Makes the native `DllGetActivationFactory` exported function for AOT scenarios also forward the activation call to all referenced WinRT components, allowing them to all be merged into a single executable or shared library |
| CsWinRTEnableManifestFreeActivation | *true \| false | Enables the manifest-free WinRT activation path as fallback when `RoGetActivationFactory` fails to resolve a WinRT type |
| CsWinRTManifestFreeActivationReportOriginalException | true \| *false | If 'CsWinRTEnableManifestFreeActivation' is set and activating a type fails, ensures the original exception is thrown, rather than 'NotSupportedException' |
| CsWinRTUseEnvironmentalTools | *true \| false | Makes the invocation of MSVC to produce a stub .exe (for Native AOT scenarios) rely on environmental tools, rather than looking up the MSVC install path. This is enabled by default when running in a Visual Studio Developer Command Prompt (or PowerShell), and false otherwise. |
| CsWinRTAotWarningLevel | 0 \| *1 \| 2 | Specifies the warning level used by the code fixer for trimming and AOT compat (0 - no warnings, 1 - warnings for scenarios involving non built-in types, 2 - warnings for all scenarios) |
\*Default value

Expand Down
13 changes: 13 additions & 0 deletions nuget/sources/StubExe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <wchar.h>

// Declare the import for '__managed__Main', which is a special export produced by the
// Native AOT runtime to allow jumping into the real 'Main' of an application. This is
// exported automatically when the 'CustomNativeMain' property is set to 'true'.
__declspec(dllimport)
int __stdcall __managed__Main(int argc, wchar_t** argv);

// Our entry point is simply a direct jump into the entry point from Native AOT
int wmain(int argc, wchar_t** argv)
{
return __managed__Main(argc, argv);
}
20 changes: 17 additions & 3 deletions src/Authoring/WinRT.SourceGenerator/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -271,13 +271,16 @@ public static int DllGetActivationFactory(void* activatableClassId, void** facto

""");

// There's three possible cases for this method:
// There's four possible cases for this method:
// 1a) The project is a standalone WinRT component
// 1b) The project is a WinRT component, and we're chaining other WinRT components
// 2) The project is an app/library, but we also want to chain other WinRT components
// 4) There's no possible types to activate (ie. no authored ones, no dependent ones)
if (context.IsCsWinRTComponent())
{
builder.AppendLine("IntPtr obj = GetActivationFactory(fullyQualifiedTypeName);");
builder.AppendLine("""
IntPtr obj = GetActivationFactory(fullyQualifiedTypeName);
""");
builder.AppendLine();

// Only emit this call if we have actually generated that. We want to avoid generating
Expand All @@ -295,7 +298,18 @@ public static int DllGetActivationFactory(void* activatableClassId, void** facto
}
else if (ShouldEmitCallToTryGetDependentActivationFactory(context))
{
builder.AppendLine("IntPtr obj = TryGetDependentActivationFactory(fullyQualifiedTypeName);");
builder.AppendLine("""
IntPtr obj = TryGetDependentActivationFactory(fullyQualifiedTypeName);
""");
builder.AppendLine();
}
else
{
// This ensures we don't get build errors if someone sets 'CsWinRTMergeReferencedActivationFactories'
// but there's no referenced activation factories defined yet (ie. no WinRT components referenced).
builder.AppendLine("""
IntPtr obj = IntPtr.Zero;
""");
builder.AppendLine();
}

Expand Down