次のAppleScriptを検討してください。
on is_running(appName)
tell application "System Events" to (name of processes) contains appName
end is_running
set safRunning to is_running("Safari")
if safRunning then
tell application "Safari"
-- Stuff I only want executed if Safari is running goes here.
end tell
return "Running"
else
return "Not running"
end if
問題:osascript
コマンドラインユーティリティを使用してこれを実行すると、Safariが実行されていない場合、Safariが起動し、スクリプトが「実行中」と報告します。これは、私が望んでいる、または期待する動作ではありません。 AppleScript Editor内で実行すると、期待どおりに動作することに注意してください。
これはosascript
バグ/既知の問題ですか?それとも私が行方不明の理由で何らかの形で意図された動作ですか?誰でも希望どおりに動作させることができますか? (ところで、OSX 10.7.5を実行しています。osascript
を取得してバージョン番号を報告する方法がわかりません)。
tell
/end tell
行をコメントアウトすると、期待どおりに動作します。Safariが実行されていない場合、Safariは起動せず、「Not running」と出力されます。 seemsは、tell
がSafariを起動する原因になっているように思えますが、実際に実行する必要はなく、スクリプトに存在するだけです...?しばらくの間、これは単にtell
がどのように機能するかを疑問に思っていましたが、AppleScript Editorではdoes n'tのように機能するので、そうではないと思います...
実際、同様の動作をする別のバージョンのhereがあります。
on is_running(appName)
tell application "System Events" to (name of processes) contains appName
end is_running
set safRunning to is_running("Safari")
return safRunning
if false then
tell application "Safari"
end tell
end if
tell
がreturnステートメントの後のif false
ブロック内にある場合でも、これは常にSafariを起動します! (ただし、これはAppleScript Editorでは問題ありません。)
ところで、この動作はSafariに限定されませんが、普遍的でもありません。
だから、私はこれをどのように修正するかルーティングするかについてアイデアを持っていますか? osascript
のバグですか?または、AppleScriptのセマンティクスについて何かが欠けていますか?
コンテキストの場合:開いているブラウザのタブのURLを開いているブラウザに照会するスクリプト(埋め込みまたはPythonから呼び出される)を作成しようとしています。すべて正常に動作しています除く開いているかどうかにかかわらず、常にSafariを起動します。この望ましくない動作を、上記の簡単なテストケースに要約しました。 osascript
を使用せずにpythonからこのスクリプトを実行する方法は、 appscript 以外は知りません。 開発/サポート/推奨されなくなった であるため使用します。
すべての入力/洞察に感謝します!
これを取得している理由は、osascriptを使用してコマンドラインからスクリプトを呼び出すたびに、スクリプトがコンパイルされているためと思われます。
tell applicationでコンパイルする行為により、アプリが起動します。
プリコンパイルされたファイルからのosascriptを使用してコマンドラインからスクリプトを呼び出します。つまり、.scptは、実行されるコンパイルがないため、この動作を引き起こしません。
ただし、プレーンテキスト(.txt、.sh)ファイルから呼び出すと、アプリが起動します。
.scptファイルを使用したくない場合、およびプレーンテキストファイルを使用する場合は、AppleScriptにrun scriptコマンドを挿入するトリックを試すことができます。
on is_running(appName)
tell application "System Events" to (name of processes) contains appName
end is_running
set safRunning to is_running("Safari")
if safRunning then
run script "tell application \"Safari\"
open location \"http://google.com\"
end tell"
return "Running"
else
return "Not running"
end if
run scriptのスクリプトは、必要な場合にのみコンパイルされます。私の例のように引用符のような文字をエスケープする必要があります。
最初に通常のapplescriptドキュメントにスクリプトを記述し、コンパイルしてエラーをチェックする方が簡単です。
次に、それをプレーンテキストファイルにコピーします。
[〜#〜] update [〜#〜] **
上記で使用した方法は、ここで答える前にこの問題を解決するために使用していた古いスクリプトからでした。
答えは機能し、エレガントにしようとするものではありません。 ;-)
私は実際にser1804762メソッドが好きです。それは機能しますが、答えが十分に明確ではないと感じているため、使用例を示します。
set appName to "Safari"
if application appName is running then
tell application id (id of application appName)
open location "http://google.com"
end tell
return "Running"
else
return "Not running"
end if
このスクリプトは、コマンドラインからosascriptを使用して実行できます
例:
osascript /Users/USERNAME/Desktop/foo.scpt
スクリプトがコンパイル済みスクリプトとして保存されていることに注意してください。これは問題なく動作し、プレーンテキストスクリプトとして保存して使用することもできます。
つまり.
osascript /Users/USERNAME/Desktop/foo.applescript
いくつかの情報:
「強化されたアプリケーションオブジェクトモデル」:
tell application "iTunes"
if it is running then
pause
end if
end tell
そのようにすることもできます:
if application "iTunes" is running then
tell application "iTunes" to quit
end if
これも行うことができます:
get name of application "iTunes"
get version of application "iTunes"
そして旅を完了するには:
get id of application "TextEdit" --> "com.Apple.TextEdit"
tell application id "com.Apple.TextEdit"
make new document
end tell
それが「拡張アプリケーションオブジェクトモデル」でした。アプリがまだ起動する場合(たとえば、最初にスクリプトをコンパイルして実行する場合)は、ASがアプリが辞書にない情報(またはそのようなもの...? )。
わかりました、この質問は本当に古いことを知っていますが、別の問題を探すためにつまずいて、これらの応答のいくつかがどれほど複雑であるかを検討しなければなりませんでした。
目的を達成するための簡単なコードは次のとおりです。
tell application "System Events"
if application process "Safari" exists then
-- do stuff you want to do only if Safari exists
end if
end tell
古いシステムでは、構文usedは次のようになります。
tell application "System Events"
if exists of application process "Safari" is true then
-- do stuff you want to do only if Safari exists
end if
end tell
これらの1つは間違いなくあなたのために働くはずです、Applescriptソリューションの勇敢な検索者は、アプリが実行されているときのみアクションを実行します。
Oh!ボーナスヒント:そして、アプリケーションプロセス名が正確にわからない場合(通常はですが、alwaysアプリ名ではありません)、最終的なスクリプトの実行をコーディングする前に…
tell application "System Events"
get every application process
end tell
結果でアプリのプロセス名を見つけます。
以下は、そのコマンドを実行する画面の一部です。 (無数のGoogle Chrome Helperインスタンス。ありがとうGoogle!)
HTH!
ただし、以前に行われたすべての回答には同じ問題があります。
名前でアプリを探します。ただし、ユーザーがアプリの名前を変更すると、実際にはアプリは実行されますが、スクリプトはアプリが実行されないと判断します。
実行中のアプリを適切に確認するには、ユーザーが変更できないバンドルIDで見つける必要があります。
バンドルIDは、たとえば次のコマンドで照会できます。
tell application "System Events"
get bundle identifier of application process "Safari"
end tell
特定のバンドルIDを持つアプリが実行されているかどうかを確認するには、次のコードを使用します。
tell application "System Events"
set ids to bundle identifier of every application process
if ids contains "com.Apple.safari" then
return "Running"
else
return "Not running"
end if
end tell
さらに、アプリが実行されているかどうかを確認し、終了してから再起動し、以前実行されていたものとまったく同じアプリが再起動され、他のコピーも存在しないことを確認する例を次に示します:
set bundleID to "com.Apple.safari"
set apps to runningApps(bundleID)
set appCount to length of apps
if appCount is not 0 then
quit application id bundleID
repeat while length of runningApps(bundleID) = appCount
-- wait for the app to quit
end repeat
open first item of apps
end if
on runningApps(bundleID)
-- The try block is to catch the rare case of having more than one
-- copy of an app running at the same time. Unfortunately, in that
-- case this code will not run as expected, because we don't get the
-- correct list of multiple items back then. But at least the script
-- will not crash from it but handle it gracefully.
tell application "System Events"
try
return application file of (every application process whose bundle identifier = bundleID)
end try
end tell
return {}
end runningApps
tell application "Finder"
set applicationsnames to get the name of every process whose visible is true
end tell
set appName to "Safari"
if applicationsnames does not contain appName then
say (appName & " is not running")
--add here what you want to happen
end if
return applicationsnames
これは私のために{"Finder", "JavaAppLauncher", "firefox", "Microsoft Word", "iTunes", "AppleScript Editor"}
を返しています
お役に立てれば
VLCまたはiTunesを再生/一時停止するAppleScript(BetterTouchToolジェスチャによってトリガーされる)を設定しようとして、ここで説明したのと同じ問題がありましたが、VLCが実行されていない場合はiTunesのみ(私のワークフローのため)、当然ながらVLCのみが実行中です。 (VLCの設定でiTunesの自動一時停止/再生トリガーを使用して、アプリを起動および終了します。)
VLCは、BTTを再起動するたびにBetterTouchToolトリガーを最初に使用したときに常に起動され、その時点で辞書キャッシュが削除され、AppleScriptハンドラーは、スクリプトを呼び出すためにテルを目的とする場合、すべてのスクリプトアプリケーションを起動する必要があります辞書。
これを回避するものはどこにも見つかりませんでした。いくつかの試みがありましたが、スクリプトハンドラーによる辞書呼び出しは私たちが影響を与えることができるものではないため、私にとってはうまくいきませんでした。私はこの汚い回避策を思いつきました:
これにより、アプリケーション(私の場合はVLC)を直接呼び出すのではなく、スクリプトのみを呼び出すスクリプトの最初のコンパイルが行われます。つまり、アプリケーションを起動する必要はありません。
その個別のファイルが呼び出されたらVLCを起動する必要がありますが、VLCに何かを伝えるためにそのファイルを呼び出すと、とにかくVLCが既に開かれている(または開かれる)ことになります。
BetterTouchToolトリガー(この場合はトラックパッドの特定のタップ)を介して呼び出すAppleScriptは、次のようになります。
if application "iTunes" is running and not application "VLC" is running then
tell application "iTunes" to playpause
アプリケーション「VLC」が実行されている場合は終了し、スクリプト「/Users/jannis/bin/PlayVLC.scpt」を実行します
別のAppleScriptファイル( "PLayVLC.scpt、このような目的のために以前に手動で作成したユーザーフォルダーの" bin "というフォルダーに保存)は、これだけです。
tell application "VLC" to play
そのスクリプトを手動で開くと、もちろんVLCも起動します。しかし、願わくば、それは頻繁に、またはこれまで必要ではないでしょう。
私はプロのコーダーではないので、これが私が知らないより深い問題を引き起こすかどうかは、実際にはわかりません。もしそうなら、私に通知してください。これが誰にも役立つことを願っています!