问题描述
我正在尝试让我的应用程序在用户注销并重新登录或重启后自动启动。目的是无限期地将应用保留在那里,除非用户关闭,但是在重新启动时重新启动它。
我遵循了一些教程,并且已经阅读了线程,但是它们似乎都已经过时了。我正在3个不同的OS(包括10.13、10.14和10.15)上使用此应用程序。我似乎在10.15机器上有大多数问题。我无法弄清楚为什么该应用程序是否在登录时被命中或丢失,以及为什么有时没有登录。
https://martiancraft.com/blog/2015/01/login-items/
https://theswiftdev.com/how-to-launch-a-macos-app-at-login/
我已经对应用程序进行了代码签名,启用了沙箱,但是也许由于我发现的教程和信息已经过时,所以我在代码之外缺少了一些东西。该应用程序仅供公司内部使用,因此,我不会提交给Apple。我打算使用我们的管理软件部署到计算机上,并已构建了一个.pkg文件,以将应用程序+启动器部署到应用程序文件夹中,并在安装后自动运行。
欢迎和赞赏任何帮助,清理,解释或建议。
主应用程序:
extension Notification.Name{
static let killLauncher = Notification.Name("killLauncher")
}
extension AppDelegate: NSApplicationDelegate{
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
//assign variables for launcherhelper
let launcherappid = "Kinetic.KTGHelperLauncher"
let runningApps = NSWorkspace.shared.runningApplications
let isRunning = !runningApps.filter {$0.bundleIdentifier == launcherappid }.isEmpty
//set launcher to login item
SMLoginItemSetEnabled(launcherappid as CFString,true)
//status check if running or not running
if isRunning {
distributedNotificationCenter.default().post(name: .killLauncher,object: Bundle.main.bundleIdentifier!)
}
//configure button to display button in assets
if let button = statusItem.button {
button.image = NSImage(named:NSImage.Name("kinetic_websitemain_red"))
}
//builds menu on start
constructMenu()
}
}
@NSApplicationMain
class AppDelegate: NSObject {
let statusItem = NsstatusBar.system.statusItem(withLength:NsstatusItem.squareLength)
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
@objc func TakeScreenshot(_ sender: Any){
//get path to user download folder
let dirPath = FileManager().urls(for:.downloadsDirectory,in:.userDomainMask)[0]
//create time stamp of when picture is taken
func CreateTimeStamp() -> Int32
{
return Int32(Date().timeIntervalSince1970)
}
var displayCount: UInt32 = 0;
var result = CGGetActivedisplayList(0,nil,&displayCount)
if (result != CGError.success) {
print("error: \(result)")
return
}
let allocated = Int(displayCount)
let activedisplays = UnsafeMutablePointer<CGDirectdisplayID>.allocate(capacity: allocated)
result = CGGetActivedisplayList(displayCount,activedisplays,&displayCount)
if (result != CGError.success) {
print("error: \(result)")
return
}
for i in 1...displayCount {
let unixTimestamp = CreateTimeStamp()
let fileUrl = dirPath.appendingPathComponent("\(unixTimestamp)" + "_" + "\(i)" + ".jpg",isDirectory:false)
let screenShot:CGImage = CGdisplayCreateImage(activedisplays[Int(i-1)])!
let bitmapRep = NSBitmapImageRep(cgImage: screenShot)
let jpegData = bitmapRep.representation(using: NSBitmapImageRep.FileType.jpeg,properties: [:])!
do {
try jpegData.write(to: fileUrl,options: .atomic)
}
catch {print("error: \(error)")}
}
}
@objc func kineticSelf(_ sender: Any){
let kineticSelfUrl = URL(string: "/Library/Addigy/macmanage/MacManage.app")
NSWorkspace.shared.openFile(kineticSelfUrl!.path)
// NSWorkspace.shared.open(URL(fileURLWithPath: "/Library/Addigy/macmanage/MacManage.app"))
}
//function that opens kinetic helpdesk website
@objc func kineticHelpdesk(_ sender: Any){
let kineticHelpdeskUrl = URL(string: "http://helpdesk.kinetictg.com")!
NSWorkspace.shared.open(kineticHelpdeskUrl)
}
//function that takes user to teamviewer ktg site
@objc func kineticRemote(_ sender: Any){
let kineticRemoteUrl = URL(string: "https://get.teamviewer.com/ktgsupport")!
NSWorkspace.shared.open(kineticRemoteUrl)
}
//call kinetic
@objc func kineticHomepage(_ sender: Any){
let url = URL(string: "https://kinetictg.com")!
NSWorkspace.shared.open(url)
}
//function to build menu
func constructMenu(){
let menu = NSMenu()
//section for "Request Support"
menu.addItem(NSMenuItem.separator())
menu.addItem(NSMenuItem(title: "Request Support",action: nil,keyEquivalent:""))
//support ticket
menu.addItem(NSMenuItem(title: "Support Ticket",action:
#selector(AppDelegate.kineticHelpdesk(_:)),keyEquivalent: ""))
//remote support
menu.addItem(NSMenuItem(title: "Remote Support",action:
#selector(AppDelegate.kineticRemote(_:)),keyEquivalent: ""))
//section for "Tools"
menu.addItem(NSMenuItem.separator( ))
menu.addItem(NSMenuItem(title: "Tools",keyEquivalent:""))
//start agent installation audit
menu.addItem(NSMenuItem(title: "Take Screenshot",action:
#selector(AppDelegate.TakeScreenshot(_:)),keyEquivalent: ""))
//open self service
menu.addItem(NSMenuItem(title: "Open Self Service",action:
#selector(AppDelegate.kineticSelf(_:)),keyEquivalent: ""))
//Section for "Info"
menu.addItem(NSMenuItem.separator( ))
menu.addItem(NSMenuItem(title: "Info",keyEquivalent:""))
//contact info
menu.addItem(NSMenuItem(title: "Kinetic Homepage",action:
#selector(AppDelegate.kineticHomepage(_:)),keyEquivalent: ""))
//quit app
menu.addItem(NSMenuItem(title: "Quit",action:
#selector(NSApplication.terminate(_:)),keyEquivalent: "q"))
statusItem.menu = menu
}
}
启动器应用程序
import Cocoa
//extension variable for launcher to kill launcher
extension Notification.Name {
static let killLauncher = Notification.Name("killLauncher")
}
@NSApplicationMain
class HelperAppDelegate: NSObject {
//terminate object
@objc func terminate(){
NSApp.terminate(nil)
}
}
extension HelperAppDelegate: NSApplicationDelegate{
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
//main app identifier
let mainAppIdentifier = "Kinetic.KTG-Helper"
let runningApps = NSWorkspace.shared.runningApplications
let isRunning = !runningApps.filter { $0.bundleIdentifier == mainAppIdentifier }.isEmpty
//if app is running kill launcher entity and reset status of killlauncher
if !isRunning {
distributedNotificationCenter.default().addobserver(self,selector: #selector(self.terminate),name: .killLauncher,object: mainAppIdentifier)
let path = Bundle.main.bundlePath as Nsstring
var components = path.pathComponents
components.removeLast(3)
components.append("MacOS")
components.append("KTG Helper")
let newPath = Nsstring.path(withComponents: components)
NSWorkspace.shared.launchApplication(newPath)
}
else{
self.terminate()
}
}
//func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
//}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)