2024-02-14 13:22:01 -08:00

64 lines
2.1 KiB
Swift

import CWinRT
import CWinAppSDK
import WindowsFoundation
import WinSDK
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
}
public init(threadingModel: ThreadingModel = .single) throws {
let roInitParam = switch threadingModel {
case .single: RO_INIT_SINGLETHREADED
case .multi: RO_INIT_MULTITHREADED
}
try CHECKED(RoInitialize(roInitParam))
try CHECKED(SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE))
guard !processHasIdentity() else {
return
}
try CHECKED(Initialize(
UInt32(WINDOWSAPPSDK_RELEASE_MAJORMINOR),
WINDOWSAPPSDK_RELEASE_VERSION_TAG_SWIFT,
.init(),
MddBootstrapInitializeOptions(
MddBootstrapInitializeOptions_OnNoMatch_ShowUI.rawValue
)
))
}
deinit {
RoUninitialize()
if !processHasIdentity() {
Shutdown()
}
FreeLibrary(bootsrapperDll)
}
}