XYplorer and Python (portable installation)

Discuss and share scripts and script files...
Post Reply
FileChaosBuster
Posts: 2
Joined: 22 Sep 2024 13:09

XYplorer and Python (portable installation)

Post by FileChaosBuster »

I would like to share my XYplorer customization to easily add Python programming language support in a portable XYplorer installation.

Example of my personal use:
- convert the selected image(s) to another image format with 2 clicks using Pillow (jpg|png|webp)
- create a python virtual environment in the current folder. Copying boilerplate files/folders to quick start a project
- run the current selected python script and using venv if found


----
XYplorer and Python
Using Python can boost your XYplorer experience, even in the portable version. No need to install Python on your machine—just use the embeddable version.

0. Requriements
  • XYplorer Portable
Not really a requirement, but a portable installation makes more sense because it makes it easy to back up XYplorer settings and use them on other machines. A portable app is the way to a happy life.

1. Download Embeddable Python
Go to https://python.org

and download the zip file:

Code: Select all

Windows embeddable package (64-bit)
In this guide, we use python version 3.12:

https://www.python.org/ftp/python/3.12. ... -amd64.zip

2. Unzip Inside a Folder in Your XYplorer Installation Folder
You can name the folder whatever you want, but in this guide, we use python_embed as an example.

Code: Select all

    xyplorer_full_noinstall/
    ├── Data/
    └── python_embed/
3. Install PIP
PIP is a package manager for Python packages, or modules, if you like.

Download: https://bootstrap.pypa.io/get-pip.py

Saved location

Code: Select all

    xyplorer_full_noinstall/
    ├── Data/
    └── python_embed/
        ├── get-pip.py
        ├── ...  
        ├── python.exe
Install PIP using the embedded python.exe.

Open the Command Prompt in the python_embed folder and type:

Code: Select all

> python get-pip.py
Now you can install packages using:

Code: Select all

> python -m pip install SomePackage
4. Installing Tkinter (Optional)
Tkinter is a Python library that can be used to construct basic graphical user interface (GUI) applications.

For this step to work, you need to have already installed the same Python version on your machine using the Windows installer (64-bit) executable.

The reason is that the .zip version doesn't contain the tkinter module, and you need to manually copy certain folders and files.

Copy:
  • tkinter/ (folder) -> python_embed/Lib/site-packages/tkinter/
  • tcl/ (folder) -> python_embed/tcl/
  • _tkinter.pyd -> python_embed/
  • tcl86t.dll -> python_embed/
  • tk86t.dll -> python_embed/
  • zlib1.dll -> python_embed/

Code: Select all

    xyplorer_full_noinstall/
    ├── Data/
    └── python_embed/
        ├── Lib/
        │   └── site-packages/   
        │       └── tkinter/
        ├── _tkinter.pyd  
        ├── tcl86t.dll  
        ├── tk86t.dll   
        ├── zlib1.dll
        ├── ...   
        ├── Scripts/
        └── tcl/
5. Editing python3xx._pth File
Depending on the version you downloaded, the file name will be different.

ver 3.11 is python311._pth
ver 3.12 is python312._pth
...
The file is located in the root of the python_embed folder.

Code: Select all

    xyplorer_full_noinstall/
    ├── ... 
    └── python_embed/
        ├── python312._pth
        ├── ...   
Open it with any text editor and add Lib/site-packages and Scripts:

Before

Code: Select all

python312.zip
.

# Uncomment to run site.main() automatically
#import site

After

Code: Select all

python312.zip
Lib/site-packages
Scripts
.

# Uncomment to run site.main() automatically
#import site

6. Creating XYplorer and Python Script
test.py

Code: Select all

import argparse

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-f", "--folder")
    args = parser.parse_args()
    if args.folder:
        print(f"python: arg -f: {args.folder}")
    else:
        print(f"python: arg -f not found")
run_test_py.xys

Code: Select all

function main(){
    // <curpath> current folder
    // <curitem> current item
    $python = """<xypath>\python_embed\pythonw.exe""";
    $script = """<xypath>\Data\Scripts\test.py"" -f ""<curpath>""";
    msg( runret("$python $script") );
}
main();
Files should be saved inside \Data\Scripts\ in this example:

Code: Select all

    xyplorer_installation/
    ├── Data/
        ├── Scripts/
            ├── run_test_py.xys
            └── test.py
tips:
Using pythonw.exe avoids opening the console window every time you run the script.
When creating your .xys script, surround any paths with "" because spaces in paths can generate errors.


7. Add Custom Button to Activate the Script
Add a button to toolbar and edit

On Left Click:

Code: Select all

Load "run_test_py.xys"
---
Note about import

Remember that the path to modules and packages should be relative to the python_embed folder, as defined in python3xx._pth. When pip is used for installation, packages are installed in the Lib/site-packages folder, which is already included in python3xx._pth in this guide.


Example

Code: Select all

    xyplorer_full_noinstall/
    ├── ... 
    └── python_embed/
        ├── ... 
        └── my_projects/
            └── myapp/
                ├── module_name.py
                └── test.py
test.py

Code: Select all

import my_projects.myapp.module_name

def main():
    module_name.foo()

if __name__ == "__main__":
    main()



Congratulation, you have a portable XYplorer with in python support :D
Last edited by FileChaosBuster on 28 Sep 2024 16:33, edited 1 time in total.

admin
Site Admin
Posts: 62028
Joined: 22 May 2004 16:48
Location: Win8.1 @100%, Win10 @100%
Contact:

Re: XYplorer and Python (portable installation)

Post by admin »

I have not tested it (no time, sorry), but thanks for the extensive and well-structured input! :tup: :beer:

highend
Posts: 13651
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: XYplorer and Python (portable installation)

Post by highend »

@FileChaosBuster
Nice first post!
Maybe you should add a few python scripts to show why somebody should use this combination?


Regarding the necessity to install Python to get Tkinter out of it:

The Python installation file can be extracted through "dark.exe" (this is a part of the wix toolset)
Current direct download link: https://github.com/wixtoolset/wix3/rele ... naries.zip

The .zip contains the necessary 3 files:

Code: Select all

dark.exe
winterop.dll
wix.dll
An extraction would look like this:

Code: Select all

dark.exe "D:\Downloads\python-3.12.6-amd64.exe" -x "D:\Downloads\python-3.12.6-amd64"
Afterwards the necessary .msi file can be found in
"D:\Downloads\python-3.12.6-amd64\AttachedContainer\tcltk.msi"

Which can then be extracted via, e.g.:

Code: Select all

msiexec.exe /a "D:\Downloads\python-3.12.6-amd64\AttachedContainer\tcltk.msi" /qb TARGETDIR="D:\Downloads\python-3.12.6-amd64\AttachedContainer\tcltk"

Ofc I use scripts for these kind of tasks so that I don't do any of these steps manually...
One of my scripts helped you out? Please donate via Paypal

bossi
Posts: 47
Joined: 30 Jul 2022 11:09

Re: XYplorer and Python (portable installation)

Post by bossi »

just my two cents , you can run any python script via venv like :

Code: Select all

$response = runret(lax("cmd" /c "D:\path\to\_venv_312\Scripts\activate.bat && python D:\path\to\file.py function "$argument""))
and inside the py file you fetch the function and $argument via :

Code: Select all

if __name__ == "__main__":
    if len(sys.argv) > 2:   
        globals().get(sys.argv[1])(sys.argv[2])  
    elif len(sys.argv) > 1:   
        globals().get(sys.argv[1])()

FileChaosBuster
Posts: 2
Joined: 22 Sep 2024 13:09

Re: XYplorer and Python (portable installation)

Post by FileChaosBuster »

A little recipe:

HOW IT WORKS:

When browsing a folder:
open the terminal in the current directory, activate the virtual environment if a .venv subfolder is found.

When a file is selected:
open the terminal in the current directory, activate the virtual environment if a .venv subfolder is found, and execute the .py script .

Required:
- Windows Terminal

run_py_script_with_venv.xys

Code: Select all

"Run Python File with VENV"
   // settings
   perm $VENV_FOLDER = ".venv";  // Your naming convention for the venv folder
   perm $TERMINAL_PROFILE = "Windows PowerShell";  // Profile name to be used by Windows Terminal
   // Depending on the language of your Windows installation, the profiles may have different names. 
   // 'Command Prompt' is 'símbolo del sistema' in Spanish, 'Invite de commandes' in French, and 
   // 'Eingabeaufforderung' in German.
   // You should check your Windows Terminal for the correct name. 
   // If you leave this setting blank, Windows Terminal will use the default profile.
   //
   // freebie: Adding Git-Bash to Windows Terminal
   // https://www.timschaeps.be/post/adding-git-bash-to-windows-terminal/

   function has_venv_folder($path) {
      return (exists("$path\$VENV_FOLDER") == 2);
   }

   function has_py_extension($file) {
      if ($file != "") {
         $file_name = getpathcomponent($file, "file");
         $file_name = recase($file_name, "lower"); 
         if (getpathcomponent($file_name, "ext") == "py") {
            return TRUE;
         } else {
            msg("$file_name - wrong file extension!");
            return FALSE;
         }
      } else {
         return FALSE;
      }
   }

   function main(){
      // Command line arguments for Windows Terminal
      // https://learn.microsoft.com/en-us/windows/terminal/command-line-arguments?tabs=windows
      if (has_py_extension(<curitem>)){
         if (has_venv_folder(<curpath>)) {
            run lax(wt.exe new-tab --profile "$TERMINAL_PROFILE" --startingDirectory "<curpath>\$VENV_FOLDER\Scripts" CMD /k "activate & cd <curpath> & python <curitem>")
         } else {
            run lax(wt.exe new-tab --profile "$TERMINAL_PROFILE" --startingDirectory "<curpath>" CMD /k "python <curitem>")
         }
      } else {
         if (has_venv_folder(<curpath>)) {
            run lax(wt.exe new-tab --profile "$TERMINAL_PROFILE" --startingDirectory "<curpath>\$VENV_FOLDER\Scripts" CMD /k activate & cd "<curpath>")
         } else {
            run lax(wt.exe new-tab --profile "$TERMINAL_PROFILE" --startingDirectory "<curpath>")
         }
      }
   }

   main();
Customizing to your Environment:

$VENV_FOLDER= ".venv"
Your naming convention for the venv folder.

$TERMINAL_PROFILE = "Windows PowerShell"
Depending on the language of your Windows installation, the profiles may have different names. 'Command Prompt' is 'símbolo del sistema' in Spanish, 'Invite de commandes' in French, and 'Eingabeaufforderung' in German. You should check your Windows Terminal for the correct name. If you leave this setting blank, Windows Terminal will use the default profile.

I assigned a button to run this XY script.

Post Reply