Re: Better way than GetNextProcess()?
Re: Better way than GetNextProcess()?
- Subject: Re: Better way than GetNextProcess()?
- From: Chris Suter <email@hidden>
- Date: Wed, 23 May 2007 14:11:21 +1000
On 23/05/2007, at 10:25 AM, John Stiles wrote:
On May 22, 2007, at 5:20 PM, Bob Clark wrote:
On May 22, 2007, at 2:32 PM, Kam Dahlin wrote:
I have a background only app that I need to be able to check to
see if it is running. I have been looking for some nice simple
cocoa calls for this, and [[NSWorkspace sharedWorkspace]
launchedApplications] looked like the way, but it doesn't show
hidden apps. In my research I have run across GetNextProcess()
and it seems to be able to do what I want. However, it is going
to be a bit more involved so before I go and make that call work
I wanted to ask here if there was a better way for getting a list
of running applications, including those that are hidden?
Hi Kam.
If your background-only app really is an application, linked to
cocoa and/or carbon frameworks, then iterating through
GetNextProcess should work. But if it's actually a BSD level
program (a daemon or something you'd often run from the command
line) then it won't be registered as a process that the Process
Manager knows about. In that case you'll have to iterate over all
processes using sysctl().
http://developer.apple.com/qa/qa2001/qa1123.html
Even this technique isn't really usable because of a note in QA1361:
IMPORTANT: Because the definition of the kinfo_proc structure (in
<sys/sysctl.h>) is conditionalized by __APPLE_API_UNSTABLE, you
should restrict use of the above code to the debug build of your
program.
http://developer.apple.com/qa/qa2004/qa1361.html
Basically I think this struct can change between major OS releases
so you can't rely on it for shipping code.
(I filed a bug on QA1123 mentioning this but it's been open for
eons without any change in status.)
It looks like ps uses it (from looking at the source code).
Checking through the process list sounds to me like an ugly way of
doing this.
One alternative would be to use Mach ports. Here's some code I just
knocked up:
#include <mach/task_special_ports.h>
#include <mach/task.h>
#include <mach/mach_init.h>
#include <servers/bootstrap.h>
#include <stdio.h>
int main ()
{
mach_port_t bootstrap_port;
bootstrap_status_t service_active;
kern_return_t result;
task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
result = bootstrap_status(bootstrap_port,
"com.coriolis-systems.iDefrag.ServiceProvider",
&service_active);
if (result == BOOTSTRAP_SUCCESS) {
char *service_active_str[] = {"Inactive", "Active", "On Demand"};
printf ("%s\n", service_active_str[service_active]);
} else {
char *result_str[] = {"Not Privileged",
"Name In Use",
"Unknown Service",
"Service Active",
"Bad Count",
"No Memory"};
printf ("%s\n", result_str[result - BOOTSTRAP_NOT_PRIVILEGED]);
}
return 0;
}
I've never really used this stuff before so there might be better
ways of doing it. Also, the API I've used isn't well documented (and
so could be subject to change). There's a bit more documentation in
the Libc source code.
I'm not sure what would happen if your background app was in a
different login session. Also, I don't know if all processes register
'<bundle id>.ServiceProvider' with the bootstrap server. Cocoa
applications certainly do.
I've also just spotted NSMachBootstrapServer which would be worth
playing with and might be better approach.
What I'm suggesting isn't really Cocoa. There are Darwin lists that
are probably better for this.
- Chris
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden