Search code examples
pythonpyinstallerinno-setupplotly-dash

Should I give my app write access to Program Files?


I've built a standalone desktop app using Dash by Plotly. To deploy it I'm using pyinstaller to create an executable and Inno Setup to create an Installation Wizard for the user to install the app. When I use pyinstaller to create an executable I'm not using the one file option as I've got several configuration files.

When run using the pyinstaller executable the app works as expected. But when I use the installed one it doesn't work. My hunch says it's a write permissions issue per this issue; my app creates some temporary files for intermediary steps. How should I handle this? Is there a temp folder on Windows I can save files to that the app doesn't need special write access to? Should I give write access to my program by default?


Solution

  • The answer, as stated by @PanagiotisKanavos in the comments, isn't to give write access to Program Files. The correct way to implement this is using the tempfiles module of python.

    import tempfile
    
    def functionA():
        temp_file = tempfile.TemporaryFile()
        temp_file.write("hello world")
        contents = temp_file.read()
        temp_file.close()
    
    def functionB():
        temp_file = tempfile.NamedTemporaryFile()
        file_path = temp_file.name
        temp_file.close()
    

    Note that tempfile deletes a temporary file when it is closed. If you intend to use the file on a windows platform it must be closed before it can be read by another process. To do this use the delete=False flag when instantiating the TemporaryFile object. Note that you will have to delete the file manualy. This is easily done by using a named temporary file and deleting the file at that path once you are done with it.

    import tempfile
    
    def functionC():
        temp_file = tempfile.NamedTemporaryFile(delete=False)
        temp_file.write("hello world")
        temp_path = temp_file.name
        temp_file.close()
        os.system(f"echo {temp_path}")
        os.remove(temp_path)