Pythonツール配布の手段として、WinPythonの実行環境に向けて一時的にpathを通すbatファイルが便利だった

# 前提
- Python言語で書いたソースコードファイルをpyファイルということにします。
- 主にpyファイルで作成したプログラムをPythonツールということにします。
- WinPythonはOSがWindowsであることを前提としたPython実行環境となります。

# 要点
:::note info
- Pythonツールを実行するにはPythonの実行環境が必要
- Pythonの実行環境を用意する手段として、Pythonをインストールするのが常套
- 配布先のPCにはPythonがインストールされていないこともあるため、インストール無しで実行できる手段が欲しい時がある
- Pythonツールからexeファイルを生成してPythonをインストールしないで実行できるようにする手段もあるが、実際にやってみると大変
- WinPythonというPythonの実行環境を1つにまとめたフォルダが配布されている
- WinPythonとPythonツールを配布し、配布先でWinPythonの実行環境に向けて一時的にpathを通すbatファイルを作ればPythonツールを簡単に実行できるのでおすすめ(配布手順案は[こちら](#winpythonとbatファイルを使用したpythonツールを配布する))
:::

# はじめに
### Pythonツールを配布するには
Pythonツールを実行するためには、Pythonの実行環境が必要になります。
このPythonの実行環境を用意するには、Pythonをインストールするのが常套手段です。
しかし、PythonをインストールしていないPCにPythonツールを配布して使用してもらいたいこともあるのではないでしょうか。
その手段としてよく取られるのが、exeファイルを生成(exe化)して実行できるようにすることだと思います。

### exe化は大変
ただ、このexe化をやってみて分かったのですが、難しいし大変です。
- exe化のためにどのモジュールを使用すればいいか決める必要がある。
- exe化のコマンドを実行してからexe化できるまで時間がかかる。
- exe化中にエラーが発生することもあり、その時は調査が必要
- exe化ができたとしてもexeファイルを実行するとexe化前では発生しなかったエラーが発生することもあり、その時も調査が必要
- これら全てをクリアしたとしても、ネット経由で他のPCに配布しようとすると、セキュリティソフトがexeファイルを脅威と判定し、実行できなかったり削除されたりする。

と、難しい・大変な点を挙げだしたらキリがありません。
実際、私はPythonツールをexe化して他のPCに配布しようとしたときがあったのですが、断念してしまいました。

### そこで、WinPython
Pythonをインストールしてもらうことなく、exe化もせずにPythonツールを配布・実行することができないか？
調べた結果、いきついたのがWinPythonと呼ばれるものでした。
次から以下の順に沿って「WinPythonについて」と「WinPythonとbatファイルを使ったPythonツールの配布手段について」を紹介していきます。
- [今回の記事のゴール](#今回の記事のゴール)
- [WinPythonとは何か](#winpythonとは何か)
- [WinPythonのダウンロード](#winpythonのダウンロード)
- [WinPythonを使用してみる](#winpythonを使用してみる)
- [WinPythonについての考察](#winpythonについての考察)
- [WinPythonとbatファイルを使用したPythonツールを配布する](#winpythonとbatファイルを使用したpythonツールを配布する)

# 今回の記事のゴール
WinPythonとPythonツールを配布し、事前準備をしてもらうことでツールを簡単に実行できる状況を作り出すことを目指します。
ここでいう簡単とは、特定のファイルをエクスプローラー上でダブルクリックするだけなど、exe化したときとあまり変わらない操作感で実行できる状態であることを指します。

# WinPythonとは何か
語弊があるかもしれませんが、WinPythonとは、Pythonが実行できる環境を1つにまとめたフォルダだと思っていただければいいかと思います。
これが自己解凍形式で圧縮されているものが公開されており、ネットを通してダウンロードができるようになっています。

Winpythonへのリンク

https://winpython.github.io/

このWinPythonのすごいところは、Pythonがインストールされている状態を擬似的に作り出せるということだと思ってます。PythonをインストールしていないPC環境であったとしてもこのWinPythonを渡してしまえばPythonが実行できる状況を作り出せるのです！

WinPythonとは何か軽い説明を終えたところで、WinPythonを使用するため実際にダウンロードしてみます。

# WinPythonのダウンロード
ダウンロードするには最初に下記のリンクへアクセスします。

https://sourceforge.net/projects/winpython/files/

![sourceforge.net_projects_winpython_files_ (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/0639475e-7e5e-dd9b-d791-f4d7ba0e3742.png)

まずWinPythonのバージョンがいくつかあるのでどのバージョンをダウンロードしたいかを決めてクリックします。どのバージョンが良いかはその時々によると思いますが、分からなければDownloads/Weekを参考にしながら人気そうなものを選べば良いのではないかと思います。

今回、私は3.10.9.0にしました。

バージョンをクリックしたら更にいくつか種類があるのでどれをダウンロードするか決めます。
![sourceforge.net_projects_winpython_files_WinPython_3.10_3.10.9.0_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/4b776ab1-cbd3-c8d4-04fd-67b5e943fd55.png)

この種類についてですが、それぞれ下記のイメージで問題ないでしょう。

|種類|説明|
|--|--|
|betas|試用版のため特に理由がなければ選ばないほうが無難|
|Winpython64-[バージョン].exe(以下 フル版)|Pythonを実行する環境をたくさん揃えたフルバージョン|
|Winpython32-[バージョン]dot.exe|Pythonを実行する最低限の環境を揃えたバージョン(32bitPC用)|
|Winpython64-[バージョン]dot.exe(以下 dot版)|Pythonを実行する最低限の環境を揃えたバージョン|

今回の記事においては、dot版で事足りると判断したため、dot版をダウンロードすることにしました。
ダウンロードするものを決めてクリックしたら画面が遷移し、しばらくすると自動でダウンロードが始まります。後は下2枚のようにダウンロード完了まで待てばOKです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/f13a2c14-d55e-507e-9fa7-2961f4cd5b3e.png">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/d406b777-81da-40d1-b417-b1cabe86d0ff.png">


次はWinPythonを使用してみます。

# WinPythonを使用してみる
では、ダウンロードしたファイルを実行することでWinPythonを解凍します。
場合によってはWindowsのSmartScreenによって以下のような画面が表示されることがあります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/f5e083a8-60a9-4ee4-7404-fc1ef080daba.png" width=50%>
[GitHub](https://github.com/winpython)に公開もされているものなので問題はないと個人的には思っているのと、実行しないと進まないので今回は実行することにします。「詳細情報」をクリック後、「実行」をクリックします。

以下のような画面が表示されたら解凍先のフォルダを決めて「Extract」で解凍。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/32b5f748-3185-12b9-528e-b31b4d555c11.png)

WPy(バージョン)という名前のフォルダが解凍されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/b2c02321-20a9-792a-dba6-8f110894a34b.png" width=50%>

この記事ではこのフォルダのことをWinPython本体フォルダと呼ぶことにします。
このWinPython本体フォルダの中にあるいくつかのソフトがPyhonを実行できるコンソールになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/cf980a30-fa7c-e298-f8f4-43375ac0fab3.png)

例えば、「WinPython Command Prompt.exe」を実行すると以下のようにPythonが実行できるコマンドプロンプトが起動されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/b200620f-abc5-6f9e-8762-2b7cb70967a6.png)

試しに「hello world」とだけ出力する以下のpyファイルを作成して、コマンドプロンプトから呼び出してみましょう。

```helloworld.py
print("hello world")
```

コマンドプロンプトに作成したpyファイルのフルパスを入れて実行すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/6ff7f0bc-511e-95ff-71b3-0bfa35da422b.png)

「hello world」と表示されました！

またpipも使用することができるので必要なモジュールも揃えられます。
このようにWinPython本体フォルダのソフトから実行したコンソールだとPythonがインストールされているかのように扱うことができるのです。

なお、dot版は全てのソフトが実行できないのと、私自身も全て把握しきれていないので、他のソフトの実行については割愛させていただきます。

# WinPythonについての考察
WinPythonをダウンロードしてから、pyファイルを呼び出すことができました。ここで、WinPythonにはPythonが実行できる環境が整っていることに改めて注目します。この実行環境に向けてpathを一時的に通すことができればPythonをインストールしなくてもPythonツールを実行することができそうな気がします。
試しに「WinPython Command Prompt.exe」で起動したプロンプトからpathを確認するとWinPython本体フォルダの実行環境に向けてpathが通っていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/273dc296-a015-6667-d3f8-6a0262a2799a.png)
そこで実際にWinPythonの実行環境に向けて一時的にpathを通したらPythonを実行できるか確かめてみます。
通常のコマンドプロンプトを起動し、WinPython本体フォルダに移動してから以下のコマンドを入力して実行環境に向けてpathを一時的に通します。
```
set envdir=%CD%\python-3.10.9.amd64
set PATH=%envdir%\Lib\site-packages\PyQt5;%envdir%\Lib\site-packages\PySide2;%envdir%\;%envdir%\DLLs;%envdir%\Scripts;%envdir%\..\t;%envdir%\..\t\Julia\bin;%envdir%\..\n;%PATH%
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/2feadde6-7bbb-28cb-ea48-bdbdaa1f5e6b.png)
そしてpyファイルを呼び出すようにPythonを実行すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/4e0373d6-8592-a609-3e4c-afe105390f32.png)
無事に実行できました！
ここまでくれば、pathを通すこととPythonツールの実行を一連のbatファイルにすることができますね。

batファイルを作ることができれば実行したいPythonツールをダブルクリックで実行することができるので、exe化のときとほぼ変わらずにPythonツールを使用することができそうです！

# WinPythonとbatファイルを使用したPythonツールを配布する
では今までの内容を基に、WinPythonとbatファイルを使用したPythonツールを配布する具体案を出します。
以下の手順でWinPythonとbatファイルを使用したPythonツールを配布します。

:::note info
1. 配布するフォルダを作成
       ※フォルダ名は任意の名前でよい
1. 配布するフォルダに以下のファイルを入れる
    - WinPython本体フォルダ
    - ツールとして用いたいpyファイル
1. 配布するフォルダをzipなどに圧縮して他のPCへ配布
1. 配布先のPCで配布されたフォルダを展開
1. 事前準備として配布されたフォルダに以下の内容を記述したbatファイルを追加で作成する
    - WinPython本体フォルダの実行環境に向けて一時的にpathを通す
    - Pythonを実行してpyファイルを呼び出す
    ※batファイル名は任意の名前でよい
    <details><summary>batファイルの例(折りたたんでます)</summary>

    ```.bat
    @echo off
    rem WinPythonの実行環境が含まれたフォルダを指定。WinPythonのバージョンによってフォルダ名は適宜変更してください。
    set envdir=%~dp0\WPy(バージョンによって異なる)\python-(バージョンによって異なる)
    set _path=%PATH%
    pushd %~dp0
    set PATH=%envdir%\Lib\site-packages\PyQt5;%envdir%\Lib\site-packages\PySide2;%envdir%\;%envdir%\DLLs;%envdir%\Scripts;%envdir%\..\t;%envdir%\..\t\Julia\bin;%envdir%\..\n;%PATH%
    rem 呼び出すpyファイルを指定してください。
    python (pyファイル名.py)
    popd
    set PATH=%_path%
    pause
    ```
    </details>
1. 以降、ツールを使用するときはbatファイルをダブルクリックなどで実行してもらう。
:::

<details><summary>手順の参考例(折りたたんでます)</summary>

「helloworld.py」をPythonツールとして配布したい想定で、手順を追ったものです。
(WinPythonのバージョン:3.10.9)
### 1.配布するフォルダを作成
ツールをまとめるフォルダを作成します。今回はフォルダ名を「PythonTool」としています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/90396cb9-1778-fd23-6012-e72a76ef57c0.png)

### 2.配布するフォルダにファイルを入れる
以下のファイルを入れます
- WinPython本体フォルダ
- ツールとして用いたいpyファイル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/d54fa90e-a1bb-4483-98fc-eda66b3542fd.png)

### 3.配布するフォルダをzipなどに圧縮して他のPCへ配布
配布するフォルダを必要に応じて圧縮します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/9e188d60-9c9e-7a6d-0e98-d75a1bdf6f99.png)
その後、フォルダを配布します。

### 4.配布先のPCで配布されたフォルダを展開
配布先のPCでフォルダを展開します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/a254b6da-f608-b35c-6829-38d75f5ccbca.png)

### 5.事前準備としてツールを配布されたフォルダに以下の内容を記述したbatファイルを追加で作成する
配布されたフォルダの中に以下の内容のbatファイルを新規で作成します。batファイル名は任意です。今回は「main.bat」としています。

```main.bat
@echo off
rem WinPythonの実行環境が含まれたフォルダを指定。WinPythonのバージョンによってフォルダ名は適宜変更してください。
set envdir=%~dp0\WPy64-31090\python-3.10.9.amd64
set _path=%PATH%
pushd %~dp0
set PATH=%envdir%\Lib\site-packages\PyQt5;%envdir%\Lib\site-packages\PySide2;%envdir%\;%envdir%\DLLs;%envdir%\Scripts;%envdir%\..\t;%envdir%\..\t\Julia\bin;%envdir%\..\n;%PATH%
rem 呼び出すpyファイルを指定してください。
python helloworld.py
popd
set PATH=%_path%
pause
```

バッチファイルの作り方は以下のサイトが参考になります。

https://nw-engineer.work/batfile/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/67d5f383-555f-58d0-a5b8-e6a46fe5e820.png)

### 6.以降、ツールを使用するときはbatファイルをダブルクリックなどで実行してもらう。
以降はbatファイルをダブルクリックするだけでツールが実行できます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/49f82f8e-add0-2b30-c5f8-4bf8afb8b4dc.png)

これで全ての手順が完了です。</details>


### 解説
Winpythonの本体フォルダとツールを配布し、Winpythonの環境にpathを通したbatファイルを作ってもらいます。こうすることで1つのフォルダを渡すだけで配布が完了しますし、以降はbatファイルをダブルクリックするだけでPythonツールを実行できるようになります。さらにモジュールが必要な場合、「WinPython Command Prompt.exe」でpipを配布前に使えばOK!Winpythonの本体フォルダに取り込まれています。
これでPythonツールを簡単に実行できる状態であるといっても問題ないでしょう！
Pythonのインストールもexe化もせずにPythonツールを配布・実行できるのは便利です！
なお、具体案で示した手順でbatファイルを配布先で作ったのは、WindowsのSmartScreenで引っかかるのを防ぐためです。

# WinPythonとbatファイルを使用したPythonツール配布のデメリット
このWinPythonとbatファイルを使用したPythonツール配布ですが、いくつかのデメリットは存在します。
- WinPython本体フォルダのサイズが大きい(フル版:約3.5GB、dot版:約80MB)
- WinPythonをzip化すると展開に時間がかかる
- Pythonツールとして作成したpyファイルのソースコードが見られてしまう

本体フォルダのサイズが大きい点については配布目的であればdot版で十分ですし、複数のPythonツールを作ったときには使い回すことができるのであまり問題にならないでしょう。
展開に時間がかかることについても、20～30分ぐらいかかるかもしれないですが、1回展開するだけなので特に問題にならないかと思います。
pyファイルのソースコードが見られてしまうのは場合によっては問題になってきそうです。ここについては状況に応じて難読化などの対策が必要になってくるのではないかと思います。ご注意ください。

# あとがき
いかがでしたでしょうか？Pythonツールの配布手段に困っているのであれば、一度WinPythonについて検討してみても良いかもしれません。この記事がどなたか1人にでも役に立ったようであれば嬉しい限りです。

# 参考文献

この記事は以下の情報を参考にしました。

- [【こりゃ便利】WinPythonでPython環境をUSB化しよう！](https://resanaplaza.com/2022/01/24/%E3%80%90%E3%81%93%E3%82%8A%E3%82%83%E4%BE%BF%E5%88%A9%E3%80%91winpython%E3%81%A7python%E7%92%B0%E5%A2%83%E3%82%92usb%E5%8C%96%E3%81%97%E3%82%88%E3%81%86%EF%BC%81/)
- [【WinPython】使い方・設定まとめ](https://algorithm.joho.info/programming/python/winpython/)

[^1]: dot版はWindowsのSmartScreenに引っかかることがあります。GitHubに公開もされているものなので問題はないと思ってますが、どうしても気になるようであればフル版にしたほうが良さそうです。