13

我正在尝试创建一个只有托盘图标而不出现在任务栏中的应用程序。(类似于 Dropbox)我需要创建应用程序的 Windows 和 Mac 版本,所以我尝试使用 MonoMac 创建 Mac 前端。

在 MonoMac 中创建仅托盘应用程序的最佳方法是什么?

我发现的所有资源都说要做两件事之一:

  • 添加<key>LSUIElement</key><string>1</string>Info.plist文件中。
  • 将以下代码添加到类中的FinishedLaunching事件中AppDelegateNSApplication.SharedApplication.ActivationPolicy = NSApplicationActivationPolicy.Accessory;

我已经尝试了这两者的所有组合,但似乎一旦我尝试实例化 C# System.Timers.Timer,图标就会重新出现在屏幕底部的 Dock 中。我是否遗漏了有关 OSX 如何处理后台应用程序的信息?

我究竟做错了什么?有没有更好的方法来制作一个在 OSX 中具有上部托盘图标但没有底部停靠图标的后台应用程序?

(这与这个SO question非常相似,但这个问题是几年前提出的,从未得到完全回答,所以我希望那里可能有更完整的答案。)


这是我到目前为止的代码:

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();
    }
}
4

2 回答 2

7

我发现了问题,它根本与应用程序设置无关。显然,MacOS 不允许“代理应用程序”执行某些操作。一旦调用其中一种方法,应用程序就会强制出现在 Dock 中。使我的应用程序绊倒的代码是对以下内容的调用:

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

删除该行并用以下 MonoMac 方法替换它允许应用程序保持隐藏:

NSEvent.CurrentMouseLocation.ToString()
于 2012-08-03T23:21:54.863 回答
3

我可以通过在 info.plist 文件中将“Application is agent (UIElement)”键的值设置为 1 来完成这项工作。即使它应该是一个 BOOL 值,MonoDevelop 也将它变成一个字符串,但将其设置为 1 似乎可行。您还可以为“图标文件”设置一个空字符串,但这不是必需的。

信息列表

于 2012-07-29T06:37:35.400 回答