Announce

PukiWiki contents have been moved into SONOTS Plugin (20070703)

NSTask

NSTaskサンプルコード

- (IBAction)chk:(id)sender
{
	//> Study Memo
	//Study Memo
	//[NSApp beginSheet:_dialogWindow
	//	modalForWindow:[self window]
	//	modalDelegate:self
	//	didEndSeletor:@selector(sheetDidEnd:returnCode:contextInfo:)
	//	  contextInfo:nil];
	[self openDialog: sender];
	[self CheckInstaller: @"-Chk"];
}

- (IBAction)mk:(id)sender
{
	[self openDialog: sender];
	[self CheckInstaller: @"-Mk"];
}

- (void)CheckInstaller:(NSString*)cmd
{
	task       = [ [ NSTask alloc ] init ]; 
	pipeStderr = [ [ NSPipe alloc ] init ];
	pipeStdout = [ [ NSPipe alloc ] init ];
	NSMutableString *curPath    = [ NSMutableString string ];
	NSMutableString *scrPath    = [ NSMutableString string ];
	NSMutableString *confPath   = [ NSMutableString string ];	
	outPath    = [ NSMutableString string ];
	
	// 標準(エラー)出力の指定 	
	[ task setStandardError  : pipeStderr ];
	[ task setStandardOutput : pipeStdout ];
	
	// パスの取得 
	[ curPath setString : [ [ NSBundle mainBundle ] bundlePath ] ];
	//[ curPath setString : [ curPath stringByDeletingLastPathComponent ] ];
	[ curPath appendString : @"/Contents/Resources/CheckInstaller.pl/" ]; 
	
	[ scrPath setString    : [ [ NSBundle mainBundle ] bundlePath ] ];
	[ scrPath appendString : @"/Contents/Resources/CheckInstaller.pl/CheckInstaller.pl" ]; 
	
	[ confPath setString    : @"/tmp/checkinstaller.conf" ];
	[ outPath setString     : @"/tmp/checkinstaller.out" ];
	
	// confファイル生成
	{
		[[NSFileManager defaultManager] createFileAtPath:confPath contents:nil attributes:nil];
		NSFileHandle* output = [NSFileHandle fileHandleForWritingAtPath: confPath];
		NSString* string = [_textView string];
		NSData* data = [string dataUsingEncoding:NSUTF8StringEncoding];
		[output writeData: data];
		[output closeFile];
	}
	
	// 実行 
	[ task setLaunchPath           : @"/usr/bin/perl" ];
	[ task setCurrentDirectoryPath : curPath ];
	[ task setArguments            : [ NSArray arrayWithObjects: scrPath, cmd, confPath, outPath, nil] ];
	[ task launch ];

#if 1
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readPipeData:) name:NSFileHandleReadCompletionNotification object:nil];
	[[pipeStderr fileHandleForReading] readInBackgroundAndNotify];
#else
	// ToDo: Show a Dialog
	[ task waitUntilExit ]; // 出力が大きい場合戻ってこないバグがある。
	// ToDo: Close a Dialog
	
	// 出力ファイル読み込み
	{
		NSFileHandle* reading = [NSFileHandle fileHandleForReadingAtPath: outPath];
		NSData* data = [reading availableData];
		NSString* string = [ NSString stringWithFormat : @"%s", [ data bytes ] ];
		[_textView setString: string];
		[reading closeFile];
	}	
#endif
	
#if 0 // Memo
	{ // 標準出力の読み出し
		NSData*   dataOut = [ [ pipeStdout fileHandleForReading ] availableData ];
		NSString* strOut  = [ NSString stringWithFormat : @"%s", [ dataOut bytes ] ];
		[_textView setString: strOut];
	}
	
	{ // 標準エラーの読み出し
		NSData*   dataErr = [ [ pipeStderr fileHandleForReading ] availableData ];
		NSString* strErr  = [ NSString stringWithFormat : @"%s", [ dataErr bytes ] ];
		NSLog( strErr );
	}
#endif
	
	// temporary ファイルの削除
	//[[NSFileManager defaultManager] removeFileAtPath:confPath handler:nil];
	//[[NSFileManager defaultManager] removeFileAtPath:outPath handler:nil];
}


- (void) readPipeData:(NSNotification *)notification
{
	NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem];
	NSString *string = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
	
	if ( [task isRunning] ) {
		[[pipeStderr fileHandleForReading] readInBackgroundAndNotify];
		
		{ // Now processing xx.x%. 1行だけの表示
			NSRange lastLineRange = [string rangeOfString:@"\n" options:NSBackwardsSearch];
			lastLineRange.location -= 22; // Now processing xxx.x%.
			lastLineRange.length = 22;
			NSString *lastLine = [string substringWithRange:lastLineRange];
			//[_textView setString: lastLine];
			[_dialogLabel setStringValue: lastLine];
			//> Study Memo
			//NSBeginAlertSheet(
			//				  @"Alert sheet", 
			//				  @"OK", 
			//				  @"Cancel", 
			//				  @"Huh?", 
			//				  nil, 
			//				  self, 
			//				  @selector(
			//							runAlertSheetDidEnd:returnCode:contextInfo:), 
			//				  nil, 
			//				  nil, 
			//				  lastLine);
			//> Study Memo
			//NSRunAlertPanel(@"Progress Dialog", lastLine, @"OK", @"NG", @"Huh?");
		}
	} else {
		// 出力ファイル読み込み
		{
			NSFileHandle* reading = [NSFileHandle fileHandleForReadingAtPath: outPath];
			NSData* fileData = [reading availableData];
			NSString* fileString = [ NSString stringWithFormat : @"%s", [ fileData bytes ] ];
			[_textView setString: fileString];
			[reading closeFile];
		}
		
		if(task) [task release];
		if(pipeStdout) [pipeStdout release];
		if(pipeStderr) [pipeStderr release];
		[[NSNotificationCenter defaultCenter] removeObserver:self];
		[self closeDialog: nil];
	}
}