控制台应用中的 Xamarin.Mac 绑定

在某些情况下,你希望使用 C# 中的某些 Apple 本机 API 通过 C# 生成无外设应用程序(不含用户界面)。

Mac 应用程序的项目模板包括对 NSApplication.Init()NSApplication.Main(args) 的依次调用,它通常如下所示:

static class MainClass {
    static void Main (string [] args)
    {
        NSApplication.Init ();
        NSApplication.Main (args);
    }
}

Init 的调用将准备 Xamarin.Mac 运行时,对 Main(args) 的调用将启动 Cocoa 应用程序主循环,该循环将准备应用程序以接收键盘和鼠标事件并显示应用程序的主窗口。 调用 Main 还将尝试查找 Cocoa 资源、准备一个顶级窗口,并期望程序成为应用程序捆绑包的一部分(程序分布在具有 .app 扩展名和非常特定布局的目录中)。

无外设应用程序不需要用户界面,也不需要作为应用程序捆绑包的一部分运行。

创建控制台应用

因此,最好从常规 .NET 控制台项目类型开始。

你需要执行一些操作:

  • 创建一个空的项目。
  • 引用 Xamarin.Mac.dll 库。
  • 将非托管依赖项引入项目。

下文对这些步骤进行了更详细的说明:

创建一个空的控制台项目

创建新的 .NET 控制台项目,确保它是 .NET,而不是 .NET Core,因为 Xamarin.Mac.dll 在 .NET Core 运行时下不运行,它只能在 Mono 运行时下运行。

引用 Xamarin.Mac 库

若要编译代码,需要从此目录引用 Xamarin.Mac.dll 程序集:/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/64bits/full

为此,请转到项目引用,选择“.NET 程序集”选项卡,然后单击“浏览”按钮以在文件系统中找到该文件。 导航到上面的路径,然后从该目录中选择 Xamarin.Mac.dll。

这样,就可以在编译时访问 Cocoa API。 此时,可以将 using AppKit 添加到文件顶部,并调用 NSApplication.Init() 方法。 在运行应用程序之前,只需再执行一个步骤。

将非托管支持库引入项目

在应用程序运行之前,需要将 Xamarin.Mac 支持库引入项目中。 为此,请将新文件添加到项目(在项目选项中依次选择“添加”和“添加现有文件”)并导航到此目录

/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/SDKs/Xamarin.macOS.sdk/lib

在此处,选择文件 libxammac.dylib。 可以选择复制、链接或移动。 我个人喜欢链接,但复制也有效。 接下来需要选择文件,然后在属性板(如果属性板不可见,请选择“视图”>“板”>“属性”)中,转到“生成”部分,并将“复制到输出目录”设置设定为“如果较新则复制”。

现在可以运行 Xamarin.Mac 应用程序。

bin 目录中的结果如下所示:

Xamarin.Mac.dll
Xamarin.Mac.pdb
consoleapp.exe
consoleapp.pdb
libxammac.dylib

若要运行此应用,需要所有这些文件位于同一目录中。

生成用于分发的独立应用程序

你可能想要将单个可执行文件分发给用户。 为此,可以使用 mkbundle 工具将各种文件转换为独立的可执行文件。

首先,请确保应用程序已编译并运行。 对结果感到满意后,可以从命令行运行以下命令:

$ mkbundle --simple -o /tmp/consoleapp consoleapp.exe --library libxammac.dylib --config /Library/Frameworks/Mono.framework/Versions/Current/etc/mono/config --machine-config /Library/Frameworks/Mono.framework/Versions/Current/etc/mono/4.5/machine.config
[Output from the bundling tool]
$ _

在上述命令行调用中,选项 -o 用于指定生成的输出,在本例中,我们传递了 /tmp/consoleapp。 现在,这是一个可用于分发的独立应用程序,在 Mono 或 Xamarin.Mac 上没有外部依赖项,因此是一个完全独立的可执行文件。

命令行手动指定了要使用的 machine.config 文件和系统范围的库映射配置文件。 它们并非所有应用程序所必需的,但捆绑它们很方便,因为当使用 .NET 的更多功能时会用到它们

不需要项目的生成

无需使用完整的项目即可创建独立的 Xamarin.Mac 应用程序,你也可以使用简单的 Unix 生成文件来完成相关作业。 以下示例演示如何为简单的命令行应用程序设置生成文件:

XAMMAC_PATH=/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/x86_64/full/
DYLD=/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib
MONODIR=/Library/Frameworks/Mono.framework/Versions/Current/etc/mono

all: consoleapp.exe

consoelapp.exe: consoleapp.cs Makefile
    mcs -g -r:$(XAMMAC_PATH)/Xamarin.Mac.dll consoleapp.cs
    
run: consoleapp.exe
    MONO_PATH=$(XAMMAC_PATH) DYLD_LIBRARY_PATH=$(DYLD) mono --debug consoleapp.exe $(COMMAND)

bundle: consoleapp.exe
    mkbundle --simple consoleapp.exe -o ncsharp -L $(XAMMAC_PATH) --library $(DYLD)/libxammac.dylib --config $(MONODIR)/config --machine-config $(MONODIR)/4.5/machine.config

以上 Makefile 提供了三个目标:

  • make 将生成程序
  • make run 将在当前目录中生成并运行程序
  • make bundle 将创建独立的可执行文件