ここ最近のブログ記事をご覧いただくと分かる通り、Power Automate、特にUIフローにハマっております。
下記記事で書いたように、多々引っ掛かる罠的なポイントがあるものの、2019年12月時点ではまだプレビュー段階であり、今後の発展性を考えると罠はさほど気になりません。
それよりも、OneDriveやSharePoint、Power Appsといったクラウドサービスから、ローカルのアプリケーションを操作できるメリットの方が私には面白く感じられます。
今回は、UIフローで実行ファイルのパスを指定してローカルのアプリケーションを起動し、そのアプリケーションを操作するために試行錯誤した結果をまとめてみたいと思います。
なぜ実行ファイルのパスを指定するのか?
まずは「なぜ操作対象となるアプリケーションの実行ファイルのパスを指定するのか?」ですが、現時点では、UIフローはすでに起動済みのアプリケーションの操作を記録すること(レコーダーによるアプリの記録)しかできません。
UIを持ったアプリケーションであればそれで問題ないのですが、UIを持たないバックグラウンドで動くアプリケーションの場合は、レコーダーで操作を記録できず、フローの中に組み込むことができません。
仕様上そういった使い方は想定されていない、と言われればそれまでですが、実行ファイルのパスを指定して起動することができれば、アプリケーションのパスを入力値として用意して、並列分岐によって処理対象のアプリケーションを切り替えたり、任意のスクリプトを自由に走らせたりすることができ、自動操作できる幅が広がるはずです。
そういったわけで、私はUIフローから任意のアプリケーションやスクリプトを実行する方法を模索することにしました。
すでにコネクタがある場合はそちらを使う
その前に、根本的な話になりますが、Power Automateには多数のコネクタが用意されています。
目的の処理がすでにコネクタとして用意されている場合は、無理にUIフローを使う必要は無いでしょう。
例えば、“任意のタイミングでDropboxにあるファイルをGoogle Driveにアップする”、といった操作を行う場合、UIフローでローカルのブラウザーを操作してファイルをアップロードして・・・といったことも出来なくはないかもしれませんが、非効率です。
Google Driveであればすでにコネクタが用意されているので、そちらを使った方が手っ取り早く確実に処理できます。
あるいは、APIが公開されているのであれば、カスタムコネクタを使った方が良いかもしれません。
どちらにせよ、第一の選択肢としてUIフローを挙げる必要はありません。
コネクタもAPIも無い、レガシーなローカルアプリケーションの操作を行いたい、そういった場合にUIフローを活用するわけです。
コマンドプロンプトの操作を試す
本題に戻りましょう。
UIフローからパスを指定して任意のアプリケーションを実行する方法ですが、まず私はコマンドプロンプトの操作を試してみました。
結果は、下記エラーが発生してアプリケーションの起動すらできませんでした。
ActionFailed. アクションが失敗しました。依存アクションが成功しませんでした。
原因は記録されたアプリケーションのパスで、下図の通り conhost.exe が記録されています。
これを cmd.exe のパスに書き換えて実行したところ、
起動には成功しましたが、その後のアクションは実行できませんでした。
32ビット版、64ビット版、どちらのコマンドプロンプトでも結果は同じです。
入力値からのパス指定ではなく、キーボードからの入力も試してみましたが、こちらも上手くいきません。
PowerShellの操作を試す
コマンドプロンプトがダメなら次はコレ、ということでPowerShellを試してみましたが、こちらもコマンドプロンプトと同様に失敗です。
「ファイル名を指定して実行」ダイアログの操作を試す
次は「ファイル名を指定して実行」ダイアログの操作を試してみました。
「サポートされていないアプリケーションの種類」にある通り、UIフローではWindowsでの対話に対応していませんが、下記コマンドのようにrundll32経由で直接呼び出すダイアログではいけるかもしれないと思ったからです。
rundll32.exe shell32.dll,#61
結果は、下図の通り失敗に終わりました。
アプリケーションのパスとして、 rundll32.exe に引数が渡せず、ダイアログの呼び出しに失敗しているようです。
(引数ごとコマンド指定しても、指定されたファイルが見つからないエラーが発生します。)
スクリプト経由でアプリケーションを実行する
こうなってくると半ば意地です。
下記のようなスクリプト経由でアプリケーションを呼び出してみます。
'*********************************** ' 任意のコマンドを実行するVBScript ' @kinuasa '*********************************** Option Explicit Dim ret ret = InputBox("実行するコマンドのパスを入力してください。", "Enter a command path") If IsEmpty(ret) = True Then WScript.Quit If Len(Trim(ret)) < 1 Then WScript.Quit On Error Resume Next With CreateObject("Scripting.FileSystemObject") Select Case LCase(.GetExtensionName(ret)) Case "vbs" CreateObject("WScript.Shell").Run """" & ret & """", 1, False Case Else With CreateObject("WbemScripting.SWbemLocator").ConnectServer.Get("Win32_Process") .Create ret, Null, Null, Null End With End Select End With On Error GoTo 0
上記はインプットボックスに入力されたコマンドを実行する簡単なスクリプトですが、このスクリプトの操作を記録・テストしてみると、下図の通り「Windows Script Host の設定」画面が表示されました。
それはそうです。
アプリケーションのパスとして「WScript.exe」が記録されているのですから。
そこで、直接スクリプトファイルのパスを指定すると、
今度は上手くいきました。
意図した通り、入力値で実行するコマンドを指定でき、当初の目的達成です。
上記の処理内容は下図の通りです。
おわりに
色々試してきましたが、
“VBScript経由で任意のアプリケーションやコマンドを実行するハック”
一手間掛かりますが、これが一番安定して処理できる方法でした。
(今後のPower Automateのアップデート次第では、このような手間は不要になるかもしれません。)
これで、ローカルのアプリケーション実行し放題、コマンド叩き放題!
メール一本で端末をロックしたり、Power Appsのボタンからバッチやスクリプトを走らせたり、もう色々やりたい放題できるはず。
UIフローに夢中な皆さん、是非一度お試しください。
この記事へのコメントはありません。