79 lines
2.7 KiB
Swift
79 lines
2.7 KiB
Swift
import CWinRT
|
|
import CWinAppSDK
|
|
import WindowsFoundation
|
|
import WinSDK
|
|
|
|
public enum ThreadingModel {
|
|
case single
|
|
case multi
|
|
}
|
|
|
|
/// WindowsAppRuntimeInitializer is used to properly initialize the Windows App SDK runtime, along with the Windows Runtime.
|
|
/// The runtime is initalized for the lifetime of the object, and is deinitialized when the object is deallocated.
|
|
/// Example usage:
|
|
/// ```
|
|
/// public static func main() {
|
|
/// do {
|
|
/// try withExtendedLifetime(WindowsAppRuntimeInitializer()) {
|
|
/// initialization code here
|
|
/// }
|
|
/// }
|
|
/// catch {
|
|
/// fatalError("Failed to initialize WindowsAppRuntimeInitializer: \(error)")
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
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) () -> Void
|
|
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)
|
|
}
|
|
}
|