2015-04-01 2 views
0

Может ли кто-нибудь подумать об обходном пути для обертки-указательного указателя по имени в виде ссылки на несколько экземпляров одного и того же приложения?Как можно адресовать два экземпляра одного и того же приложения через osascript

Если мы получим два идентификатора процесса - по одному для каждого из двух разных экземпляров одного и того же приложения, osascript возвращает тот же экземпляр в обмен на pid - как если бы он сначала сопоставлял pid с именем приложения, а затем извлекал первый процесс приложения с этим именем.

Например, запуск двух различных экземпляров VLC.app, играя два различных видео файлов, с чем-то вроде:

open -na /Applications/VLC.app ~/fileA.m4v 
open -na /Applications/VLC.app ~/fileB.m4v 

затем получить два отдельных идентификаторов процесса приложения с помощью, например:

echo "$(ps -ceo pid=,comm= | awk '/VLC/ { print $1}')" 

Мы можем использовать Javascript Applescript или Yosemite JXA для получения ссылки на объект приложения из любого pid.

Оказывается, однако, что независимо от того, какой идентификатор процесса мы поставляем, мы всегда возвращаем ссылку на один и тот же экземпляр, запускаем тот же видеофайл, как если бы osascript просто переводил pid в имя приложения, а затем всегда возвращал первый процесс, который соответствует этому имени.

Yosemite Javascript для приложений:

function run() { 
    var app = Application.currentApplication(); 
    app.includeStandardAdditions = true; 

    var lstVLC = app.doShellScript(
      "echo \"$(ps -ceo pid=,comm= | awk '/VLC/ { print $1}')\"" 
     ).split(/[\r\n]/).map(Number).map(Application); 

    return { 
     firstInstance: lstVLC[0].windows[0].name(), 
     secondInstance: lstVLC[1].windows[0].name() 
    }; 
} 

Applescript:

on run {} 
    set strCMD to "echo \"$(ps -ceo pid=,comm= | awk '/VLC/ { print $1}')\"" 
    set lstNum to paragraphs of (do shell script strCMD) 
    repeat with i from 1 to length of lstNum 
     set item i of lstNum to (item i of lstNum) as number 
    end repeat 


    tell application "System Events" 
     set oProcA to first application process where unix id = (item 1 of lstNum) 
     set oProcB to first application process where unix id = (item 2 of lstNum) 
    end tell 

    return [name of first window of oProcA, name of first window of oProcB] 
end run 

Любые мысли на пути к скриптовый каждый экземпляр отдельно?

ответ

1

Для каждого экземпляра, задать имя окна из одной и той же линии, как специфический процесс, как это:

set windowNames to {} 
set lstNum to paragraphs of (do shell script "ps -ceo pid=,comm= | awk '/VLC/ { print $1}'") 
tell application "System Events" to repeat with i in lstNum 
    set end of windowNames to name of first window of (first application process where unix id = i) 
end repeat 
return windowNames 
+0

Мы можем, конечно, получить свойства, открытые такими системными событиями, но это все равно не позволяет нам получить сценарий для объекта приложения для каждого из экземпляров. Если, например, мы спрашиваем JXA Javascript для экземпляра приложения pid, он просто дает нам первый экземпляр с соответствующей строкой имени, независимо от конкретного pid ... – houthakker

+0

Tho на вторых мыслях - ваш подход - хороший путь к обход объекта приложения и выполнение некоторых пользовательских скриптов ... – houthakker

0

Использование jackjr300 «s подход в Javascript, чтобы получить по крайней мере, в написании сценариев пользовательского интерфейса (хотя не для интерфейса объекта приложения):

function run() { 
    var appSE = Application("System Events"); 
    app = Application.currentApplication(); 

    app.includeStandardAdditions = true; 

    function uiWidgets(lngID) { 
     return appSE.processes.whose({ 
      unixId: lngID 
     })[0].windows[0].uiElements(); 
    } 

    var lstWidgets = app.doShellScript(
      "ps -ceo pid=,comm= | awk '/VLC/ { print $1}'" 
     ).split(/\r/).map(Number).map(uiWidgets); 

    return lstWidgets; 
} 
0

JXA - это набор ошибок и дефектного дизайна. Его неспособность делать такие вещи right удручает, но совершенно неудивительно (команда AS has form).

Что касается AppleScript, он никогда не предоставлял прямой доступ к целевым приложениям с помощью PID. Раньше я, возможно, обманул его, включив удаленные события Apple и нацелив процесс с URL-адресом eppc://[email protected]/APPNAME?pid=PID, но попробовал его сейчас 10.10, если бы я мог заставить его работать, поскольку он всегда возвращал ошибку «с удаленным доступом».

Appcript может делать это во сне, но я поддерживаю его общественную поддержку из-за войны Apple с Carbon и дерьмовой «замены» API-интерфейсов Cocoa, что приводит к «статусу наследия», поэтому вы сами по себе.

Официально поддерживаемая опция, которая может работать, представляет собой платформу Scripting Bridge от OS X, которая предоставляет метод для таргетинга процессов с помощью PID. Хотя, как JXA, он пронизан недостатками дизайна, отсутствием функций и проблемами совместимости приложений, поэтому YMWV.

1

Это, похоже, исправлено в El Capitan, так как ваш код JavaScript отлично работает на моей машине.

Смежные вопросы