get image icon of running applications in daemon

I need to get image icon of running applications in daemon.

I have found the method iconForFile.

[[NSWorkspace sharedWorkspace] iconForFile: bundlePath];

However, as far as I know, the framework AppKit is not daemon-safe. https://developer.apple.com/library/archive/technotes/tn2083/_index.html

So, the only way which I see is to get icon file path via parsing Info.plist.

However, the icon is not defined for some system app, e.g.: /System/Applications/Calendar.app /System/Applications/System Settings.app Are there any way to get icons of system application in daemon code?

Is it safe to use NSBundle in daemon code?

Thank you in advance.

Answered by DTS Engineer in 798108022

I need to get image icon of running applications in daemon.

Why? What are you trying to do this "for"?

I have found the method iconForFile. [[NSWorkspace sharedWorkspace] iconForFile: bundlePath]; However, as far as I know, the framework AppKit is not daemon-safe.

Correct, and NSWorkspace and "iconForFile" are definitely NOT daemon safe, as they ultimately call into LaunchServices with is specifically part of the "Agent" context.

So, the only way which I see is to get icon file path via parsing Info.plist.

No, that won't work. Getting the icon for any object very quickly devolves into a vast collection of details and edge cases, all piled on top of each other. The only thing I'm confident of is that anyone trying to list "all" of the possibilities has missed SOMETHING.

Case in point:

However, the icon is not defined for some system app, e.g.: /System/Applications/Calendar.app /System/Applications/System Settings.app Are there any way to get icons of system application in daemon code?

No, because this isn't a "system application" issue. Both of those apps are using a dock tile plugin* to specify their "icon". That's a general plugin option any app can use.

*I don't know why "System Settings.app" does this, but this is how "Calendar.app" makes it's icon show current date.

However, that situation is actually worse than that. NSDockTilePlugin let you control your icon when you're not running, but an apps that's actually running doesn't need to do ANYTHING "extra". They can just change their icon directly through NSApplication, either using a fancy dock tile or by specifying an image.

Keep in mind that this also means that icons can be user specific, not just system wide.

Jumping back to here:

So, the only way which I see is to get icon file path via parsing Info.plist.

No. The correct answer to "how do I access agent specific data from a daemon" is specifically described in the great classic of this genre, "TN2083 Daemons and Agents":

_
"The correct solution to this problem is to split your program into multiple components, each specialized for a particular role. So, you might have a daemon for managing the global state and an agent operating on behalf of each of the logged in users. If the daemon needs the user to answer a question, it signals all the agents and the agents use local knowledge to decide what to do. For example, the agent might behave differently depending on whether it's running in a GUI or non-GUI login session, or whether the GUI session is active (that is, using the console in a fast user switched environment)."
_

I started by asking "why" and the architecture above is why I asked. In my experience, deamon's are never looking for just ONE piece of user context data. Typically, they've been resisting for awhile the architecture by changing requirements or finding tricks/hacks until they run into a case they just can't avoid. The upside here is that adopting this approach not only solves the immediate issue, it also means that you can more easily address whatever other issues you've been avoiding.

Is it safe to use NSBundle in daemon code?

Yes. NSBundle is part of Foundation and Foundation is specifically documented as "daemon safe".

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Accepted Answer

I need to get image icon of running applications in daemon.

Why? What are you trying to do this "for"?

I have found the method iconForFile. [[NSWorkspace sharedWorkspace] iconForFile: bundlePath]; However, as far as I know, the framework AppKit is not daemon-safe.

Correct, and NSWorkspace and "iconForFile" are definitely NOT daemon safe, as they ultimately call into LaunchServices with is specifically part of the "Agent" context.

So, the only way which I see is to get icon file path via parsing Info.plist.

No, that won't work. Getting the icon for any object very quickly devolves into a vast collection of details and edge cases, all piled on top of each other. The only thing I'm confident of is that anyone trying to list "all" of the possibilities has missed SOMETHING.

Case in point:

However, the icon is not defined for some system app, e.g.: /System/Applications/Calendar.app /System/Applications/System Settings.app Are there any way to get icons of system application in daemon code?

No, because this isn't a "system application" issue. Both of those apps are using a dock tile plugin* to specify their "icon". That's a general plugin option any app can use.

*I don't know why "System Settings.app" does this, but this is how "Calendar.app" makes it's icon show current date.

However, that situation is actually worse than that. NSDockTilePlugin let you control your icon when you're not running, but an apps that's actually running doesn't need to do ANYTHING "extra". They can just change their icon directly through NSApplication, either using a fancy dock tile or by specifying an image.

Keep in mind that this also means that icons can be user specific, not just system wide.

Jumping back to here:

So, the only way which I see is to get icon file path via parsing Info.plist.

No. The correct answer to "how do I access agent specific data from a daemon" is specifically described in the great classic of this genre, "TN2083 Daemons and Agents":

_
"The correct solution to this problem is to split your program into multiple components, each specialized for a particular role. So, you might have a daemon for managing the global state and an agent operating on behalf of each of the logged in users. If the daemon needs the user to answer a question, it signals all the agents and the agents use local knowledge to decide what to do. For example, the agent might behave differently depending on whether it's running in a GUI or non-GUI login session, or whether the GUI session is active (that is, using the console in a fast user switched environment)."
_

I started by asking "why" and the architecture above is why I asked. In my experience, deamon's are never looking for just ONE piece of user context data. Typically, they've been resisting for awhile the architecture by changing requirements or finding tricks/hacks until they run into a case they just can't avoid. The upside here is that adopting this approach not only solves the immediate issue, it also means that you can more easily address whatever other issues you've been avoiding.

Is it safe to use NSBundle in daemon code?

Yes. NSBundle is part of Foundation and Foundation is specifically documented as "daemon safe".

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thank you a lot for clear cut explanation and tips!

get image icon of running applications in daemon
 
 
Q