// // DeVercruesseProcess.m // // Created by Frank Vercruesse on Wed Apr 04 2001. // Copyright (c) 2001 Frank Vercruesse. // // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. // njr changes: #import "DeVercruesseProcess.h" #import "DeVercruesseProcessManager.h" @implementation DeVercruesseProcess + (id)processWithPSN:(ProcessSerialNumber*)sn { return [[[self alloc] initWithPSN:sn] autorelease]; } - (id)init { return [self initWithPSN:nil]; } - (id)initWithPSN:(ProcessSerialNumber*)sn { OSErr err; CPSProcessInfoRec pInfo; int dummy; if( sn ) { err = CPSGetProcessInfo( (CPSProcessSerNum*) sn, &pInfo, nil, 0, &dummy, nil, 0); if( !err ) { self = [super init]; if( self ) { psn.highLongOfPSN = sn->highLongOfPSN; psn.lowLongOfPSN = sn->lowLongOfPSN; pid = pInfo.UnixPID; flavour = pInfo.Flavour; attributes = pInfo.Attributes; type = pInfo.ExecFileType; creator = pInfo.ExecFileCreator; bundleIdentifier = nil; identifier = nil; name = nil; loc = nil; img = nil; } } else { [self dealloc]; return nil; } } else { [self dealloc]; return nil; } return self; } - (void)dealloc { [bundleIdentifier release]; [identifier release]; [name release]; [img release]; [cachedImage release]; [loc release]; [super dealloc]; } - (NSString *)executableLoc; { CFURLRef bundleURL = CFURLCreateWithFileSystemPath(NULL, (CFStringRef) [self loc], kCFURLPOSIXPathStyle, NO); CFBundleRef bundleRef = CFBundleCreate(NULL, bundleURL); if (bundleRef == NULL) { CFRelease(bundleURL); return nil; // not a bundle } else { CFURLRef execURL = CFBundleCopyExecutableURL(bundleRef); CFURLRef absURL = CFURLCopyAbsoluteURL(execURL); CFStringRef execPath = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle); if (absURL != NULL) CFRelease(absURL); if (execURL != NULL) CFRelease(execURL); CFRelease(bundleRef); return [(NSString *)execPath autorelease]; } } - (NSString*)loc { char buffer[1025]; FSRef location; if( !loc ) { if( !GetProcessBundleLocation( &psn, &location) ) { FSRefMakePath( &location, buffer, 1024); loc = [NSString stringWithUTF8String:buffer]; [loc retain]; } } return loc; } - (NSString*)name; { char buffer[1025]; CFStringRef pName; NSBundle *b; if( !name ) { if( [self loc] ) { b = [NSBundle bundleWithPath:loc]; if( b ) { name = [b localizedStringForKey:@"CFBundleName" value:@"_AsM_nO_nAmE_" table:@"InfoPlist"]; if( [name isEqualToString:@"_AsM_nO_nAmE_"] ) name = [[b infoDictionary] objectForKey:@"CFBundleName"]; if( name ) [name retain]; } } if( !name && (CopyProcessName( &psn, &pName) == noErr) ) // with thanks to Dylan Ashe { CFStringGetCString( pName, buffer, 256, CFStringConvertNSStringEncodingToEncoding( [NSString defaultCStringEncoding])); name = [NSString stringWithCString:buffer]; [name retain]; CFRelease( pName); } } return name; } - (NSImage*)img { if( !img ) { if( [self loc] ) { img = [[NSWorkspace sharedWorkspace] iconForFile:loc]; if( img ) { [img setDataRetained:YES]; // [img setCachedSeparately:YES]; // added 8/26/01 by Frank [img retain]; } } } return img; } - (NSImage *)cachedImage; { return cachedImage; } - (void)setCachedImage:(NSImage *)anImage; { if (anImage != cachedImage) { [anImage retain]; [cachedImage release]; cachedImage = anImage; } } - (ProcessSerialNumber*)psn { return &psn; } - (UInt32)pid { return pid; } - (UInt32)flavour { return flavour; } - (UInt32)attributes { CPSProcessInfoRec pInfo; int dummy; if( CPSGetProcessInfo( (CPSProcessSerNum*) &psn, &pInfo, nil, 0, &dummy, nil, 0) == noErr ) attributes = pInfo.Attributes; return attributes; } - (UInt32)type { return type; } - (UInt32)creator { return creator; } - (NSString*)identifier { if( !identifier ) { identifier = [[NSString alloc] initWithFormat:@"%@%.8X%.8X", [self bundleIdentifier], [self type] ? type : 'APPL', [self creator] ? creator : '????']; } return identifier; } - (NSString*)bundleIdentifier { NSBundle *b; if( !bundleIdentifier && [self loc] && (b = [NSBundle bundleWithPath:loc]) ) bundleIdentifier = [[b bundleIdentifier] retain]; return bundleIdentifier ? bundleIdentifier : @""; } - (unsigned)hash { return psn.lowLongOfPSN; // return pid; } - (BOOL)isEqual:(id)anObject { if( anObject ) return CPSEqualProcess( (CPSProcessSerNum*) &psn, (CPSProcessSerNum*) [anObject psn]); else return NO; } - (BOOL)isEqualToCurrent { return [self isEqual:[ProcessMgr currentProcess]]; } - (BOOL)isEqualToFront { return [self isEqual:[ProcessMgr frontProcess]]; } - (BOOL)isStillRunning { CPSProcessInfoRec pInfo; int dummy; if( CPSGetProcessInfo( (CPSProcessSerNum*) &psn, &pInfo, nil, 0, &dummy, nil, 0) == noErr ) return YES; else return NO; } - (BOOL)isBackgroundOnly { return (((attributes & kCPSBGOnlyAttr) | (attributes & kCPSUIElementAttr)) != 0); } - (BOOL)isHidden { return (([self attributes] & kCPSHiddenAttr) != 0); } - (BOOL)isClassic { return (flavour == kCPSBlueApp); } - (BOOL)isCarbon { return (flavour == kCPSCarbonApp); } - (BOOL)isCocoa { return (flavour == kCPSYellowApp); } - (void)show { if( [self isStillRunning] ) CPSPostShowReq( (CPSProcessSerNum*) &psn); } - (void)hide { if( [self isStillRunning] ) CPSPostHideReq( (CPSProcessSerNum*) &psn); } - (void)makeFront { if( [self isStillRunning] ) { CPSSetFrontProcess( (CPSProcessSerNum*) &psn); CPSPostShowReq( (CPSProcessSerNum*) &psn); } } - (void)kill { [self kill:NO]; } - (void)kill:(BOOL)hard { if( [self isStillRunning] ) CPSPostKillRequest( (CPSProcessSerNum*) &psn, hard ? bfCPSKillHard : 0 ); } - (NSString *)description; { return [NSString stringWithFormat: @"%@ pid %d: '%@' (%@)", [super description], [self pid], [self name], [self identifier]]; } @end