Macos 只有一个FireMonkey应用程序实例

Macos 只有一个FireMonkey应用程序实例,macos,delphi,delphi-xe2,instance,firemonkey,Macos,Delphi,Delphi Xe2,Instance,Firemonkey,使用FireMonkey和多平台应用程序(Windows+MacOSX),如何让应用程序的仅一个实例同时运行 如果以前的实例已在运行,如何将其设置为桌面前台窗口 我可以检查文件是否已锁定: 未锁定:我锁定它并正常运行 锁定:查找以前的版本(在windows上,我知道如何..但在mac上?),并将其设置为前景窗口 我可以检查同一进程启动了多少次(同上,在windows上,可以,但在Mac OS X上如何启动) 对于Windows和OSX,您可以获取正在运行的应用程序的列表,并在关闭前检查您

使用FireMonkey和多平台应用程序(Windows+MacOSX),如何让应用程序的仅一个实例同时运行

如果以前的实例已在运行,如何将其设置为桌面前台窗口

  • 我可以检查文件是否已锁定:
    • 未锁定:我锁定它并正常运行
    • 锁定:查找以前的版本(在windows上,我知道如何..但在mac上?),并将其设置为前景窗口
  • 我可以检查同一进程启动了多少次(同上,在windows上,可以,但在Mac OS X上如何启动)

对于Windows和OSX,您可以获取正在运行的应用程序的列表,并在关闭前检查您的应用程序是否在列表中。在OSX中,您可以使用NSWorkspace的lauchedApplications方法获取列表,在Windows中,您可以使用toolhelp32库实现相同的目的。 以下是我在我的网站上写的TPlatformExtensions类的相关代码

对于OSX:

uses Macapi.AppKit, Macapi.Foundation;

class procedure TPlatformExtensionsMac.GetRunningApplications(
  Applist: TStringlist);
var
  fWorkSpace:NSWorkSpace;
  list:NSArray;
  i: Integer;
  lItem:NSDictionary;
  key,value: NSString;
begin
  fWorkSpace := TNsWorkspace.Wrap(TNsWorkSpace.OCClass.sharedWorkspace);
  list := fWorkspace.launchedApplications;
  if (List <> nil) and (List.count > 0) then
  begin
    for i := 0 to list.count-1 do
    begin
      lItem := TNSDictionary.Wrap(List.objectAtIndex(i));
      key := NSSTR(String(PAnsiChar(UTF8Encode('NSApplicationBundleIdentifier'))));
      // You can also use NSApplicationPath or NSApplicationName
      value := TNSString.Wrap(lItem.valueForKey(key));
      Applist.Add(String(value.UTF8String));
    end;
  end;
end; 
<代码>使用MACAPI .AppKIT、MACAPI、基金会; 类过程TPlatformExtensionsMac.GetRunningApplications( 申请者:TStringlist); 变量 f工作空间:NSWorkSpace; 名单:NSArray; i:整数; lItem:NSDictionary; 键,值:NSString; 开始 fWorkSpace:=TNsWorkspace.Wrap(TNsWorkspace.OCClass.sharedWorkspace); 列表:=fWorkspace.LaunchedApplication; 如果(List nil)和(List.count>0),则 开始 对于i:=0到list.count-1 do 开始 lItem:=TNSDictionary.Wrap(List.objectAtIndex(i)); key:=NSSTR(字符串(PAnsiChar(UTF8Encode('NSApplicationBundleIdentifier'))); //您还可以使用NSApplicationPath或NSApplicationName 值:=TNSString.Wrap(lItem.valueForKey(key)); Add(String(value.UTF8String)); 结束; 结束; 结束; 对于Windows:

uses Winapi.TlHelp32, Winapi.Windows;

class procedure TPlatformExtensionsWin.GetRunningApplications(
  Applist: TStringlist);
var
 PE: TProcessEntry32;
 Snap: THandle;
 fName: String;
begin
  pe.dwsize:=sizeof(PE);
  Snap:= CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if Snap <> 0 then
  begin
    if Process32First(Snap, PE) then
    begin
     fName := String(PE.szExeFile);
     Applist.Add(fName);
     while Process32Next(Snap, PE) do
     begin
       fName := String(PE.szExeFile);
       Applist.Add(fName);
     end;
    end;
    CloseHandle(Snap);
  end;
end; 
使用Winapi.TlHelp32、Winapi.Windows;
类过程TPlatformExtensionsWin.GetRunningApplications(
申请者:TStringlist);
变量
PE:tprocesentry32;
Snap:THandle;
fName:字符串;
开始
pe.dwsize:=sizeof(pe);
快照:=CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS,0);
如果快照为0,则
开始
如果先处理32(快照、PE),则
开始
fName:=字符串(PE.szExeFile);
Applist.Add(fName);
而Process32Next(快照、PE)则执行
开始
fName:=字符串(PE.szExeFile);
Applist.Add(fName);
结束;
结束;
闭合手柄(按扣);
结束;
结束;

如果您需要有关该主题的更多信息,可以阅读我的主题说明。

此外,我希望您不要在Windows上执行基于文件的操作。使用命名的互斥体。自从Vista以来,我对互斥体有一些问题。。。但也许我在记忆中混合了不同的问题(比如互斥和服务等);o) 顺便说一句。。。我知道这不应该发生在Mac上。。。但正如在其他问题中所解释的,如果复制应用程序,则可能会发生这种情况。。。这让我烦恼;o) 尽管如此,在所有平台上都需要互斥。