0

I want some of my Python scripts on Windows to have a custom icon, have their filename text in the title bar, and I want them to be pinnable to the taskbar and start menu. The easiest way to do this, I found, was to compile an exe file that just runs the Python script.

This has the benefit of everything I desire above while also not forcing me to recompile an exe every time I edit the Python script. I went about this with PS2Exe. For example, here's my compile script:

Invoke-PS2EXE "runPythonFile.ps1" "output.exe" -iconFile icons/myIconFile.ico

Here's the PS1 script that calls the Python file (named runPythonFile.ps1):

Set-Location $PSScriptRoot
./myPythonFile.py arg1 arg2
Read-Host -Prompt 'Press enter to exit'

There are two undesirable side effects from doing it this way:

  1. If I use colorama in Python to print text in color, running output.exe file does not print any color.
  2. If I use the input function in Python, the input text prompt does not show up until after pressing enter.

Sample Python script illustrating both problems:

from colorama import Fore, Back, Style
import colorama
colorama.init()

print(Style.BRIGHT + Fore.GREEN + "Howdy")
print(Style.BRIGHT + Fore.WHITE + "Done")

result = input("Please enter your pin number: ")
print(result)

Here's a brief video demonstrating both problems (which are independent of each other). Notice how when I run the exe, I have to enter the input value before the prompt shows up, but after the prompt shows up when running the Python script directly. Also notice how the "Howdy" message isn't green when I run the exe, but it is when I run the Python script.

Is there an easy solution to this? I like having an exe file that just calls the Python script for the benefits I mentioned at the beginning, but I don't like how it prevents me from using colors and messes up the input function. Any recommendation on what to do here?

1 Answer 1

0

It's because you are using the $PsScriptRoot variable. Try using the following code.

if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript"){ 
    $ScriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition 
}
else { 
    $ScriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) 
    if (!$ScriptPath){ 
        $ScriptPath = Get-Location 
    } 
}

and using $ScriptPath variable in your script instead.

1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Dec 28, 2021 at 14:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .