diff --git a/Package.swift b/Package.swift index b266513..ddb0a22 100644 --- a/Package.swift +++ b/Package.swift @@ -2,15 +2,14 @@ import PackageDescription import Foundation + let currentDirectory = Context.packageDirectory -print(currentDirectory) -let includeSettings: [SwiftSetting] = [ - .unsafeFlags(["-I\(currentDirectory)/vendor/include"]) -] - let linkerSettings: [LinkerSetting] = [ - .unsafeFlags(["-L\(currentDirectory)/vendor/lib"]) +/* Figure out magic incantation so we can delay load these dlls + .unsafeFlags(["-L\(currentDirectory)/Sources/CWinAppSDK/nuget/lib"]), + .unsafeFlags(["-Xlinker" , "/DELAYLOAD:Microsoft.WindowsAppRuntime.Bootstrap.dll"]), +*/ ] let package = Package( @@ -33,14 +32,13 @@ let package = Package( .product(name: "UWP", package: "swift-uwp"), .product(name: "WindowsFoundation", package: "swift-windowsfoundation"), "CWinAppSDK" - ], - resources: [ - .copy("../../vendor/bin/Microsoft.WindowsAppRuntime.Bootstrap.dll"), ] ), .target( name: "CWinAppSDK", - swiftSettings: includeSettings, + resources: [ + .copy("nuget/bin/Microsoft.WindowsAppRuntime.Bootstrap.dll"), + ], linkerSettings: linkerSettings ), .target( @@ -50,5 +48,11 @@ let package = Package( "CWinAppSDK" ] ), + .testTarget( + name: "WinAppSDKExtTests", + dependencies: [ + "WinAppSDKExt", + ] + ) ] ) diff --git a/Sources/CWinAppSDK/delayloadhelper.c b/Sources/CWinAppSDK/delayloadhelper.c index 3883fad..b5162d4 100644 --- a/Sources/CWinAppSDK/delayloadhelper.c +++ b/Sources/CWinAppSDK/delayloadhelper.c @@ -2,12 +2,15 @@ #include #include #include "delayimp.h" +#include + FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli) { switch (dliNotify) { case dliFailLoadLib : + printf("dliFailLoadLib: %s\n", pdli->szDll); if (strcmp(pdli->szDll, "Microsoft.WindowsAppRuntime.Boostrap.dll") == 0) { - return (FARPROC)LoadLibraryW(L"swift-windowsappsdk_WinAppSDK.resources\\Microsoft.WindowsAppRuntime.Bootstrap.dll"); + return (FARPROC)LoadLibraryW(L"swift-windowsappsdk_CWinAppSDK.resources\\Microsoft.WindowsAppRuntime.Bootstrap.dll"); } break; diff --git a/Sources/CWinAppSDK/include/CWinAppSDK-Bridging-Header.h b/Sources/CWinAppSDK/include/CWinAppSDK-Bridging-Header.h index 29cbbfd..551c90b 100644 --- a/Sources/CWinAppSDK/include/CWinAppSDK-Bridging-Header.h +++ b/Sources/CWinAppSDK/include/CWinAppSDK-Bridging-Header.h @@ -6,8 +6,11 @@ #include #include #include "stdlib.h" -#include -#include + +// Headers are placed in a seperate directory because we only want to expose +// those which we know compile and work with Swift. +#include <../nuget/include/MddBootstrap.h> +#include <../nuget/include/WindowsAppSDK-VersionInfo.h> // re-define the string to make it visible in Swift. (#define only supports numbers & strings) static PCWSTR WINDOWSAPPSDK_RELEASE_VERSION_TAG_SWIFT = WINDOWSAPPSDK_RELEASE_VERSION_TAG_W; \ No newline at end of file diff --git a/Sources/CWinAppSDK/include/module.modulemap b/Sources/CWinAppSDK/include/module.modulemap new file mode 100644 index 0000000..a7eed59 --- /dev/null +++ b/Sources/CWinAppSDK/include/module.modulemap @@ -0,0 +1,7 @@ +module CWinAppSDK { + header "CWinAppSDK-Bridging-Header.h" + // Don't actually link since we can't get delay loading to work. These DLLs are loaded manually via LoadLibrary/GetProcAddress + //link "Microsoft.WindowsAppRuntime.Bootstrap" + //link "delayimp" + export * +} diff --git a/Sources/CWinAppSDK/module.modulemap b/Sources/CWinAppSDK/module.modulemap deleted file mode 100644 index a5a0bb3..0000000 --- a/Sources/CWinAppSDK/module.modulemap +++ /dev/null @@ -1,5 +0,0 @@ -module CWinAppSDK { - header "Headers/CWinAppSDK-Bridging-Header.h" - link "Microsoft.WindowsAppRuntime.Bootstrap" - export * -} diff --git a/vendor/bin/Microsoft.WindowsAppRuntime.Bootstrap.dll b/Sources/CWinAppSDK/nuget/bin/Microsoft.WindowsAppRuntime.Bootstrap.dll similarity index 100% rename from vendor/bin/Microsoft.WindowsAppRuntime.Bootstrap.dll rename to Sources/CWinAppSDK/nuget/bin/Microsoft.WindowsAppRuntime.Bootstrap.dll diff --git a/vendor/include/MRM.h b/Sources/CWinAppSDK/nuget/include/MRM.h similarity index 100% rename from vendor/include/MRM.h rename to Sources/CWinAppSDK/nuget/include/MRM.h diff --git a/vendor/include/MddBootstrap.h b/Sources/CWinAppSDK/nuget/include/MddBootstrap.h similarity index 100% rename from vendor/include/MddBootstrap.h rename to Sources/CWinAppSDK/nuget/include/MddBootstrap.h diff --git a/vendor/include/Microsoft.UI.Composition.Interop.h b/Sources/CWinAppSDK/nuget/include/Microsoft.UI.Composition.Interop.h similarity index 100% rename from vendor/include/Microsoft.UI.Composition.Interop.h rename to Sources/CWinAppSDK/nuget/include/Microsoft.UI.Composition.Interop.h diff --git a/vendor/include/Microsoft.UI.Dispatching.Interop.h b/Sources/CWinAppSDK/nuget/include/Microsoft.UI.Dispatching.Interop.h similarity index 100% rename from vendor/include/Microsoft.UI.Dispatching.Interop.h rename to Sources/CWinAppSDK/nuget/include/Microsoft.UI.Dispatching.Interop.h diff --git a/vendor/include/Microsoft.UI.Input.InputCursor.Interop.h b/Sources/CWinAppSDK/nuget/include/Microsoft.UI.Input.InputCursor.Interop.h similarity index 100% rename from vendor/include/Microsoft.UI.Input.InputCursor.Interop.h rename to Sources/CWinAppSDK/nuget/include/Microsoft.UI.Input.InputCursor.Interop.h diff --git a/vendor/include/Microsoft.UI.Input.InputPreTranslateSource.Interop.h b/Sources/CWinAppSDK/nuget/include/Microsoft.UI.Input.InputPreTranslateSource.Interop.h similarity index 100% rename from vendor/include/Microsoft.UI.Input.InputPreTranslateSource.Interop.h rename to Sources/CWinAppSDK/nuget/include/Microsoft.UI.Input.InputPreTranslateSource.Interop.h diff --git a/vendor/include/Microsoft.UI.Interop.h b/Sources/CWinAppSDK/nuget/include/Microsoft.UI.Interop.h similarity index 100% rename from vendor/include/Microsoft.UI.Interop.h rename to Sources/CWinAppSDK/nuget/include/Microsoft.UI.Interop.h diff --git a/vendor/include/MsixDynamicDependency.h b/Sources/CWinAppSDK/nuget/include/MsixDynamicDependency.h similarity index 100% rename from vendor/include/MsixDynamicDependency.h rename to Sources/CWinAppSDK/nuget/include/MsixDynamicDependency.h diff --git a/vendor/include/Security.AccessControl.h b/Sources/CWinAppSDK/nuget/include/Security.AccessControl.h similarity index 100% rename from vendor/include/Security.AccessControl.h rename to Sources/CWinAppSDK/nuget/include/Security.AccessControl.h diff --git a/vendor/include/WebView2.h b/Sources/CWinAppSDK/nuget/include/WebView2.h similarity index 100% rename from vendor/include/WebView2.h rename to Sources/CWinAppSDK/nuget/include/WebView2.h diff --git a/vendor/include/WindowsAppRuntimeInsights.h b/Sources/CWinAppSDK/nuget/include/WindowsAppRuntimeInsights.h similarity index 100% rename from vendor/include/WindowsAppRuntimeInsights.h rename to Sources/CWinAppSDK/nuget/include/WindowsAppRuntimeInsights.h diff --git a/vendor/include/WindowsAppSDK-VersionInfo.h b/Sources/CWinAppSDK/nuget/include/WindowsAppSDK-VersionInfo.h similarity index 100% rename from vendor/include/WindowsAppSDK-VersionInfo.h rename to Sources/CWinAppSDK/nuget/include/WindowsAppSDK-VersionInfo.h diff --git a/vendor/include/dwrite.h b/Sources/CWinAppSDK/nuget/include/dwrite.h similarity index 100% rename from vendor/include/dwrite.h rename to Sources/CWinAppSDK/nuget/include/dwrite.h diff --git a/vendor/include/dwrite_1.h b/Sources/CWinAppSDK/nuget/include/dwrite_1.h similarity index 100% rename from vendor/include/dwrite_1.h rename to Sources/CWinAppSDK/nuget/include/dwrite_1.h diff --git a/vendor/include/dwrite_2.h b/Sources/CWinAppSDK/nuget/include/dwrite_2.h similarity index 100% rename from vendor/include/dwrite_2.h rename to Sources/CWinAppSDK/nuget/include/dwrite_2.h diff --git a/vendor/include/dwrite_3.h b/Sources/CWinAppSDK/nuget/include/dwrite_3.h similarity index 100% rename from vendor/include/dwrite_3.h rename to Sources/CWinAppSDK/nuget/include/dwrite_3.h diff --git a/vendor/include/dwrite_core.h b/Sources/CWinAppSDK/nuget/include/dwrite_core.h similarity index 100% rename from vendor/include/dwrite_core.h rename to Sources/CWinAppSDK/nuget/include/dwrite_core.h diff --git a/vendor/include/microsoft.ui.xaml.hosting.referencetracker.h b/Sources/CWinAppSDK/nuget/include/microsoft.ui.xaml.hosting.referencetracker.h similarity index 100% rename from vendor/include/microsoft.ui.xaml.hosting.referencetracker.h rename to Sources/CWinAppSDK/nuget/include/microsoft.ui.xaml.hosting.referencetracker.h diff --git a/vendor/include/microsoft.ui.xaml.media.dxinterop.h b/Sources/CWinAppSDK/nuget/include/microsoft.ui.xaml.media.dxinterop.h similarity index 100% rename from vendor/include/microsoft.ui.xaml.media.dxinterop.h rename to Sources/CWinAppSDK/nuget/include/microsoft.ui.xaml.media.dxinterop.h diff --git a/vendor/include/microsoft.ui.xaml.window.h b/Sources/CWinAppSDK/nuget/include/microsoft.ui.xaml.window.h similarity index 100% rename from vendor/include/microsoft.ui.xaml.window.h rename to Sources/CWinAppSDK/nuget/include/microsoft.ui.xaml.window.h diff --git a/vendor/include/wil_msixdynamicdependency.h b/Sources/CWinAppSDK/nuget/include/wil_msixdynamicdependency.h similarity index 100% rename from vendor/include/wil_msixdynamicdependency.h rename to Sources/CWinAppSDK/nuget/include/wil_msixdynamicdependency.h diff --git a/vendor/include/winrtdirect3d11.h b/Sources/CWinAppSDK/nuget/include/winrtdirect3d11.h similarity index 100% rename from vendor/include/winrtdirect3d11.h rename to Sources/CWinAppSDK/nuget/include/winrtdirect3d11.h diff --git a/vendor/include/winrtdirectxcommon.h b/Sources/CWinAppSDK/nuget/include/winrtdirectxcommon.h similarity index 100% rename from vendor/include/winrtdirectxcommon.h rename to Sources/CWinAppSDK/nuget/include/winrtdirectxcommon.h diff --git a/vendor/include/xamlom.winui.h b/Sources/CWinAppSDK/nuget/include/xamlom.winui.h similarity index 100% rename from vendor/include/xamlom.winui.h rename to Sources/CWinAppSDK/nuget/include/xamlom.winui.h diff --git a/vendor/lib/DWriteCore.lib b/Sources/CWinAppSDK/nuget/lib/DWriteCore.lib similarity index 100% rename from vendor/lib/DWriteCore.lib rename to Sources/CWinAppSDK/nuget/lib/DWriteCore.lib diff --git a/vendor/lib/MRM.lib b/Sources/CWinAppSDK/nuget/lib/MRM.lib similarity index 100% rename from vendor/lib/MRM.lib rename to Sources/CWinAppSDK/nuget/lib/MRM.lib diff --git a/vendor/lib/Microsoft.WindowsAppRuntime.Bootstrap.lib b/Sources/CWinAppSDK/nuget/lib/Microsoft.WindowsAppRuntime.Bootstrap.lib similarity index 100% rename from vendor/lib/Microsoft.WindowsAppRuntime.Bootstrap.lib rename to Sources/CWinAppSDK/nuget/lib/Microsoft.WindowsAppRuntime.Bootstrap.lib diff --git a/vendor/lib/Microsoft.WindowsAppRuntime.lib b/Sources/CWinAppSDK/nuget/lib/Microsoft.WindowsAppRuntime.lib similarity index 100% rename from vendor/lib/Microsoft.WindowsAppRuntime.lib rename to Sources/CWinAppSDK/nuget/lib/Microsoft.WindowsAppRuntime.lib diff --git a/Sources/WinAppSDKExt/Initialize.swift b/Sources/WinAppSDKExt/Initialize.swift index e60313d..0ca4cc6 100644 --- a/Sources/WinAppSDKExt/Initialize.swift +++ b/Sources/WinAppSDKExt/Initialize.swift @@ -1,18 +1,29 @@ -import CWinAppSDK import CWinRT +import CWinAppSDK import WindowsFoundation import WinSDK -public enum WindowsAppSDKError: Error { - case failedToInitialize -} - public enum ThreadingModel { case single case multi } public class WindowsAppRuntimeInitializer { + // TODO: Figure out how to properly link against delayimp.lib so that we can delay load the bootstrap dll. + private typealias pfnMddBootstrapInitialize2 = @convention(c) (UInt32, PCWSTR?, PACKAGE_VERSION, MddBootstrapInitializeOptions) -> HRESULT + private typealias pfnMddBootstrapShutdown = @convention(c) () -> HRESULT + private let bootsrapperDll = LoadLibraryA("swift-windowsappsdk_CWinAppSDK.resources\\Microsoft.WindowsAppRuntime.Bootstrap.dll") + + private lazy var Initialize: pfnMddBootstrapInitialize2 = { + let pfn = GetProcAddress(bootsrapperDll, "MddBootstrapInitialize2") + return unsafeBitCast(pfn, to: pfnMddBootstrapInitialize2.self) + }() + + private lazy var Shutdown: pfnMddBootstrapShutdown = { + let pfn = GetProcAddress(bootsrapperDll, "MddBootstrapShutdown") + return unsafeBitCast(pfn, to: pfnMddBootstrapShutdown.self) + }() + private func processHasIdentity() -> Bool { var length: UInt32 = 0 return GetCurrentPackageFullName(&length, nil) != APPMODEL_ERROR_NO_PACKAGE @@ -26,27 +37,27 @@ public class WindowsAppRuntimeInitializer { try CHECKED(RoInitialize(roInitParam)) + try CHECKED(SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)) + guard !processHasIdentity() else { return } - let result = MddBootstrapInitialize2( + try CHECKED(Initialize( UInt32(WINDOWSAPPSDK_RELEASE_MAJORMINOR), WINDOWSAPPSDK_RELEASE_VERSION_TAG_SWIFT, .init(), MddBootstrapInitializeOptions( MddBootstrapInitializeOptions_OnNoMatch_ShowUI.rawValue ) - ) - guard result = S_OK else { - throw WindowsAppSDKError.failedToInitialize - } + )) } deinit { RoUninitialize() if !processHasIdentity() { - MddBootstrapShutdown() + Shutdown() } + FreeLibrary(bootsrapperDll) } } diff --git a/Tests/WinAppSDKExtTests/InitializerTests.swift b/Tests/WinAppSDKExtTests/InitializerTests.swift new file mode 100644 index 0000000..d4a18fb --- /dev/null +++ b/Tests/WinAppSDKExtTests/InitializerTests.swift @@ -0,0 +1,8 @@ +import WinAppSDKExt +import XCTest + +public class InitiailzerTests: XCTestCase { + public func testInitializer() { + XCTAssertNoThrow(try WindowsAppRuntimeInitializer()) + } +} diff --git a/generate-bindings.ps1 b/generate-bindings.ps1 index f5d9c0b..8f0f60e 100644 --- a/generate-bindings.ps1 +++ b/generate-bindings.ps1 @@ -101,7 +101,8 @@ function Copy-PackageAssets { $Package = $Projections.Package $PackageVersion = Get-NugetPackageVersion -Package $Package - $ProjectDir = Join-Path $PSScriptRoot "vendor" + $ProjectName = $Projections.Project + $ProjectDir = Join-Path $PSScriptRoot "Sources\C$ProjectName\nuget" # copy dlls from runtimes\win-\native to vendor\bin $PackageDir = Join-Path $PackagesDir "$Package.$PackageVersion"