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.