move things around and just use loadlibrary for now

This commit is contained in:
Steve Kirbach 2024-02-14 13:22:01 -08:00
parent 53e1d3ee2d
commit f647935c6d
37 changed files with 62 additions and 30 deletions

View File

@ -2,15 +2,14 @@
import PackageDescription import PackageDescription
import Foundation import Foundation
let currentDirectory = Context.packageDirectory let currentDirectory = Context.packageDirectory
print(currentDirectory)
let includeSettings: [SwiftSetting] = [
.unsafeFlags(["-I\(currentDirectory)/vendor/include"])
]
let linkerSettings: [LinkerSetting] = [ 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( let package = Package(
@ -33,14 +32,13 @@ let package = Package(
.product(name: "UWP", package: "swift-uwp"), .product(name: "UWP", package: "swift-uwp"),
.product(name: "WindowsFoundation", package: "swift-windowsfoundation"), .product(name: "WindowsFoundation", package: "swift-windowsfoundation"),
"CWinAppSDK" "CWinAppSDK"
],
resources: [
.copy("../../vendor/bin/Microsoft.WindowsAppRuntime.Bootstrap.dll"),
] ]
), ),
.target( .target(
name: "CWinAppSDK", name: "CWinAppSDK",
swiftSettings: includeSettings, resources: [
.copy("nuget/bin/Microsoft.WindowsAppRuntime.Bootstrap.dll"),
],
linkerSettings: linkerSettings linkerSettings: linkerSettings
), ),
.target( .target(
@ -50,5 +48,11 @@ let package = Package(
"CWinAppSDK" "CWinAppSDK"
] ]
), ),
.testTarget(
name: "WinAppSDKExtTests",
dependencies: [
"WinAppSDKExt",
]
)
] ]
) )

View File

@ -2,12 +2,15 @@
#include <minwindef.h> #include <minwindef.h>
#include <winnt.h> #include <winnt.h>
#include "delayimp.h" #include "delayimp.h"
#include <stdio.h>
FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli) FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli)
{ {
switch (dliNotify) { switch (dliNotify) {
case dliFailLoadLib : case dliFailLoadLib :
printf("dliFailLoadLib: %s\n", pdli->szDll);
if (strcmp(pdli->szDll, "Microsoft.WindowsAppRuntime.Boostrap.dll") == 0) { 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; break;

View File

@ -6,8 +6,11 @@
#include <roapi.h> #include <roapi.h>
#include <winstring.h> #include <winstring.h>
#include "stdlib.h" #include "stdlib.h"
#include <MddBootstrap.h>
#include <WindowsAppSDK-VersionInfo.h> // 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) // 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; static PCWSTR WINDOWSAPPSDK_RELEASE_VERSION_TAG_SWIFT = WINDOWSAPPSDK_RELEASE_VERSION_TAG_W;

View File

@ -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 *
}

View File

@ -1,5 +0,0 @@
module CWinAppSDK {
header "Headers/CWinAppSDK-Bridging-Header.h"
link "Microsoft.WindowsAppRuntime.Bootstrap"
export *
}

View File

@ -1,18 +1,29 @@
import CWinAppSDK
import CWinRT import CWinRT
import CWinAppSDK
import WindowsFoundation import WindowsFoundation
import WinSDK import WinSDK
public enum WindowsAppSDKError: Error {
case failedToInitialize
}
public enum ThreadingModel { public enum ThreadingModel {
case single case single
case multi case multi
} }
public class WindowsAppRuntimeInitializer { 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 { private func processHasIdentity() -> Bool {
var length: UInt32 = 0 var length: UInt32 = 0
return GetCurrentPackageFullName(&length, nil) != APPMODEL_ERROR_NO_PACKAGE return GetCurrentPackageFullName(&length, nil) != APPMODEL_ERROR_NO_PACKAGE
@ -26,27 +37,27 @@ public class WindowsAppRuntimeInitializer {
try CHECKED(RoInitialize(roInitParam)) try CHECKED(RoInitialize(roInitParam))
try CHECKED(SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE))
guard !processHasIdentity() else { guard !processHasIdentity() else {
return return
} }
let result = MddBootstrapInitialize2( try CHECKED(Initialize(
UInt32(WINDOWSAPPSDK_RELEASE_MAJORMINOR), UInt32(WINDOWSAPPSDK_RELEASE_MAJORMINOR),
WINDOWSAPPSDK_RELEASE_VERSION_TAG_SWIFT, WINDOWSAPPSDK_RELEASE_VERSION_TAG_SWIFT,
.init(), .init(),
MddBootstrapInitializeOptions( MddBootstrapInitializeOptions(
MddBootstrapInitializeOptions_OnNoMatch_ShowUI.rawValue MddBootstrapInitializeOptions_OnNoMatch_ShowUI.rawValue
) )
) ))
guard result = S_OK else {
throw WindowsAppSDKError.failedToInitialize
}
} }
deinit { deinit {
RoUninitialize() RoUninitialize()
if !processHasIdentity() { if !processHasIdentity() {
MddBootstrapShutdown() Shutdown()
} }
FreeLibrary(bootsrapperDll)
} }
} }

View File

@ -0,0 +1,8 @@
import WinAppSDKExt
import XCTest
public class InitiailzerTests: XCTestCase {
public func testInitializer() {
XCTAssertNoThrow(try WindowsAppRuntimeInitializer())
}
}

View File

@ -101,7 +101,8 @@ function Copy-PackageAssets {
$Package = $Projections.Package $Package = $Projections.Package
$PackageVersion = Get-NugetPackageVersion -Package $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-<arch>\native to vendor\bin # copy dlls from runtimes\win-<arch>\native to vendor\bin
$PackageDir = Join-Path $PackagesDir "$Package.$PackageVersion" $PackageDir = Join-Path $PackagesDir "$Package.$PackageVersion"