【问题标题】:Python and Applescript path of running application using a partial app name?使用部分应用程序名称运行应用程序的 Python 和 Applescript 路径?
【发布时间】:2021-03-28 01:47:54
【问题描述】:

我正在编写一个 Python 程序(试图坚持使用包含的模块),并且需要仅使用应用程序名称的一部分来获取在 MacOS 平台上打开/活动的应用程序的路径。 (例如,使用“Adobe Acrobat Reader DC”中的“Acrobat”)。在stdout中获取路径输出的正确applescript代码是什么? (如果 MacOS 上有更好的方法,请告诉我)。 (注意:在我的情况下需要是 subprocess.run 而不是 subprocess.Popen)

import subprocess

def get_window_path():
    cmd = """
        tell application "System Events",
          if (get name of every application process) contains "Acrobat" then
            return POSIX path of (path to ((get name of every application process) contains "Acrobat"))
          end if
        end tell
    """
    result = subprocess.run(['osascript', '-e', cmd], capture_output=True)
    return result.stdout

print(get_window_path())

【问题讨论】:

  • 你不能跳过 AppleScript 子进程并通过 PyObjC 桥使用 NSWorkspace 吗?
  • @red_menace 我会研究这个选项,还没有听说过,如果它足够简单,会很高兴看到它如何工作的解决方案。

标签: python applescript


【解决方案1】:

不知道如何从python 调用 AppleScript,但是...

以下示例 AppleScript 代码假设您只有一个应用程序正在运行,其中包含“Acrobat” name,否则您需要在 repeatloop 中处理从 系统事件 返回的 list

tell application "System Events" to ¬
    set appAcrobatList to the ¬
        name of every application process ¬
        whose background only is false ¬
        and name contains "Acrobat"

if appAcrobatList is not {} then ¬
    return POSIX path of ¬
        (path to application ¬
            (first item of appAcrobatList))

【讨论】:

    【解决方案2】:

    与其在 Python 和 AppleScript 之间来回切换,另一种选择是将所有内容都保留在 Python 中,并使用内置的PyObjC 桥接器来访问 Cocoa API。 AppleScript 的功能很好,但在这种情况下,您实际上并不需要使用它。

    我不是很擅长 Python,但以下使用 NSWorkspaceNSPredicate 过滤器(使用标准 Catalina 和 Big Sur 安装测试 - 请注意 Apple 使用旧版本):

    #!/usr/bin/env python
    
    from Cocoa import NSWorkspace, NSPredicate
    
    appName = "Acrobat"
    runningApps = NSWorkspace.sharedWorkspace().runningApplications()
    predicate = NSPredicate.predicateWithFormat_("localizedName contains[c] '%s'" % appName)
    results = runningApps.filteredArrayUsingPredicate_(predicate)
    
    if results == []:
       print("Matching Application Not Found")
    else:  # just get some values from the first match
       print(results[0].localizedName())
       print(results[0].bundleIdentifier())
       print(results[0].bundleURL().path())
    
    

    【讨论】:

      【解决方案3】:

      以下 AppleScript 解决方案将在应用程序运行时返回应用程序的路径。如果有多个,它还将返回应用程序所有正在运行的实例的路径(不需要repeat 循环)。

      property singleAppPath : missing value
      property multipleAppPaths : missing value
      
      tell application "System Events"
          set searchedApps to a reference to ¬
              ((every application process) whose name contains "Acrobat" or ¬
                  displayed name contains "Acrobat")
          if (count of searchedApps) is 1 then
              set singleAppPath to POSIX path of application file of searchedApps as text
          else if (count of searchedApps) > 1 then
              set multipleAppPaths to POSIX path of application file of searchedApps
          end if
      end tell
      

      【讨论】:

      • BTW 在我的系统上按名称属性搜索“Acrobat”会返回 {},但显示的名称会返回结果。根据System Events,它的名字是“AdobeReader”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多