【问题标题】:Only one application instance with FireMonkey只有一个具有 FireMonkey 的应用程序实例
【发布时间】:2012-10-30 20:21:37
【问题描述】:

使用 FireMonkey 和多平台应用程序(Windows + Mac OS X),如何只有一个实例 同时运行的应用程序?

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

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

【问题讨论】:

  • 另外,我希望你不要在 Windows 上做基于文件的事情。使用命名互斥体。
  • 自 Vista 以来我遇到了一些互斥锁的问题......但也许我在记忆中混合了不同的问题(如互斥锁和服务......);o)
  • 顺便说一句...我知道这不应该在 Mac 上发生...但正如其他问题中所解释的那样,如果您复制应用程序,这可能会发生...这让我很困扰 ;o)
  • 同理,在所有平台上你需要的是互斥体。

标签: macos delphi delphi-xe2 instance firemonkey


【解决方案1】:

对于 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; 

对于 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; 

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

【讨论】:

    猜你喜欢
    • 2018-08-31
    • 1970-01-01
    • 2023-03-31
    • 2014-01-26
    • 2021-06-22
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-20
    相关资源
    最近更新 更多