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 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",
]
)
]
)

View File

@ -2,12 +2,15 @@
#include <minwindef.h>
#include <winnt.h>
#include "delayimp.h"
#include <stdio.h>
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;

View File

@ -6,8 +6,11 @@
#include <roapi.h>
#include <winstring.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)
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 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)
}
}

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
$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
$PackageDir = Join-Path $PackagesDir "$Package.$PackageVersion"