This is TSWorkspace.m in view mode; [Download] [Up]
/* TSWorkspace.m created by tsengel on Mon 01-Sep-1997 */ #import "TSWorkspace.h" #import <MiscFoundation/MiscFoundation.h> #import "NSString+MiscPathComparing.h" #import "NSTask+MiscExtensions.h" static id sharedTSWorkspace = nil; @implementation TSWorkspace /*" This class is mainly a helper class which allows us to "bypass" some of the shortcomings of the regular NSWorkspace class. However..it is not a real subclass for various reasons...and a complete hack anyway. "*/ + (id)sharedWorkspace { if( !sharedTSWorkspace ) { sharedTSWorkspace = [[self class] new]; } return sharedTSWorkspace; } - (id)init { id theCenter = [[NSWorkspace sharedWorkspace] notificationCenter]; self = [super init]; if( !self ) return nil; // So lets register for the interesting notifications. [theCenter addObserver:self selector:@selector(externalAppLaunched:) name:NSWorkspaceDidLaunchApplicationNotification object:nil]; [theCenter addObserver:self selector:@selector(externalAppTerminated:) name:NSWorkspaceDidTerminateApplicationNotification object:nil]; return self; } - (void)dealloc { [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self]; [runningApps release]; [mountedDrives release]; [super dealloc]; } - (NSArray *)runningApplications { if( !runningApps ) { id psData; id outputString; id outputLines; int i; int n; id psInfoParts; id aString; runningApps = [NSMutableArray new]; // During startup we will fill it with all the "machLaunched" apps that we can find by checking the processes command // /bin/ps... however.. on NT this won't work... so let's not try it if the file does not exist. // This is quite ugly but with the limited functionality of the NSWorkspace class this is the easiest way // to get our hands on the list of runnign processes. psData = [NSTask outputOfCommand:@"/bin/ps -xwww"]; outputString = [[NSString alloc] initWithData:psData encoding:NSASCIIStringEncoding]; // NSLog( @"Found ps report: \n%@", outputString ); // Ok..thius is really brutal hardcoded evil behavior...but hey.. it works. outputLines = [outputString componentsSeparatedByString:@"\n"]; for( i=0; i<[outputLines count]; i++ ) { psInfoParts = [[[outputLines objectAtIndex:i] stringByTrimmingSpaces] componentsSeparatedByString:@" "]; if( [psInfoParts containsObject:@"-MachLaunch"] ) { for( n=4; n<[psInfoParts count]; n++ ) { aString = [psInfoParts objectAtIndex:n]; if( [aString hasPrefix:@"/"] ) { [runningApps addObject:[aString stringByDeletingLastPathComponent]]; break; } } } } [outputString release]; } return runningApps; } - (NSArray *)mountedDrives { if( !mountedDrives ) mountedDrives = [NSMutableArray new]; return mountedDrives; } - (void)externalAppLaunched:(NSNotification *)notification { id appPath = [[notification userInfo] objectForKey:@"NSApplicationName"]; // This is ugly since we should somehow be able to "track" the PIDs of the running processes...welll... [(NSMutableArray *)[self runningApplications] addObject:appPath]; // Sorting is disabled right now so that the Workspace really is the first...so we get teh apps in startup // time order.. at least somehow startuptime dependant. // [runningApps autorelease]; // runningApps = [[runningApps sortedArrayUsingSelector:@selector(compareByLastPathComponent:)] mutableCopy]; // NSLog( @"Workspace started application: %@", appPath ); [[NSNotificationCenter defaultCenter] postNotificationName:@"ProcessesListChanged" object:self]; } - (void)externalAppTerminated:(NSNotification *)notification { id appPath = [[notification userInfo] objectForKey:@"NSApplicationName"]; // NSLog( @"Workspace terminated application: %@", appPath ); [(NSMutableArray *)[self runningApplications] removeObject:appPath]; [[NSNotificationCenter defaultCenter] postNotificationName:@"ProcessesListChanged" object:self]; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.