Could not find application running with another user (via switch user)

Use case : I log in as " user1 " and start Safari, then I click " user1 " in the upper right corner and switch user " user2 ". Now I am trying to determine if Safari works for " user1 ", but I cannot do this with standard calls. I am using OS X 10.8 Mountain Lion to develop and run my code.

I used the following, but in vain:

  • [[NSWorkspace sharedWorkspace] runningApplications] - Safari does not exist in the list
  • GetNextProcess() - Safari does not appear
  • GetProcessForPID() - I get a "no such process" error

But when I do ps -aef | grep Safari ps -aef | grep Safari from the terminal, I can see Safari. (This applies not only to Safari, but also to other applications.)

Someone can help. Thank you very much.

+4
source share
1 answer

You can use the sysctl or ps command to list all BSD processes. See Technical Q & A QA1123

 #include <sys/sysctl.h> #include <pwd.h> typedef struct kinfo_proc kinfo_proc; static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount) // Returns a list of all BSD processes on the system. This routine // allocates the list and puts it in *procList and a count of the // number of entries in *procCount. You are responsible for freeing // this list (use "free" from System framework). // On success, the function returns 0. // On error, the function returns a BSD errno value. { int err; kinfo_proc * result; bool done; static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 }; // Declaring name as const requires us to cast it when passing it to // sysctl because the prototype doesn't include the const modifier. size_t length; // assert( procList != NULL); // assert(*procList == NULL); // assert(procCount != NULL); *procCount = 0; // We start by calling sysctl with result == NULL and length == 0. // That will succeed, and set length to the appropriate length. // We then allocate a buffer of that size and call sysctl again // with that buffer. If that succeeds, we're done. If that fails // with ENOMEM, we have to throw away our buffer and loop. Note // that the loop causes use to call sysctl with NULL again; this // is necessary because the ENOMEM failure case sets length to // the amount of data returned, not the amount of data that // could have been returned. result = NULL; done = false; do { assert(result == NULL); // Call sysctl with a NULL buffer. length = 0; err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0); if (err == -1) { err = errno; } // Allocate an appropriately sized buffer based on the results // from the previous call. if (err == 0) { result = malloc(length); if (result == NULL) { err = ENOMEM; } } // Call sysctl again with the new buffer. If we get an ENOMEM // error, toss away our buffer and start again. if (err == 0) { err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0); if (err == -1) { err = errno; } if (err == 0) { done = true; } else if (err == ENOMEM) { assert(result != NULL); free(result); result = NULL; err = 0; } } } while (err == 0 && ! done); // Clean up and establish post conditions. if (err != 0 && result != NULL) { free(result); result = NULL; } *procList = result; if (err == 0) { *procCount = length / sizeof(kinfo_proc); } assert( (err == 0) == (*procList != NULL) ); return err; } + (NSArray*)getBSDProcessList { kinfo_proc *mylist =NULL; size_t mycount = 0; GetBSDProcessList(&mylist, &mycount); NSMutableArray *processes = [NSMutableArray arrayWithCapacity:(int)mycount]; for (int i = 0; i < mycount; i++) { struct kinfo_proc *currentProcess = &mylist[i]; struct passwd *user = getpwuid(currentProcess->kp_eproc.e_ucred.cr_uid); NSMutableDictionary *entry = [NSMutableDictionary dictionaryWithCapacity:4]; NSNumber *processID = [NSNumber numberWithInt:currentProcess->kp_proc.p_pid]; NSString *processName = [NSString stringWithFormat: @"%s",currentProcess->kp_proc.p_comm]; if (processID)[entry setObject:processID forKey:@"processID"]; if (processName)[entry setObject:processName forKey:@"processName"]; if (user){ NSNumber *userID = [NSNumber numberWithUnsignedInt:currentProcess->kp_eproc.e_ucred.cr_uid]; NSString *userName = [NSString stringWithFormat: @"%s",user->pw_name]; if (userID)[entry setObject:userID forKey:@"userID"]; if (userName)[entry setObject:userName forKey:@"userName"]; } [processes addObject:[NSDictionary dictionaryWithDictionary:entry]]; } free(mylist); return [NSArray arrayWithArray:processes]; } 
+11
source

All Articles