標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

ShellExecute でネットワーク上の実行ファイルを呼び出そうとするとエラーになる

結論から言うと

The operation was canceled by the user

というエラーが発生する時は、ネットワークドライブとか、シンボリックリンクなどを経由せず、確実なUNCパスを使えという話です。

自分は VM 内の Windows の中で開発をよくするのですが、ツール類をいちいち VM にコピーするのが面倒なので、ネットワークドライブにパスを通して使っています。 が、一部のプログラムの起動が失敗します。条件を確認すると次のような場合のようです。

  • nyagos上のみ。CMD.EXE ではエラーにならない
  • GUI のプログラムである
  • ローカルディスクの実行ファイルではエラーにならない

nyagos では、GUI プログラムを起動する時は ShellExcute API を使います。試しに Lua の os.execute 関数を使って、CreateProcess API 経由で GUI プログラムを起動させようとすると、こちらは問題ありません。ShellExecute は Windowsエクスプローラーからクリックのと同じ起動方法なので、おそらくこれはセキュリティー的な制約なのでしょう。

これの回避方法が長い間分からなかったのですが、昨日、ようやくわかりました。その実行ファイルの真のフルパス(UNCパス)であれば、エラーが発生しないようです。

Go言語で真のフルパスを得るのは簡単で、"path/filepath".EvalSymlinks 関数を呼べば Ok です。

ということで、2年越しの issue をクローズできたのでした。めでたし、めでたし