2009-07-04 10 views
7

En Windows, es una práctica común crear un mutex con nombre y usar la presencia de eso para determinar que ya se está ejecutando una instancia de una aplicación determinada. Esto tiene sus inconvenientes, pero funciona principalmente.Forma ideal para aplicaciones de instancia única en Mac

No puedo pensar en una manera de hacer esto en el Mac:

  1. nombrados exclusiones mutuas pthread
  2. procesos Enumerar correr y buscar uno que coincida con
  3. crear y bloquear un archivo

¿Hay algo incorporado en Cocoa/Carbon que sea más fácil que las opciones anteriores? Si no, ¿cuál de los tres es el más utilizado en el mac? Supongo que 2 o 3 ...

+0

solo mirando cómo se inician las aplicaciones y con las que interactué No creí que fuera posible tener varias instancias ... Al menos no con aplicaciones empaquetadas en una buena .app – Cogsy

+0

Ok, hice un poco de trampa en mi pregunta. .. Realmente quería ejecutar una aplicación de prueba que hiciera un montón de validación pero iniciarla mientras se ejecutaba la aplicación causaba falsos positivos. Para no perder el tiempo persiguiendo problemas inútiles, quería que la aplicación de prueba rescatara con un error si la aplicación se está ejecutando. En Windows, lo resolví usando el enfoque de instancia única y asumí que quería hacer lo mismo para el mac. – psychotik

+0

[utilizado NSRunningApplication detectar si la aplicación con mismo BundleID se está ejecutando, activarlo y cerrar lo que comienza.] [1] [1]: http://stackoverflow.com/questions/684911/how-to- detectar-si-un-os-x-aplicación-ya-se lanzó/23775478 # 23775478 –

Respuesta

7

Los Mac no tienen instancias del mismo modo que Windows. En términos generales, quiere que la aplicación se ejecute dos veces, físicamente necesita copiar el archivo binario y luego hacer doble clic en la versión copiada también.

Si necesita dos instancias de una aplicación ejecutándose, entonces no está pensando como un usuario de Mac :).

Editar: Esto es técnicamente no es cierto. Verifica los comentarios.

+5

En otras palabras, no hay necesidad si estamos hablando de aplicaciones GUI. Ya funciona de esa manera. – Chuck

+16

Eso no es verdad. Si inicia la aplicación desde la terminal, por ejemplo, puede iniciar _N_ instancias simultáneamente. El hecho de que sea "poco común" no significa que el caso no deba tenerse en cuenta. – Dev

+0

Derecha. Incluso le daré un ejemplo simple, que creo que es bastante común: iniciar una aplicación desde el postinstall de un instalador. Si busca la aplicación y la inicia desde Spotlight, se ilumina la segunda instancia. –

1

La gestión de procesos de asignación entre sistemas operativos dispares no funciona. O no funciona bien Por defecto y sin un esfuerzo particular, obtienes una copia y solo una copia de la aplicación.

Aquí hay una pregunta anterior similar que va un paso más allá de esta pregunta actual, y con algunas respuestas que discuten el enclavamiento cuando hay múltiples copias de una imagen, o múltiples aplicaciones que necesitan coordinación.

How to detect whether an OS X application is already launched

Para una introducción al contexto en tiempo de ejecución, y en particular alrededor de Mac OS X demonios y agentes (y para aquellos casos en los que es necesario tener múltiples copias de una ejecución ejecutable, como una piscina o tal y similar a Apache), ver:

http://developer.apple.com/technotes/tn2005/tn2083.html

1

Si usted está escribiendo una aplicación Cocoa, puede utilizar NSWorkspace para ver si otro proceso está en marcha con su identificador de paquete. He visto algunas aplicaciones que presentan un diálogo y dicen: "Ya se está ejecutando una instancia de esta aplicación". Creo que Firefox lo hace, en realidad.

No es un enfoque muy "mac-ish", pero hará el trabajo.

+0

Esto es un poco lo que quiero hacer, pero mi aplicación de prueba no es una aplicación Cocoa (vea el comentario actualizado en mi Q anterior). Encontré GetNextProcess() en Carbon que podría ayudar ... ¿alguna otra sugerencia? – psychotik

8

Para más detalles sobre el uso de NSWorkspace. Intenta usar launchApplications en NSWorkspace. Esto devuelve un NSArray que contiene un diccionario para cada aplicación iniciada. Puede recorrer la matriz para ver si la aplicación que está buscando ya se está ejecutando. Le aconsejo que use el valor con la clave NSApplicationBundleIdentifier que tendrá un valor como "com.mycompany.myapp" en lugar de buscar el nombre. Si necesita encontrar el identificador del paquete para una aplicación, puede ver su archivo info.plist en el paquete de la aplicación.

+0

Esto es lo que quiero hacer, pero mi aplicación de prueba no es una aplicación Cocoa (consulte el comentario actualizado en mi Q anterior). Encontré GetNextProcess() en Carbon que podría ayudar ... ¿alguna otra sugerencia? – psychotik

+0

Esa sería la manera de hacerlo si usted es una aplicación de carbono. ¿Ya estás vinculado a la biblioteca de carbono? Sin embargo, la misma característica de instancia única también se aplica a las aplicaciones de Carbon. Parece que estás construyendo un programa de línea de comandos Unix, ¿es correcto? Puede ser útil describir lo que está construyendo con más detalle. –

+0

Tenga en cuenta que 'NSWorkspace -launchedApplications' se depreció en Mac OS X 10.7. Apple recomienda que ahora use 'NSWorkspace -runningApplications' en su lugar (10.6+): http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSWorkspace_Class/Reference/Reference.html# // apple_ref/occ/instm/NSWorkspace/runningApplications –

0

Si va a implementar su aplicación con Java Web Start (JWS), puede usar javax.jnlp.SingleInstanceService. El aprovisionamiento de JWS también proporcionará actualizaciones automáticas del programa.

Cuestiones relacionadas