Archive for the 'OSAScript' Category

2017/10/18 macOS 10.12から10.13のマシンを呼び出してAppleScriptをリモート実行

リモートAppleEventsを使ってmacOS 10.12上で編集中のScriptを10.13側で実行して結果を表示するScriptです。

リモートAppleEventsは、OSのバージョンが違っていても複数のMacを連携させたシステムを組めるので、知っている人は少ないとしても有用な機構です。ちょっと前のOSでないと動かない周辺機器(FAXとかドキュメントスキャナとか)を最新のOS環境から利用できたりもします(直接ドライブするのではなく、結果だけもらってきたり、入力があったことを通知したり)。

同一のLAN内で、固定のIPアドレスを振って運用しています。

figs.png

macOS 10.13側

macOS 10.13のMac側の「システム環境設定」の「共有」で、

share_resized.png

リモートAppleEventsをオンにします。AppleScriptをリモートで受信して実行するアプレット「RemoteAgent」を作成して起動しっぱなしの設定にして(アプレットとして保存するときに「ハンドラの実行後に終了しない」のオプションをオンに設定)保存し、起動したままにしておきます。アプレットの名称にはとくに意味とか必然性はありません。たまたま、そういう名前で書いたのでそうなってるだけです。

AppleScript名:RemoteAgent
– Created 2017-10-18 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OSAKit”
use framework “AppKit”
–http://piyocast.com/as/archives/4906

on run
  
end run

on testMe(aParam)
  return aParam
end testMe

on getVers()
  set vers to (do shell script “defaults read /System/Library/CoreServices/SystemVersion ProductUserVisibleVersion”)
  
set build to (do shell script “defaults read /System/Library/CoreServices/SystemVersion ProductBuildVersion”)
  
return {vers, build}
end getVers

on execASstring(aString)
  
  
set aRect to current application’s NSMakeRect(0, 0, 500, 200)
  
  
–Make AppleScript Controller & Script Editor View
  
set osaCon to current application’s OSAScriptController’s alloc()’s init()
  
set osaView to current application’s OSAScriptView’s alloc()’s initWithFrame:aRect
  
  
–Make Result View
  
set resView to current application’s NSTextView’s alloc()’s initWithFrame:aRect
  
resView’s setRichText:true
  
resView’s useAllLigatures:true
  
  
–Connect OSAScriptController to Editor View & Result View
  
osaCon’s setScriptView:osaView
  
osaCon’s setResultView:resView
  
  
–Set AppleScript Source to Editor View & Execute it
  
set aSource to current application’s NSString’s stringWithString:aString
  
osaView’s setString:aSource
  
osaCon’s runScript:(missing value)
  
  
–Get AppleScript’s Result as string
  
set aRes to resView’s |string|() as string
  
  
return aRes
end execASstring

–指定AppleScriptファイルのソースコードを取得する(実行専用Scriptからは取得できない)
– Original Created 2014-02-23 Shane Stanley
on getASsourceFor(anAlias as {alias, string})
  set anHFSpath to anAlias as string
  
set aURL to current application’s |NSURL|’s fileURLWithPath:(POSIX path of anHFSpath)
  
set theScript to current application’s OSAScript’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)
  
return theScript’s source() as text
end getASsourceFor

★Click Here to Open This Script 

macOS 10.12側

macOS 10.12側で呼び出し用のScriptを書いてScript Menuに登録しておきます。Script中のUser名とパスワードはmacOS 10.13側のものを書いておきます。ここではmacOS 10.13側のIPアドレスを直接記述していますが「MBP11.local」のようなBonjour名称でももちろんOKです。

ここにユーザー名とパスワードを書かないと毎回ダイアログが出てユーザー名、パスワード、キーチェーンに保存するかなど聞かれますが、結局保存されなくて毎回聞かれるので、直接コード中に書いておくか、別途キーチェーンに保存して実行時に読み出してもいいでしょう。

AppleScript名:macOS 10.13でリモート実行
– Created 2017-10-18 by Takaaki Naganoya
– 2017 Piyomaru Software
–http://piyocast.com/as/archives/4906
tell application “Script Editor”
  tell front document
    set aSource to contents
  end tell
end tell

tell application “RemoteAgent” of machine “eppc://user:password@192.168.0.7″
  set {vRes, bRes} to getVers()
  
set aRes to execASString(aSource)
end tell

set vText to “macOS “ & vRes & ” (Build:” & bRes & “) Result:”
display dialog vText default answer aRes

★Click Here to Open This Script 

macos10126_1.png

こんなAppleScriptをScript Editor上でオープンした状態で(複数Window表示時には最前面であること)、Scriptを実行。

macos10126_2.png

LANごしにリモートAppleEventを実行し、macOS 10.13上のアプレットで指定のAppleScriptを動的にコンパイルして実行。結果をmacOS 10.12のマシン側に返してきます。

macos10126_3.png

こんな感じで動作確認を行なっています。ただリモート実行するだけなら、もうちょっとシンプルに書けたような気もしますが、Cocoa系の機能を使ってリモートScript実行を行なってみたときの部品をそのまま流用しています。

LAN経由、とくにWiFi経由でのリモートAppleEventsは通信にコストがかかる(時間がかかる)ため、パラメータだけ与えてまとめて結果をもらうようにするべきです。VPN経由で遠隔地のMacの操作を行うような場合にも同様です。

2017/06/04 指定スクリプト書類の記述OSA言語を取得する

指定スクリプト書類の記述OSA(Open Scripting Architecture)言語の情報を取得するAppleScriptです。

指定のスクリプト書類がどのOSA言語で記述されているかについては、Script Editorでオープンして書類のプロパティを取得するのが手っ取り早い方法ですが、

AppleScript名:Script Editorでスクリプト書類をオープンして記述OSA言語名称を取得
set anAlias to choose file of type {“com.apple.applescript.script”, “com.apple.applescript.script-bundle”}
tell application “Script Editor”
  set aDoc to open anAlias
  
tell aDoc
    set aProp to properties
    
set aLang to name of language of aProp
  end tell
end tell

★Click Here to Open This Script 

これだと、スクリプト書類内で呼び出しているアプリケーションが自動的に起動されます。

スクリプト書類を大量に処理するような場合、アプリケーションが自動起動されたくないような用途もあります。そのために、Cocoaの機能(OSAKit)を呼び出して、スクリプト書類から直接情報を取得してみました。

これだと、InDesignのコントロールを行なっているスクリプトから情報を取得しても、InDesignが起動されることはありません。

AppleScript名:指定スクリプト書類の記述OSA言語を取得する
– Created 2017-06-04 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OSAKit”
–http://piyocast.com/as/archives/4674

set anAlias to choose file of type {“com.apple.applescript.script”, “com.apple.applescript.script-bundle”}

set aURL to current application’s |NSURL|’s fileURLWithPath:(POSIX path of anAlias)
set theScript to current application’s OSAScript’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)

set scriptName to theScript’s |language|()’s |name|() as string
set scriptDesc to theScript’s |language|()’s info() as string
set scriptVer to theScript’s |language|()’s |version|() as string

return {osaName:scriptName, osaDesc:scriptDesc, osaVer:scriptVer}
–>  {osaName:”AppleScript”, osaDesc:”AppleScript.”, osaVer:”2.5″}
–>  {osaName:”JavaScript”, osaDesc:”JavaScript”, osaVer:”1.1″}

★Click Here to Open This Script 

2017/06/03 指定フォルダ中のPure ASのファイルを別フォルダに移動

指定フォルダ中のPure AppleScriptのファイルを別フォルダに移動するAppleScriptです。

最近は(処理速度が速いことや並列実行させやすいことから)なるべくCocoaの機能を呼び出すASOC(AppleScriptObjC)の部品を使うようにしているので、Pure AppleScript(Cocoaの機能を使わないもの)のファイルを整理して別フォルダに移動させておくためのScriptを書いてみました。

任意のAppleScript書類からソースを取得して、ソース中にuse framework “Foundation”の宣言文が入っていないかどうかを確認しています。入っていればASOC、入っていなければPure ASと判定。実行専用のScriptからはソースコードは取得できないので無視していますし、実行形式のアプレットについては最初の段階で対象外にしています。

AppleScript名:指定フォルダ中のPure ASのファイルを別フォルダに移動
– Created 2017-06-03 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OSAKit”
–http://piyocast.com/as/archives/4673

set tFol to choose folder with prompt “処理対象フォルダを選択”
set sFol to choose folder with prompt “Pure AppleScriptの移動先フォルダを選択”

tell application “Finder”
  tell folder (tFol)
    set sList to (every file whose name ends with “.scpt” or name ends with “.scptd”) as alias list
  end tell
end tell

repeat with i in sList
  set sRes to detectScriptIsPureASorASOC(i) of me
  
if sRes = false then
    tell application “Finder”
      move i to sFol
    end tell
  end if
end repeat

–指定AppleScriptファイルがPure ASかASOCかを判定して返す
on detectScriptIsPureASorASOC(aFile)
  set sText to getASsourceFor(aFile) of me
  
if sText = “” or sText = missing value then return missing value
  
if sText contains “use framework \”Foundation\”" then
    return true –ASOC (AppleScript with Cocoa Framework)
  else
    return false –Pure AppleScript
  end if
end detectScriptIsPureASorASOC

–指定AppleScriptファイルのソースコードを取得する(実行専用Scriptからは取得できない)
on getASsourceFor(anAlias as {alias, string})
  set anHFSpath to anAlias as string
  
set aURL to current application’s |NSURL|’s fileURLWithPath:(POSIX path of anHFSpath)
  
set theScript to current application’s OSAScript’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)
  
return theScript’s source() as text
end getASsourceFor

★Click Here to Open This Script 

2016/01/07 OSAScriptViewでAppleScriptをソース取得&コンパイルして書式付きでPDF出力

Cocoaの機能を用いて、指定のAppleScriptのソースを取得して、再度OSAScriptView上でコンパイル(構文確認)を行い、構文色分けを反映させたスタイルつきのPDFとして出力するAppleScriptです。

わかりにくいですが、AppleScriptの書類をPDF出力するAppleScriptです(正確に書けば書くほどわからなくなるのはなぜだろう)。デスクトップフォルダ上に元Scriptのファイル名でPDF出力します。

script1.png
▲出力対象のAppleScript書類

scriptpdf.png
▲上記書類をPDF出力したもの

PDF出力部分は、指定URLの内容を1枚モノのPDFに書き出すAppleScriptを書いた際に利用した記述そのままです。ページネーションは一切していないため、こういう用途ではページネーション指定をしてPDF出力したほうがよいかもしれません。

AppleScriptのパスだけ与えれば、あとはGUIアプリの機能は利用していないため、大量データの並列処理に適した構造になっています。

「なんでこんなもの作ったの?」と聞かれましたが、結局「これじゃない何か」を作ろうとして、その途中経過ができたものなので、本Scriptは本当に作りたいものの副産物です。

AppleScript名:OSAScriptViewでAppleScriptをソース取得&コンパイルして書式付きでPDF出力
– Created 2016-01-07 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OSAKit”
use framework “AppKit”
use framework “Quartz”

set targX to 1024 –PDF Width
set targY to 2048 –PDF Height

–Select & Read AppleScript Source (Only Editable AppleScripts are available)
set aScriptAlias to (choose file with prompt “Choose AppleScript to convert to PDF” of type {“com.apple.applescript.script-bundle”, “com.apple.applescript.script”})

set srcStr to getASsourceFor(aScriptAlias) of me
if srcStr = missing value or srcStr = “” then
  –Error
  
display dialog “Error in reading script source….” buttons {“OK”} default button 1 with icon 1
  
return
end if

–Making PDF Out Path from source script file name
set outName to getFileNameFromAlias(aScriptAlias) of me
set outFol to POSIX path of (path to desktop)
set outPath to outFol & outName
set pathString to current application’s NSString’s stringWithString:outPath
set newPath to pathString’s stringByDeletingPathExtension()
set pdfOutPath to newPath’s stringByAppendingPathExtension:“pdf”

–Compile AppleScript
set osaCon to current application’s OSAScriptController’s alloc()’s init()
set osaView to current application’s OSAScriptView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, targX, targY))
osaCon’s setScriptView:osaView
osaView’s setString:srcStr
osaCon’s compileScript:(missing value) –Compile(構文確認)

–Make Print into PDF
set aPrintInfo to current application’s NSPrintInfo’s sharedPrintInfo()
set newPrintOp to current application’s NSPrintOperation’s PDFOperationWithView:(osaView) insideRect:(current application’s NSMakeRect(0, 0, targX, targY)) toPath:pdfOutPath printInfo:aPrintInfo

set runPrint to newPrintOp’s runOperation()
return (runPrint as boolean)

–指定AppleScriptファイルのソースコードを取得する(実行専用Scriptからは取得できない)
– Original Created 2014-02-23 Shane Stanley
on getASsourceFor(anAlias as {alias, string})
  set anHFSpath to anAlias as string
  
set aURL to current application’s |NSURL|’s fileURLWithPath:(POSIX path of anHFSpath)
  
set theScript to current application’s OSAScript’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)
  
return theScript’s source() as text
end getASsourceFor

–指定のAliasからファイル名を取得する
on getFileNameFromAlias(anAlias)
  set aPath to POSIX path of anAlias
  
set pathString to current application’s NSString’s stringWithString:aPath
  
set newPath to pathString’s lastPathComponent()
  
return newPath as string
end getFileNameFromAlias

★Click Here to Open This Script 

2014/12/16 指定AppleScriptをしらべたり実行したりする

Cocoaの機能を用いて、AppleScript(の書類やテキスト)を実行したり調べたりするAppleScriptです。

日本語として間違った文に見えますが、正しい内容です。

(1)TEST1:ASOCのプログラムをテキストで組み立てて実行
普通のAppleScriptを実行できることは容易に想像できるのですが、OS X 10.10から利用可能になったを機能を使いまくったScriptを渡して実行できるか試してみました。海外でもサンプルコードをチラホラ見かけるのですが、お行儀のよい最低限の内容だったりしていただけません(限界まで切り込んでない感が、、、)。

問題なく実行できるものの、display dialogを実行させたら無視されたりと、制約はあるようです(コマンドラインからosascriptコマンドで実行しているかのよーだ)。choose fileは無視されません。

(2)TEST2:指定ASがコンパイルずみかどうか調べる
コンパイル(中間言語翻訳)ずみかどうかを調べます。

(3)TEST3:指定ASのソースを取得
指定のAppleScriptのソースコードを取得します。実行専用で保存されている場合には取得できません。

AppleScript名:指定AppleScriptの各種属性を取得
– Created 2014-12-16 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”
use framework “OSAKit”

–TEST1: ASOCのプログラムをテキストで組み立てて実行
set asText to
use AppleScript version \”2.4\”
use framework \”Foundation\”
use framework \”ASObjCExtras\”
use framework \”QuartzCore\”
use scripting additions

property PDFDocument : class \”PDFDocument\”

set aHFSPath to (choose file of type {\”com.adobe.pdf\”} with prompt \”ページ数をかぞえるPDFを指定してください\”) as string
set aURL to (current application’s SMSFord’s URLFrom:aHFSPath)

set aPDFdoc to PDFDocument’s alloc()’s initWithURL:aURL
set aRes to aPDFdoc’s pageCount()
say (aRes as string)


set aRes to compileAndExecuteASstring(asText)

–TEST2: 指定AppleScriptがコンパイルずみ(中間コードへの翻訳の意)かどうかをしらべる
set a to (choose file of type {“com.apple.applescript.script”})
set asRes to chkAScompiled(a)
–> true or false

–TEST3: 指定AppleScriptのソースを取得
set asSource to getASsourceFor(a)
–> AppleScriptのソースがテキストで返る

–指定のAppleScriptファイルがコンパイル(構文確認+中間言語化)ずみかどうかを取得する
on chkAScompiled(anAlias as {alias, string})
  set anHFSpath to anAlias as string
  
set aURL to (current application’s SMSFord’s URLFrom:anHFSpath)
  
set asO to current application’s OSAScript’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)
  
try
    set compF to asO’s isCompiled() as boolean
  on error
    return false
  end try
  
  
return compF
end chkAScompiled

–指定AppleScriptファイルのソースコードを取得する(実行専用Scriptからは取得できない)
– Original Created 2014-02-23 Shane Stanley
on getASsourceFor(anAlias as {alias, string})
  set anHFSpath to anAlias as string
  
set aURL to current application’s SMSFord’s URLFrom:anHFSpath
  
set theScript to current application’s OSAScript’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value)
  
return theScript’s source() as text
end getASsourceFor

–与えられた文字列をAppleScriptとして評価してエラーになるかどうかを返す(falseでエラー)
on compileASstring(asSourceStr as string)
  set aNSString to current application’s NSString’s stringWithString:asSourceStr
  
set asObj to current application’s OSAScript’s alloc()’s initWithSource:aNSString
  
set asRes to asObj’s compileAndReturnError:(missing value)
  
return asRes as boolean
end compileASstring

–与えられた文字列をAppleScriptとして評価して正しければ実行
on compileAndExecuteASstring(asSourceStr as string)
  set aNSString to current application’s NSString’s stringWithString:asSourceStr
  
set asObj to current application’s OSAScript’s alloc()’s initWithSource:aNSString
  
set asRes to asObj’s compileAndReturnError:(missing value)
  
if asRes = false then return false –エラーの場合falseを返す
  
  
set aErrorRec to current application’s NSMutableDictionary
  
asObj’s executeAndReturnError:aErrorRec
  
return aErrorRec’s ASify() as record –Resultだけちょっといただけない
end compileAndExecuteASstring

★Click Here to Open This Script