2012-07-23 18 views
12

Estoy intentando crear una aplicación que solo tendrá un icono de bandeja y no aparecerá en la barra de tareas. (similar a Dropbox) Necesito crear la versión para Windows y Mac de la aplicación, así que traté de usar MonoMac para crear el front-end de Mac.¿Cómo puedo hacer una aplicación C# con solo un icono de bandeja en MonoMac (sin icono de dock)?

¿Cuál es la mejor manera de crear una aplicación de solo bandeja en MonoMac?

Todos los recursos que he encontrado dicen que hacer una de dos cosas:

  • Añadir <key>LSUIElement</key><string>1</string> al archivo Info.plist.
  • Agregue el código siguiente al evento FinishedLaunching en la clase AppDelegate: NSApplication.SharedApplication.ActivationPolicy = NSApplicationActivationPolicy.Accessory;

que han intentado todas las combinaciones de estos dos, pero parece que en cuanto trato de crear instancias de un C# System.Timers.Timer, el icono reaparece en el dock en la parte inferior de la pantalla. ¿Me falta algo acerca de cómo OSX maneja las aplicaciones de fondo?

¿Qué estoy haciendo mal? ¿Hay una mejor manera de hacer una aplicación en segundo plano que tenga un icono de bandeja superior pero no un icono de base en OSX?

(Esto es muy similar a esta SO question, pero esa pregunta fue desde hace un par de años y nunca fue respondida por completo, así que espero que podría haber una respuesta más completa que hay.)


Aquí está el código que tengo hasta ahora:

public partial class AppDelegate : NSApplicationDelegate 
{ 
    MyServiceObject currentServiceObject; 

    public AppDelegate() { } 

    public override void FinishedLaunching (NSObject notification) 
    { 
     // Construct menu that will be displayed when tray icon is clicked 
     var notifyMenu = new NSMenu(); 
     var exitMenuItem = new NSMenuItem("Quit My Application", 
      (a,b) => { System.Environment.Exit(0); }); // Just add 'Quit' command 
     notifyMenu.AddItem(exitMenuItem); 

     // Display tray icon in upper-right-hand corner of the screen 
     var sItem = NSStatusBar.SystemStatusBar.CreateStatusItem(30); 
     sItem.Menu = notifyMenu; 
     sItem.Image = NSImage.FromStream(System.IO.File.OpenRead(
      NSBundle.MainBundle.ResourcePath + @"/notify-icon.icns")); 
     sItem.HighlightMode = true; 

     // Remove the system tray icon from upper-right hand corner of the screen 
     // (works without adjusting the LSUIElement setting in Info.plist) 
     NSApplication.SharedApplication.ActivationPolicy = 
      NSApplicationActivationPolicy.Accessory; 

     // Start running the program -- If I comment out then no dock icon appears 
     currentServiceObject = new MyServiceObject(); 
    } 
} 
+0

amor saber la respuesta a esto también! – berg

Respuesta

6

me encontré con el problema, y ​​no estaba relacionado con la configuración de la aplicación en absoluto. Evidentemente, hay algunas operaciones que MacOS no permite que realicen 'aplicaciones de un agente'. Tan pronto como se invoca uno de esos métodos, la aplicación se ve obligada a aparecer en el dock. El código que fue tropezando con mi solicitud era una llamada a:

System.Windows.Forms.Cursor.Position.ToString() 

Extracción de esa línea, y su sustitución por el siguiente método MonoMac la aplicación puede permanecer oculto:

NSEvent.CurrentMouseLocation.ToString() 
2

yo era capaz de conseguir este trabajo estableciendo el valor de la "Solicitud es agente (UIElement)" clave en 1 en el archivo info.plist. A pesar de que debería ser un valor BOOL, MonoDevelop lo convierte en una cadena, pero establecerlo en 1 parece funcionar. También puede establecer una cadena vacía para el "Archivo de icono" pero no es necesario.

info.plist

+0

Gracias por el consejo: lo intenté, pero desafortunadamente no sirvió. – Matt

+0

¿puedes compartir más código de tu aplicación? ¿Cómo se ve tu info.plist? ¿Qué hace MyServiceObject? – berg

Cuestiones relacionadas