在MacOSX下的.app是一个程序包(实际上是个目录),双击该目录时系统会根据包的目录结构启动相应的可执行程序。.app的程序默认是单实例运行的,所以从.app启动的程序实例只有一个(可执行程序不受该规则影响),操作系统根据Bundle identifier 做互斥处理。
如果你的.app支持多个参数启动不同的模块且都是跟窗口相关,那么在启动第二个.app的时候会自动激活第一个程序实例的窗口而不是再启动一个程序实例。
在Google查阅相关资料,得出的结论是
open -n /Applications/xxx.app
没有办法解决鼠标双击启动的问题,比如已经有个后台界面(不显示)程序在运行。双击后.app包后,已运行的程序会接收到applicationShouldHandleReopen消息,第二个程序并不启动。通过参考TeamViewer的二进制程序,通过不断的调试终于了解一点MacOSX的程序启动原理:
1. 程序包(Bundle)启动时互斥的,也就是正常的启动是只启动一个唯一实例,如果想启动多个只能通过以上的方式启动多个。
2. 即使给同一个程序包下的不同程序指定一个不同的Bundle identifier,如果都在同一Contents/MacOSMacOS下,正常启动结果还是唯一实例。
3. 即使给同一个程序包下的不同程序指定一个不同的Bundle identifier,且不在同一Contents/MacOS目录下,启动OK。
如何给程序指定不同的Bundle identifier?
增加链接选项(Other Link flags):
-sectcreate __TEXT __info_plist $(INFOPLIST_FILE)
参考:https://red-sweater.com/blog/2083/the-power-of-plist
记录!