パッケージ化時にUnityプロセスを終了します



Terminate Unity Process When Packaging



転送元:https://networm.me/2019/06/09/kill-open-unity-process/

前書き

自動パッケージングを実行するときは、現在のプロジェクトを開くUnityプロセスを閉じる必要があります。そうしないと、Unityは同じプロジェクトが複数のUnityプロセスを開くことができないと報告します。



It looks like another Unity instance is running with this project open. Multiple Unity instances cannot open the same project. If you are sure that there is no running Unity instance with the project open, remove /UnityProject/Temp/UnityLockfile and restart Unity. Project: /UnityProject

周囲

  • Unity 5.6.6f2
  • Windows 7
  • macOS 10.14.4

理論的には、Unity、Windows、macOSのすべてのバージョンをサポートします。

アイデア

Unityによって記録Library/EditorInstance.json

Unityの起動後、Library/EditorInstance.json現在開いているプロセスのID情報がファイルに記録されますが、問題は、このファイルがWindowsおよびmacOSで生成されない場合が多く、理由が不明であるということです。



このメカニズムはあまり信頼できないため、除外されています。

プロセス開始後に返されたプロセスIDを記録します

Unityプロセスを開始するためのパッケージ化スクリプトを作成する場合、返されたプロセスIDを記録し、次にパックするときにプロセスを閉じるために使用するためにファイルに保存できます。

しかし、まだ問題があります。誰かがUnityで現在のプロジェクトを手動で開いた場合でも、パッケージ化は失敗します。



オープンを見つけるTemp/UnityLockfileプロセス

デフォルトでは、Unityはプロジェクトを開くときにこのファイルを作成し、開いたままにします。したがって、オペレーティングシステムでUnityという名前のすべてのプロセスをトラバースすることにより、開いているファイルに現在のプロジェクトがあるかどうかを確認します。Temp/UnityLockfileファイルがある場合は、プロセスを強制終了します。

この方法は、WindowsとmacOSの両方に適用でき、安定していて実用的です。

解決

使用psutilこのクロスプラットフォームのPythonライブラリは、この問題を簡単に解決できます。このライブラリの主な機能は、さまざまなプラットフォームでプロセスを操作するための統一されたインターフェイスをカプセル化することです。

異なるオペレーティングシステムにインストールすると、異なるネイティブライブラリが実行されるため、サポートされているすべてのプラットフォームにインストールして送信する必要があります。

注意:

  1. Unityプロセス名WindowsはmacOSとは異なります。
  2. Unityプロセスの終了後に削除する必要がありますTempディレクトリとそのコンテンツ。そうしないと、Unityを開いたときにエラーメッセージが表示されます。
  3. プロセスを強制終了した後、しばらく待って、オペレーティングシステムがプロセスを強制終了して開いているファイルを閉じるのを待つ必要があります。それ以外の場合は、プロセスを削除しますTemp/UnityLockfileファイルが占有されていることを確認します。
  4. Unityを管理者として起動した場合、権限を取得するとエラーが報告されます。実際、この状況に対処する必要はありません。通常の状況では、管理者権限でUnityを開くことはできません。誰かがこれを行う場合は、パッケージングを失敗させてください。
  5. プロセスを終了するときにKILLシグナルを使用できます。プロセスが終了するのを待つ必要はありません。クリーンアップ操作を安全に実行できるように、オペレーティングシステムを直接リサイクルするだけです。

成し遂げる

def kill_unity(project_path): unity_lockfile = os.path.abspath(os.path.join(project_path, 'Temp/UnityLockfile')) if not os.path.exists(unity_lockfile): return if platform.system() == 'Windows': unity_name = 'Unity.exe' else: unity_name = 'Unity' for proc in psutil.process_iter(): try: if proc.name() != unity_name: continue # this returns the list of opened files by the current process open_files = proc.open_files() if not open_files: continue found = False for open_file in open_files: if os.path.abspath(open_file.path) != unity_lockfile: continue found = True print(f'Kill open Unity process: {proc.pid}') sys.stdout.flush() proc.kill() # Wait for OS to terminate process and close open files time.sleep(1) break if found: break # This catches a race condition where a process ends # before we can examine its files except psutil.NoSuchProcess as err: print('****', err) shutil.rmtree(os.path.join(project_path, 'Temp'))

Pythonでファイルが開かれていない(他のプロセスで使用されていない)かどうかを確認します-Stack Overflow

参照