mirror of
https://github.com/X1a0He/Adobe-Downloader.git
synced 2025-11-25 03:14:57 +08:00
feat: Add Helper to solve permission issues.
This commit is contained in:
@@ -7,10 +7,34 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
3C60E1C32CE3AA1B00600C07 /* com.x1a0he.macOS.Adobe-Downloader.helper in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3C60E16D2CE3A6CB00600C07 /* com.x1a0he.macOS.Adobe-Downloader.helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
3CB9FF092CDBAEF200D7A58B /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 3CB9FF082CDBAEF200D7A58B /* Sparkle */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
3C60E16B2CE3A6CB00600C07 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
3C60E1C22CE3AA0B00600C07 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = Contents/Library/LaunchServices;
|
||||
dstSubfolderSpec = 1;
|
||||
files = (
|
||||
3C60E1C32CE3AA1B00600C07 /* com.x1a0he.macOS.Adobe-Downloader.helper in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
3C60E16D2CE3A6CB00600C07 /* com.x1a0he.macOS.Adobe-Downloader.helper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "com.x1a0he.macOS.Adobe-Downloader.helper"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3CCC3AE02CC67B8F006E22B4 /* Adobe Downloader.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Adobe Downloader.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@@ -25,6 +49,11 @@
|
||||
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||
|
||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||
3C60E16E2CE3A6CB00600C07 /* AdobeDownloaderHelperTool */ = {
|
||||
isa = PBXFileSystemSynchronizedRootGroup;
|
||||
path = AdobeDownloaderHelperTool;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3CCC3AE22CC67B8F006E22B4 /* Adobe Downloader */ = {
|
||||
isa = PBXFileSystemSynchronizedRootGroup;
|
||||
exceptions = (
|
||||
@@ -41,6 +70,13 @@
|
||||
/* End PBXFileSystemSynchronizedRootGroup section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
3C60E16A2CE3A6CB00600C07 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
3CCC3ADD2CC67B8F006E22B4 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -56,6 +92,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3CCC3AE22CC67B8F006E22B4 /* Adobe Downloader */,
|
||||
3C60E16E2CE3A6CB00600C07 /* AdobeDownloaderHelperTool */,
|
||||
3CCC3AE12CC67B8F006E22B4 /* Products */,
|
||||
3CCC3B112CC67F7A006E22B4 /* Localizables */,
|
||||
);
|
||||
@@ -65,6 +102,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3CCC3AE02CC67B8F006E22B4 /* Adobe Downloader.app */,
|
||||
3C60E16D2CE3A6CB00600C07 /* com.x1a0he.macOS.Adobe-Downloader.helper */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -72,6 +110,28 @@
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
3C60E16C2CE3A6CB00600C07 /* AdobeDownloaderHelperTool */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 3C60E1732CE3A6CB00600C07 /* Build configuration list for PBXNativeTarget "AdobeDownloaderHelperTool" */;
|
||||
buildPhases = (
|
||||
3C60E1692CE3A6CB00600C07 /* Sources */,
|
||||
3C60E16A2CE3A6CB00600C07 /* Frameworks */,
|
||||
3C60E16B2CE3A6CB00600C07 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
fileSystemSynchronizedGroups = (
|
||||
3C60E16E2CE3A6CB00600C07 /* AdobeDownloaderHelperTool */,
|
||||
);
|
||||
name = AdobeDownloaderHelperTool;
|
||||
packageProductDependencies = (
|
||||
);
|
||||
productName = AdobeDownloaderHelperTool;
|
||||
productReference = 3C60E16D2CE3A6CB00600C07 /* com.x1a0he.macOS.Adobe-Downloader.helper */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
3CCC3ADF2CC67B8F006E22B4 /* Adobe Downloader */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 3CCC3B052CC67B91006E22B4 /* Build configuration list for PBXNativeTarget "Adobe Downloader" */;
|
||||
@@ -79,6 +139,7 @@
|
||||
3CCC3ADC2CC67B8F006E22B4 /* Sources */,
|
||||
3CCC3ADD2CC67B8F006E22B4 /* Frameworks */,
|
||||
3CCC3ADE2CC67B8F006E22B4 /* Resources */,
|
||||
3C60E1C22CE3AA0B00600C07 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -106,6 +167,9 @@
|
||||
LastSwiftUpdateCheck = 1610;
|
||||
LastUpgradeCheck = 1610;
|
||||
TargetAttributes = {
|
||||
3C60E16C2CE3A6CB00600C07 = {
|
||||
CreatedOnToolsVersion = 16.1;
|
||||
};
|
||||
3CCC3ADF2CC67B8F006E22B4 = {
|
||||
CreatedOnToolsVersion = 16.0;
|
||||
};
|
||||
@@ -129,6 +193,7 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
3CCC3ADF2CC67B8F006E22B4 /* Adobe Downloader */,
|
||||
3C60E16C2CE3A6CB00600C07 /* AdobeDownloaderHelperTool */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -144,6 +209,13 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
3C60E1692CE3A6CB00600C07 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
3CCC3ADC2CC67B8F006E22B4 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -154,6 +226,63 @@
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
3C60E1712CE3A6CB00600C07 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = AdobeDownloaderHelperTool/AdobeDownloaderHelperTool.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
ENABLE_HARDENED_RUNTIME = NO;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||
INFOPLIST_FILE = AdobeDownloaderHelperTool/Info.plist;
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = NO;
|
||||
MACOSX_DEPLOYMENT_TARGET = 15.1;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = (
|
||||
"-sectcreate",
|
||||
__TEXT,
|
||||
__info_plist,
|
||||
"$(SRCROOT)/AdobeDownloaderHelperTool/Info.plist",
|
||||
"-sectcreate",
|
||||
__TEXT,
|
||||
__launchd_plist,
|
||||
"$(SRCROOT)/AdobeDownloaderHelperTool/Launchd.plist",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.x1a0he.macOS.Adobe-Downloader.helper";
|
||||
PRODUCT_NAME = "com.x1a0he.macOS.Adobe-Downloader.helper";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
3C60E1722CE3A6CB00600C07 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = AdobeDownloaderHelperTool/AdobeDownloaderHelperTool.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
ENABLE_HARDENED_RUNTIME = NO;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||
INFOPLIST_FILE = AdobeDownloaderHelperTool/Info.plist;
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = NO;
|
||||
MACOSX_DEPLOYMENT_TARGET = 15.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-sectcreate",
|
||||
__TEXT,
|
||||
__info_plist,
|
||||
"$(SRCROOT)/AdobeDownloaderHelperTool/Info.plist",
|
||||
"-sectcreate",
|
||||
__TEXT,
|
||||
__launchd_plist,
|
||||
"$(SRCROOT)/AdobeDownloaderHelperTool/Launchd.plist",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.x1a0he.macOS.Adobe-Downloader.helper";
|
||||
PRODUCT_NAME = "com.x1a0he.macOS.Adobe-Downloader.helper";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
3CCC3B032CC67B91006E22B4 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@@ -316,7 +445,6 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||
CODE_SIGN_ENTITLEMENTS = "Adobe Downloader/Adobe Downloader.entitlements";
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 120;
|
||||
@@ -345,6 +473,15 @@
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
3C60E1732CE3A6CB00600C07 /* Build configuration list for PBXNativeTarget "AdobeDownloaderHelperTool" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
3C60E1712CE3A6CB00600C07 /* Debug */,
|
||||
3C60E1722CE3A6CB00600C07 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
3CCC3ADB2CC67B8F006E22B4 /* Build configuration list for PBXProject "Adobe Downloader" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>AdobeDownloaderHelperTool.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
|
||||
@@ -50,6 +50,7 @@ struct Adobe_DownloaderApp: App {
|
||||
UserDefaults.standard.set(downloadsURL.path, forKey: "defaultDirectory")
|
||||
}
|
||||
}
|
||||
PrivilegedHelperManager.shared.checkInstall()
|
||||
}
|
||||
|
||||
var body: some Scene {
|
||||
|
||||
241
Adobe Downloader/HelperManager/PrivilegedHelperManager.swift
Normal file
241
Adobe Downloader/HelperManager/PrivilegedHelperManager.swift
Normal file
@@ -0,0 +1,241 @@
|
||||
//
|
||||
// Untitled.swift
|
||||
// Adobe Downloader
|
||||
//
|
||||
// Created by X1a0He on 11/12/24.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
import Cocoa
|
||||
import ServiceManagement
|
||||
|
||||
@objcMembers
|
||||
class PrivilegedHelperManager: NSObject {
|
||||
|
||||
enum HelperStatus {
|
||||
case installed
|
||||
case noFound
|
||||
case needUpdate
|
||||
}
|
||||
|
||||
static let shared = PrivilegedHelperManager()
|
||||
static let machServiceName = "com.x1a0he.macOS.Adobe-Downloader.helper"
|
||||
var connectionSuccessBlock: (() -> Void)?
|
||||
|
||||
private var useLegacyInstall = false
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
initAuthorizationRef()
|
||||
}
|
||||
|
||||
func checkInstall() {
|
||||
getHelperStatus { [weak self] status in
|
||||
guard let self = self else {return}
|
||||
switch status {
|
||||
case .noFound:
|
||||
if #available(macOS 13, *) {
|
||||
let url = URL(string: "/Library/LaunchDaemons/\(PrivilegedHelperManager.machServiceName).plist")!
|
||||
let status = SMAppService.statusForLegacyPlist(at: url)
|
||||
if status == .requiresApproval {
|
||||
let alert = NSAlert()
|
||||
let notice = "Adobe Downloader 需要通过后台Daemon进程来安装与移动文件,请在\"系统偏好设置->登录项->允许在后台 中\"允许当前App"
|
||||
let addition = "如果在设置里没找到当前App,可以尝试重置守护程序"
|
||||
alert.messageText = notice + "\n" + addition
|
||||
alert.addButton(withTitle: "打开系统登录项设置")
|
||||
alert.addButton(withTitle: "重置守护程序")
|
||||
if alert.runModal() == .alertFirstButtonReturn {
|
||||
SMAppService.openSystemSettingsLoginItems()
|
||||
} else {
|
||||
self.removeInstallHelper()
|
||||
}
|
||||
}
|
||||
}
|
||||
fallthrough
|
||||
case .needUpdate:
|
||||
if Thread.isMainThread {
|
||||
self.notifyInstall()
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
self.notifyInstall()
|
||||
}
|
||||
}
|
||||
case .installed:
|
||||
self.connectionSuccessBlock?()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func initAuthorizationRef() {
|
||||
var authRef: AuthorizationRef?
|
||||
let status = AuthorizationCreate(nil, nil, AuthorizationFlags(), &authRef)
|
||||
if status != OSStatus(errAuthorizationSuccess) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func installHelperDaemon() -> DaemonInstallResult {
|
||||
defer {
|
||||
|
||||
}
|
||||
var authRef: AuthorizationRef?
|
||||
var authStatus = AuthorizationCreate(nil, nil, [], &authRef)
|
||||
|
||||
guard authStatus == errAuthorizationSuccess else {
|
||||
return .authorizationFail
|
||||
}
|
||||
|
||||
var authItem = AuthorizationItem(name: (kSMRightBlessPrivilegedHelper as NSString).utf8String!, valueLength: 0, value: nil, flags: 0)
|
||||
var authRights = withUnsafeMutablePointer(to: &authItem) { pointer in
|
||||
AuthorizationRights(count: 1, items: pointer)
|
||||
}
|
||||
let flags: AuthorizationFlags = [[], .interactionAllowed, .extendRights, .preAuthorize]
|
||||
authStatus = AuthorizationCreate(&authRights, nil, flags, &authRef)
|
||||
defer {
|
||||
if let ref = authRef {
|
||||
AuthorizationFree(ref, [])
|
||||
}
|
||||
}
|
||||
guard authStatus == errAuthorizationSuccess else {
|
||||
return .getAdminFail
|
||||
}
|
||||
|
||||
var error: Unmanaged<CFError>?
|
||||
let helperURL = Bundle.main.bundleURL.appendingPathComponent("Contents/Library/LaunchServices/" + PrivilegedHelperManager.machServiceName)
|
||||
|
||||
|
||||
|
||||
if SMJobBless(kSMDomainSystemLaunchd, PrivilegedHelperManager.machServiceName as CFString, authRef, &error) == false {
|
||||
if let blessError = error?.takeRetainedValue() {
|
||||
let nsError = blessError as Error as NSError
|
||||
NSAlert.alert(with: "SMJobBless failed with error: \(blessError)\nError domain: \(nsError.domain)\nError code: \(nsError.code)\nError description: \(nsError.localizedDescription)\nError user info: \(nsError.userInfo)")
|
||||
return .blessError(nsError.code)
|
||||
}
|
||||
}
|
||||
|
||||
return .success
|
||||
}
|
||||
|
||||
private func getHelperStatus(callback: @escaping ((HelperStatus) -> Void)) {
|
||||
var called = false
|
||||
let reply: ((HelperStatus) -> Void) = {
|
||||
status in
|
||||
if called {return}
|
||||
called = true
|
||||
callback(status)
|
||||
}
|
||||
|
||||
let helperURL = Bundle.main.bundleURL.appendingPathComponent("Contents/Library/LaunchServices/" + PrivilegedHelperManager.machServiceName)
|
||||
guard
|
||||
let helperBundleInfo = CFBundleCopyInfoDictionaryForURL(helperURL as CFURL) as? [String: Any],
|
||||
let helperVersion = helperBundleInfo["CFBundleShortVersionString"] as? String else {
|
||||
reply(.noFound)
|
||||
return
|
||||
}
|
||||
let helperFileExists = FileManager.default.fileExists(atPath: "/Library/PrivilegedHelperTools/\(PrivilegedHelperManager.machServiceName)")
|
||||
if !helperFileExists {
|
||||
reply(.noFound)
|
||||
return
|
||||
}
|
||||
|
||||
reply(.installed)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PrivilegedHelperManager {
|
||||
private func notifyInstall() {
|
||||
if useLegacyInstall {
|
||||
useLegacyInstall = false
|
||||
legacyInstallHelper()
|
||||
checkInstall()
|
||||
return
|
||||
}
|
||||
|
||||
let result = installHelperDaemon()
|
||||
if case .success = result {
|
||||
checkInstall()
|
||||
return
|
||||
}
|
||||
result.alertAction()
|
||||
let ret = result.shouldRetryLegacyWay()
|
||||
useLegacyInstall = ret.0
|
||||
let isCancle = ret.1
|
||||
if !isCancle, useLegacyInstall {
|
||||
checkInstall()
|
||||
} else if isCancle, !useLegacyInstall {
|
||||
NSAlert.alert(with: "获取管理员授权失败,用户主动取消授权!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum DaemonInstallResult {
|
||||
case success
|
||||
case authorizationFail
|
||||
case getAdminFail
|
||||
case blessError(Int)
|
||||
var alertContent: String {
|
||||
switch self {
|
||||
case .success:
|
||||
return ""
|
||||
case .authorizationFail: return "Failed to create authorization!"
|
||||
case .getAdminFail: return "The user actively cancels the authorization, Failed to get admin authorization! "
|
||||
case let .blessError(code):
|
||||
switch code {
|
||||
case kSMErrorInternalFailure: return "blessError: kSMErrorInternalFailure"
|
||||
case kSMErrorInvalidSignature: return "blessError: kSMErrorInvalidSignature"
|
||||
case kSMErrorAuthorizationFailure: return "blessError: kSMErrorAuthorizationFailure"
|
||||
case kSMErrorToolNotValid: return "blessError: kSMErrorToolNotValid"
|
||||
case kSMErrorJobNotFound: return "blessError: kSMErrorJobNotFound"
|
||||
case kSMErrorServiceUnavailable: return "blessError: kSMErrorServiceUnavailable"
|
||||
case kSMErrorJobMustBeEnabled: return "Adobe Downloader Helper is disabled by other process. Please run \"sudo launchctl enable system/\(PrivilegedHelperManager.machServiceName)\" in your terminal. The command has been copied to your pasteboard"
|
||||
case kSMErrorInvalidPlist: return "blessError: kSMErrorInvalidPlist"
|
||||
default:
|
||||
return "bless unknown error:\(code)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func shouldRetryLegacyWay() -> (Bool, Bool) {
|
||||
switch self {
|
||||
case .success: return (false, false)
|
||||
case let .blessError(code):
|
||||
switch code {
|
||||
case kSMErrorJobMustBeEnabled:
|
||||
return (false, false)
|
||||
default:
|
||||
return (true, false)
|
||||
}
|
||||
case .authorizationFail:
|
||||
return (true, false)
|
||||
case .getAdminFail:
|
||||
return (false, true)
|
||||
}
|
||||
}
|
||||
|
||||
func alertAction() {
|
||||
switch self {
|
||||
case let .blessError(code):
|
||||
switch code {
|
||||
case kSMErrorJobMustBeEnabled:
|
||||
NSPasteboard.general.clearContents()
|
||||
NSPasteboard.general.setString("sudo launchctl enable system/\(PrivilegedHelperManager.machServiceName)", forType: .string)
|
||||
default:
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension NSAlert {
|
||||
static func alert(with text: String) {
|
||||
let alert = NSAlert()
|
||||
alert.messageText = text
|
||||
alert.alertStyle = .warning
|
||||
alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
|
||||
alert.runModal()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// PrivilegedHelperManagerLegacy.swift
|
||||
// Adobe Downloader
|
||||
//
|
||||
// Created by X1a0He on 11/13/24.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
extension PrivilegedHelperManager {
|
||||
func getInstallScript() -> String {
|
||||
let appPath = Bundle.main.bundlePath
|
||||
let bash = """
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
plistPath=/Library/LaunchDaemons/\(PrivilegedHelperManager.machServiceName).plist
|
||||
rm -rf /Library/PrivilegedHelperTools/\(PrivilegedHelperManager.machServiceName)
|
||||
if [ -e ${plistPath} ]; then
|
||||
launchctl unload -w ${plistPath}
|
||||
rm ${plistPath}
|
||||
fi
|
||||
launchctl remove \(PrivilegedHelperManager.machServiceName) || true
|
||||
|
||||
mkdir -p /Library/PrivilegedHelperTools/
|
||||
rm -f /Library/PrivilegedHelperTools/\(PrivilegedHelperManager.machServiceName)
|
||||
|
||||
cp "\(appPath)/Contents/Library/LaunchServices/\(PrivilegedHelperManager.machServiceName)" "/Library/PrivilegedHelperTools/\(PrivilegedHelperManager.machServiceName)"
|
||||
|
||||
echo '
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>\(PrivilegedHelperManager.machServiceName)</string>
|
||||
<key>MachServices</key>
|
||||
<dict>
|
||||
<key>\(PrivilegedHelperManager.machServiceName)</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Program</key>
|
||||
<string>/Library/PrivilegedHelperTools/\(PrivilegedHelperManager.machServiceName)</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/Library/PrivilegedHelperTools/\(PrivilegedHelperManager.machServiceName)</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
' > ${plistPath}
|
||||
|
||||
launchctl load -w ${plistPath}
|
||||
"""
|
||||
return bash
|
||||
}
|
||||
|
||||
func runScriptWithRootPermission(script: String) {
|
||||
let tmpPath = FileManager.default.temporaryDirectory.appendingPathComponent(NSUUID().uuidString).appendingPathExtension("sh")
|
||||
do {
|
||||
try script.write(to: tmpPath, atomically: true, encoding: .utf8)
|
||||
let appleScriptStr = "do shell script \"bash \(tmpPath.path) \" with administrator privileges"
|
||||
let appleScript = NSAppleScript(source: appleScriptStr)
|
||||
var dict: NSDictionary?
|
||||
if appleScript?.executeAndReturnError(&dict) == nil {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
} catch let err {
|
||||
print("legacyInstallHelper create script fail: \(err)")
|
||||
}
|
||||
try? FileManager.default.removeItem(at: tmpPath)
|
||||
}
|
||||
|
||||
func legacyInstallHelper() {
|
||||
defer {
|
||||
Thread.sleep(forTimeInterval: 1)
|
||||
}
|
||||
let script = getInstallScript()
|
||||
runScriptWithRootPermission(script: script)
|
||||
}
|
||||
|
||||
func removeInstallHelper() {
|
||||
defer {
|
||||
Thread.sleep(forTimeInterval: 5)
|
||||
}
|
||||
let script = """
|
||||
/bin/launchctl remove \(PrivilegedHelperManager.machServiceName) || true
|
||||
/usr/bin/killall -u root -9 \(PrivilegedHelperManager.machServiceName)
|
||||
/bin/rm -rf /Library/LaunchDaemons/\(PrivilegedHelperManager.machServiceName).plist
|
||||
/bin/rm -rf /Library/PrivilegedHelperTools/\(PrivilegedHelperManager.machServiceName)
|
||||
"""
|
||||
runScriptWithRootPermission(script: script)
|
||||
}
|
||||
}
|
||||
@@ -2,17 +2,22 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>SMPrivilegedExecutables</key>
|
||||
<dict>
|
||||
<key>com.x1a0he.macOS.Adobe-Downloader.helper</key>
|
||||
<string>identifier "com.x1a0he.macOS.Adobe-Downloader.helper" and anchor apple generic</string>
|
||||
</dict>
|
||||
<key>SUFeedURL</key>
|
||||
<string>https://raw.githubusercontent.com/X1a0He/Adobe-Downloader/refs/heads/main/appcast.xml</string>
|
||||
<key>SUPublicEDKey</key>
|
||||
<string>gYylad3ybfiyK5ZTS3xRrw+3c/8063mpXdQnPpMB86Q=</string>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.downloads.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-write</key>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict/>
|
||||
</plist>
|
||||
20
AdobeDownloaderHelperTool/Info.plist
Normal file
20
AdobeDownloaderHelperTool/Info.plist
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.x1a0he.macOS.Adobe-Downloader.helper</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>com.x1a0he.macOS.Adobe-Downloader.helper</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>100</string>
|
||||
<key>SMAuthorizedClients</key>
|
||||
<array>
|
||||
<string>identifier "com.x1a0he.macOS.Adobe-Downloader" and anchor apple generic</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
15
AdobeDownloaderHelperTool/Launchd.plist
Normal file
15
AdobeDownloaderHelperTool/Launchd.plist
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.x1a0he.macOS.Adobe-Downloader.helper</string>
|
||||
<key>MachServices</key>
|
||||
<dict>
|
||||
<key>com.x1a0he.macOS.Adobe-Downloader.helper</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>AssociatedBundleIdentifiers</key>
|
||||
<string>com.x1a0he.macOS.Adobe-Downloader</string>
|
||||
</dict>
|
||||
</plist>
|
||||
11
AdobeDownloaderHelperTool/main.swift
Normal file
11
AdobeDownloaderHelperTool/main.swift
Normal file
@@ -0,0 +1,11 @@
|
||||
//
|
||||
// main.swift
|
||||
// AdobeDownloaderHelperTool
|
||||
//
|
||||
// Created by X1a0He on 11/12/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
print("Hello, World!")
|
||||
|
||||
@@ -151,6 +151,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OK" : {
|
||||
|
||||
},
|
||||
"Setup 组件未处理" : {
|
||||
"localizations" : {
|
||||
|
||||
Reference in New Issue
Block a user