I am trying to schedule a shutdown event with pmset executed via NSTask in OSX app.
NSCalendar *cal = [NSCalendar new];
NSDate *dateNext = [date dateByAddingTimeInterval:120];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"MM/dd/YYYY HH:mm:ss"];
NSString* dS = [df stringFromDate:dateNext];
//# pmset schedule shutdown "MM/DD/YYYY HH:MM:SS"
NSString* dateString = [NSString stringWithFormat:#"\"%#\"", dS];
NSLog(#"Date to set %#", dateString);
int pid = [[NSProcessInfo processInfo] processIdentifier];
NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;
NSTask *task = [[NSTask alloc] init];
task.launchPath = #"/usr/bin/pmset";
NSArray *args = [NSArray arrayWithObjects:#"schedule",#"shutdown", dateString, nil];
[task setArguments:args];
task.standardOutput = pipe;
[task launch];
NSData *data = [file readDataToEndOfFile];
[file closeFile];
NSString *out = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog (#"Result:\n%#", out);
The log shows as follows:
2019-09-12 12:38:53.470793+0100 TheApp[51008:4925389] Date to set "09/12/2019 12:40:53"
2019-09-12 12:38:53.518372+0100 TheApp[51008:4925389] Result:
Error: Badly formatted date (2)
Error parsing scheduled event.
The dateString argument seems to be correctly formatted between quotes, as required by pmset, but I keep getting such error. Is there some parameter missing in NSTask?
Thank you.
Related
Thanks for the help. My code below works, returning results in the Console. I want to display the same results in a textView. Can't get it to work. Can anyone explain what I need to do?
Thanks.
-(IBAction)activateTask:(id)sender
{
NSURL *fileURL = [NSURL fileURLWithPath:sourceField.stringValue];
NSString *filePath= [fileURL path];
[soxTask setArguments:[NSArray arrayWithObjects:#"--show-progress", filePath, #"-n", #"stats" , nil]];
NSPipe *pipe;
pipe = [NSPipe pipe];
[soxTask setStandardOutput: pipe];
NSFileHandle *file;
file = [pipe fileHandleForReading];
[soxTask launch];
[soxTask waitUntilExit];
NSData *data;
data = [file readDataToEndOfFile];
NSString *string;
string = [[NSString alloc] initWithData: data
encoding: NSUTF8StringEncoding];
[textView setString:string];
///
}
Try using -setStandardError: instead of -setStandardOutput:
I am very new to develop mac osx application using xcode. I am trying to get all running application list with their memory usage.
Can any body help me in this case.
Please help me.
Thanks in advance.
It will help you to get list of running application :
for (NSRunningApplication *app in [[NSWorkspace sharedWorkspace] runningApplications]) {
NSLog(#"%#",[app localizedName]);
}
You may get the cpu usage as:
- (NSString*) get_process_usage:(int) pid
{
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath:#"/bin/ps"];
NSArray *arguments;
arguments = [NSArray arrayWithObjects: #"-O",#"%cpu",#"-p",[NSString stringWithFormat:#"%d",pid], nil];
[task setArguments: arguments];
NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
NSFileHandle *file;
file = [pipe fileHandleForReading];
[task launch];
NSData *data;
data = [file readDataToEndOfFile];
NSString *string;
string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSString* temp = [string stringByReplacingOccurrencesOfString:#"PID %CPU TT STAT TIME COMMAND" withString:#""];
NSMutableArray* arr =(NSMutableArray*) [temp componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[arr removeObject:#""];
[string release];
[task release];
if([arr count]>=2)
return [arr objectAtIndex:1];
else
return #"unknown";
}
Thanks for the help. The results of this executed command is displayed in my Xcode Console. What's the best way to get the results of the command to be displayed in an NSTextView?
NSString *commandToRun = #"~/Library/webREF/ffmpeg -nostats -i ~/Desktop/input.wav - filter_complex ebur128 -f null -";
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: #"/bin/sh"];
NSArray *arguments = [NSArray arrayWithObjects:
#"-c" ,
[NSString stringWithFormat:#"%#", commandToRun],
nil];
NSLog(#"run command: %#",commandToRun);
[task setArguments: arguments];
NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
NSFileHandle *file;
file = [pipe fileHandleForReading];
[task launch];
Add something like:
…
NSFileHandle *file;
file = [pipe fileHandleForReading];
NSMutableData *data = [[NSMutableData alloc] init];
NSData *inData = nil;
[task setStandardOutput:pipe];
[task launch];
[task waitUntilExit];
while ((inData = [file availableData]) && [inData length]) {
[data appendData:inData];
}
[file closeFile];
[task release];
[pipe release];
NSString *result = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
[data release];
// somewhere we have an NSTextView textView
[textView setString: result];
I was wondering how I would output text from NSTask and send it to a NSTextField on OSX.
I googled NSTask and got this...
but here is the code to do what you want.
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: #"/bin/ls"];
NSArray *arguments;
arguments = [NSArray arrayWithObjects: #"-l", #"-a", #"-t", nil];
[task setArguments: arguments];
NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
NSFileHandle *file;
file = [pipe fileHandleForReading];
[task launch];
NSData *data;
data = [file readDataToEndOfFile];
NSString *string;
string = [[NSString alloc] initWithData: data
encoding: NSUTF8StringEncoding];
[myTextField setStringValue: string];
whats I missed?
NSString * configPath = nil;
-(IBAction)setPlistPathAndWriteData:(id)sender{
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setDirectory:#"/Volumes/"];
[panel setNameFieldStringValue:#"config.plist"];
[panel setRequiredFileType:#"plist"];
NSInteger ret = [panel runModal];
if ( ret == NSFileHandlingPanelOKButton ) {
NSString *filePath= [[panel URL] path];
// with this works fine
//configPath = [NSString stringWithFormat:#"/Volumes/Macintosh HD/config.plist"];
// with this EXC BAD ACCESS
configPath = [NSString stringWithFormat:#"%#", filePath];
[self writeData];
}
}
-(void)writeData {
SET_TEMP_PLIST
NSTask *task = [[NSTask alloc] init];
NSPipe *pipe = [[NSPipe alloc] init];
NSFileHandle *writeHandle = [pipe fileHandleForWriting];
NSData *configData = [NSPropertyListSerialization dataFromPropertyList:tmpPlist format:
NSPropertyListXMLFormat_v1_0 errorDescription:nil];
[task setLaunchPath:#"/usr/libexec/authopen"];
////////////////////////////////////////////////////////EXC_BAD_ACCESS HERE////////
[task setArguments:[NSArray arrayWithObjects:#"-c", #"-w", configPath, nil]];
[task setStandardInput:pipe];
[writeHandle writeData:configData];
[task launch];
close([writeHandle fileDescriptor]);
[task waitUntilExit];
[task release];
}
EDIT
well... works fine with this code:
NSString *filePath= [[[panel URL] path] retain];
const char * cString = [filePath UTF8String];
configPath = [[NSString stringWithUTF8String:cString] retain];
but this is not perfect method.. thought
Your app crashes likely because configPath is nil, and later in writeData you try to initialize a new array with nil as the third object :
[NSArray arrayWithObjects:#"-c", #"-w", configPath, nil]
// ^^^ this is nil
I suggest you copy the string returned by path :
if(ret == NSFileHandlingPanelOKButton ) {
// you become the owner of the string,
// don't forget to release configPath later
configPath = [[[panel URL] path] copy];
[self writeData];
}
This may run without any problem.