0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Windows で python から ShellExecute を利用する

Posted at

意外にはまってしまったのでメモしておきます。

背景

Windows において、python を1つ上げたら芋ずる式に他のプロセスを上げていきたい。
起動数は固定なので、shell32.dll の ShellExecute を使うことを考えた。
しかし python からこの DLL を利用するにはいくつか tips があるようだ。

問題のあるプログラム

最初は単純に ShellExecute を呼び出せばよいと思い、以下のようなプログラムを書いていました。

from ctypes import windll
shellexecute = windll.shell32.ShellExecuteA
err = shellexecute(None, "open", "./test.exe", None, None, 1)
print(err)

しかし結果は 31 エラーで撃沈。仕方がないので python の ctypes の項を読むと、ASCII 文字列は c_char_p で変換して渡す必要がありそう。さっそく実行。

from ctypes import windll, c_char_p
shellexecute = windll.shell32.ShellExecuteA
err = shellexecute(None, c_char_p(b"open"), c_char_p(b"./test.exe"), None, None, 1)
print(err)

が、これも 31 エラーで弾かれる。

もしかして、区切り記号?

途方に暮れていると、Windows ではフォルダの区切り記号が \ であることに気づいた。やってみよう!

from ctypes import windll, c_char_p
shellexecute = windll.shell32.ShellExecuteA
err = shellexecute(None, c_char_p(b"open"), c_char_p(b".\\test.exe"), None, None, 1)
print(err)

今度はうまく動きました。ShellExecuteW を使いたい場合は、

from ctypes import windll, c_wchar_p
shellexecute = windll.shell32.ShellExecuteW
err = shellexecute(None, c_wchar_p("open"), c_wchar_p(".\\test.exe"), None, None, 1)
print(err)

とすれば OK。

DLL 化して呼び出しを簡略化

でも一々 c_wchar_p を指定するのは面倒なので、DLL に組み込んでしまった。

mycommon.cc
#include <windows.h>
extern "C" __declspec(dllexport) int launch(LPCWSTR file, int mode) {
   HINSTANCE hInst = ShellExecuteW(NULL, L"open", file, NULL, NULL, mode);
   return GetLastError();
}

mycommon.cc をコンパイルし、mycommon.dll を作成すると、

from ctypes import cdll

launch = cdll["./mycommon"].launch
err = launch(".\\test.exe", 1)

という形で呼び出すことができた。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?