Swift error: launch path not accessible - shell

I'm doing a simple OSX App to show/hide hidden files in the Finder from a StatuBar menu.
This is the IBAction to show/hide files:
#IBAction func menuClicked(sender: NSMenuItem) {
let task = NSTask()
task.currentDirectoryPath = "/var/tmp/"
task.launchPath = "usr/bin/defaults"
if(sender.state == NSOnState){
sender.state = NSOffState
task.arguments = ["write", "com.apple.finder", "AppleShowAllFiles", "NO"]
}else{
sender.state = NSOnState
task.arguments = ["write", "com.apple.finder", "AppleShowAllFiles", "YES"]
}
task.launch()
task.waitUntilExit()
let killTask = NSTask()
killTask.launchPath = "usr/bin/killall"
killTask.arguments = ["Finder"]
killTask.launch()
}
This gives me this error:
2015-05-10 23:54:22.237 ShowHideFiles[1234:303] An uncaught exception was raised
2015-05-10 23:54:22.238 ShowHideFiles[1234:303] launch path not accessible
I tried to find out why but cannot find an answer.
I tried also to see which of the two launchPath was wrong by disabling one or the other and they both give the same error.
Can somebody help me?

Both var and usr are at the same level, so you need to prefix usr with / like you did for var:
task.currentDirectoryPath = "/var/tmp/"
task.launchPath = "/usr/bin/defaults"
killTask.launchPath = "/usr/bin/killall"

Related

How to get top output with swift 3 on osx (NOT iOS)

// Playground
import Foundation
let task = Process()
task.launchPath = "/usr/bin/top"
task.arguments = ["-s","2"]
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
task.waitUntilExit()
print(String(data: data, encoding: String.Encoding.utf8)!)
This code work with "/bin/ls" instead of "/usr/bin/top" and when i put others argument but like it is actualy i get nothing on playground and it crach in my xcode8 project with an "An uncaught exception was raised" and it lunch a debuger with asm.So how to get TOP output in a variable ?
Found
// Playground
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let task = Process()
task.launchPath = "/usr/bin/top"
task.arguments = ["-s","9"]
let pipe = Pipe()
task.standardOutput = pipe
let outHandle = pipe.fileHandleForReading
outHandle.readabilityHandler = { pipe in
if let line = String(data: pipe.availableData, encoding: String.Encoding.utf8) {
// Update your view with the new text here
print("New ouput: \(line)")
} else {
print("Error decoding data: \(pipe.availableData)")
}
}
task.launch()

Root Privilegs for NSTask in Swift

I searched a lot on the web to find a simple way to get root privileges in my NSTask but I only found old articles which are written in Objective-C. But my Xcode Project is written in Swift :x is there a way to solve this problem to run a NSTask with Root Privilegs? :) I know I have to use something like AppleScript, STPrivilegedTask or the BetterAuthorizationSample from Apple but all I've found is written in Objective-C...
My Idea is to create a application that makes a storage media bootable with the command createinstallmedia :p all works perfectly the only problem is that the command wants root privileges, for testing I simply open my Terminal and login as Root but this is not the greatest solution for this Problem :D so please help me! :o
My Code the only thing that miss is the code to get root access:
import Cocoa
class ViewController: NSViewController {
var Task = NSTask()
var openPanel = NSOpenPanel()
var workingpath_createinstallmedia : String!
var workingpath_medium : String!
var workingpath_application : String!
var volume_flag = "--volume"
var applicationpath_flag = "--applicationpath"
var nointeraction_flag = "--nointeraction"
var commandpath : String!
var postcommand : [String]!
var DirectoryOS : NSURL!
var DirectoryMedium : NSURL!
#IBOutlet weak var PathControlOS: NSPathControl!
#IBOutlet weak var PathControlMedium: NSPathControl!
#IBOutlet weak var Outputlabel: NSTextField!
#IBAction func OSauswählen(sender: AnyObject) {
openPanel.canChooseDirectories = false
openPanel.canChooseFiles = true
openPanel.canCreateDirectories = false
openPanel.allowsMultipleSelection = false
if openPanel.runModal() == NSModalResponseOK {
DirectoryOS = openPanel.URLs[0] as NSURL
PathControlOS.objectValue = DirectoryOS
}
}
#IBAction func Mediumauswählen(sender: AnyObject) {
openPanel.canChooseDirectories = true
openPanel.canChooseFiles = false
openPanel.canCreateDirectories = false
openPanel.allowsMultipleSelection = false
if openPanel.runModal() == NSModalResponseOK {
DirectoryMedium = openPanel.URLs[0] as NSURL
PathControlMedium.objectValue = DirectoryMedium
}
}
#IBAction func starttask(sender: AnyObject) {
// edit Strings
// Createinstallmedia
workingpath_createinstallmedia = String(DirectoryOS)
workingpath_createinstallmedia = workingpath_createinstallmedia.stringByReplacingOccurrencesOfString("file://", withString: "")
workingpath_application = workingpath_createinstallmedia.stringByReplacingOccurrencesOfString("%20", withString: " ")
workingpath_createinstallmedia = workingpath_application + "/Contents/Resources/createinstallmedia"
// Medium
workingpath_medium = String(DirectoryMedium)
workingpath_medium = workingpath_medium.stringByReplacingOccurrencesOfString("file://", withString: "")
workingpath_medium = workingpath_medium.stringByReplacingOccurrencesOfString("%20", withString: " ")
// config Task Parameters
commandpath = workingpath_createinstallmedia
postcommand = [volume_flag,workingpath_medium,applicationpath_flag,workingpath_application,nointeraction_flag]
// commit the Parameters to the Task
Task.launchPath = commandpath
Task.arguments = postcommand
// start Task
Task.launch()
Task.waitUntilExit()
}
}
Thanks for your help!!!
I solved using sudo into the command and asking to the user for the password to give directly to the sudo, in the following way:
echo "passwordhere" | sudo -S command --arguments
and doing this using the sh shell executable to run the process, using this method i successfully created an app to create bootable mac os install media called TINU, but you need to be careful while dealing with user password, i chose to make my app open source to let others know what it does with this kinds of tasks that needs user password, but on mac os you should create specialized programs that does this kind of privileged tasks and then start them using system apis that will manage authentication for you and let the specialized program to do his job.

Swift 2 - fileURLWithPath returns NIL

I am trying to load a video using MPMoviePlayerController. I have added the file in my project and also added to the Build Phase "Copy Bundle Resource".
When I call the function to open the video I can see that the path its printed out however, the app crashes on 'fileURLWithPath`.
What am I doing wrong? Are .mp4 flies playable?
func firstView(){
if let filePath = NSBundle.mainBundle().pathForResource("firstVideo", ofType: "mp4") {
print(filePath)
//PRINTS: /var/mobile/Containers/Bundle/Application/B93BB049-DA87-4D89-AEBE-A5C92C01726E/MyApp.app/firstVideo.mp4
firstMoviePlayer!.contentURL = NSURL.fileURLWithPath(filePath) // fatal error
}
firstMoviePlayer!.repeatMode = .None
firstMoviePlayer!.controlStyle = MPMovieControlStyle.Embedded
firstMoviePlayer!.view.frame = FirstTimeVideoView.frame
FirstTimeVideoView.addSubview(firstMoviePlayer!.view)
firstMoviePlayer!.play()
}
You just need to change:
if let filePath = NSBundle.mainBundle().pathForResource("firstVideo", ofType: "mp4") {
print(filePath)
//PRINTS: /var/mobile/Containers/Bundle/Application/B93BB049-DA87-4D89-AEBE-A5C92C01726E/MyApp.app/firstVideo.mp4
firstMoviePlayer!.contentURL = NSURL.fileURLWithPath(filePath) // fatal error
}
TO:
if let filePath = NSBundle.mainBundle().URLForResource("firstVideo", ofType: "mp4") {
print(filePath)
//PRINTS: /var/mobile/Containers/Bundle/Application/B93BB049-DA87-4D89-AEBE-A5C92C01726E/MyApp.app/firstVideo.mp4
firstMoviePlayer!.contentURL = NSURL.fileURLWithPath(filePath) // fatal error
}

Restart Dock from app

I have an app that needs to restart the dock application. I have tried this with both Apple Script:
var errorDict: NSDictionary? = nil
let appleScript = NSAppleScript(source: "tell application \"Dock\" to quit")
var error = appleScript?.executeAndReturnError(&errorDict)
if let errorDict = errorDict {
println("An error occured: \(errorDict)")
}
... and NSTask:
let task = NSTask()
task.launchPath = "/usr/bin/killall"
task.arguments = ["Dock"]
task.launch()
... and another NSTask:
func restartFinder () {
let task = NSTask()
task.launchPath = "/bin/bash"
task.arguments = ["killall Dock"]
task.launch()
}
However, it seems my app is not allowed to restart it. I'd like to release my app to the AppStore, but how can I restart the dock?
Error when using Apple Script:
An error occured: {
NSAppleScriptErrorAppName = Dock;
NSAppleScriptErrorBriefMessage = "Application isn\U2019t running.";
NSAppleScriptErrorMessage = "Dock got an error: Application isn\U2019t running.";
NSAppleScriptErrorNumber = "-600";
NSAppleScriptErrorRange = "NSRange: {27, 4}";
}
Error when using NSTask:
killall: warning: kill -TERM 255: Operation not permitted
Update
I have also tried it with STPrivilegedTask, which didn't work for me either. Neither did I get an auth window.
I would try using Applescript, but instead like this:
var errorDict: NSDictionary? = nil
let appleScript = NSAppleScript(source: "do shell script \"killall Dock\" with administrator " +
"privileges")
var error = appleScript?.executeAndReturnError(&errorDict)
if let errorDict = errorDict {
println("An error occured: \(errorDict)")
}
This way, it executes the shell script(as if through Terminal) with admin privileges. The problem is since this is a task normally only done by the system or the user, it requires you to type in the admin password.

NSTask launchPath not working

I have a NSOpenPanel where the user choses a directory and I'm trying to run an NSTask but the launchPath isn't working.
Here's my code:
#IBAction func choseFile(sender: AnyObject) {
var panel = NSOpenPanel()
panel.canChooseFiles = false
panel.canChooseDirectories = true
panel.allowsMultipleSelection = false
panel.beginWithCompletionHandler { (result) -> Void in
if result == NSFileHandlingPanelOKButton {
var path : String = panel.URL!.absoluteString as String!
var filePath = path.stringByReplacingOccurrencesOfString("file://", withString: "", options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil)
let task = NSTask()
task.launchPath = filePath
task.arguments = ["ls"]
task.launch()
task.waitUntilExit()
}
}
}
Thanks :)
The launchPath of an NSTask is the path to the program to run, not the working directory.
I assume, since you set the arguments to be ls, that you want to run the ls command in a particular directory. In that case, you want to set the launchPath to "/bin/ls" and the arguments to [panel.URL!.path].

Resources