How to click on a file in Linux and have a Bottles Windows program open and load that file

How to click on a file in Linux and have a Bottles Windows program open and load that file.
aka “How to do file associations in Linux for Windows programs running in a Bottle”
aka “How to run a Windows program from a file association in Linux and have the program open the file automatically.”

The instructions below are based on my experience with MS Word 2007 running in a Bottle. I posted a detailed description of the problem a few days back, here.

These instructions will allow you to double-click on a data file - in a Linux directory - associated with a Windows program (e.g. a docx file, or an xlsx file, etc.) to open that program through Bottles, passing the data file’s name as an argument to the progam (which normally causes the program to open the file).

Please note that this solution will NOT work if the file’s name or path contains SPACES.
I believe this solution can be adapted to resolve that issue, however, and if anyone does so, please let me know.

  1. Create your Bottle as usual and make sure you can start the Windows program from the Bottle.

  2. In Bottles, click on the 3-dot menu of the program and select “Add Desktop entry”.

  3. Find the new app in your Linux application launcher. In Kubuntu, it gets created in the “Lost & Found” folder (you can move it elsewhere).

  4. Now you need to edit the command that launches the app. Right click on the app and choose the option that allows you to edit it. In Kubuntu, it’s called “Edit Application”.

  5. Find the command that starts the app. It looks like this:

flatpak run --command=bottles-cli com.usebottles.bottles run -p WINWORD -b 'Office2007'

You will need to change the -p argument to -e. The -e argument takes the fully-qualified file name of the Windows program in the Linux directory structure.
My new command looks like this:

flatpak run --command=bottles-cli com.usebottles.bottles run -b 'Office2007' -e '/home/eduardo/.var/app/com.usebottles.bottles/data/bottles/bottles/Office2007/drive_c/Program Files/Microsoft Office/Office12/WINWORD.EXE'

  1. Here’s where it gets tricky. Bottles has a -a argument that you can add to the end of the command to pass arguments to the Windows program. If you simply add -a “test” to the end of the command, your Windows program will be started and given an argument “test”. It doesn’t work for file paths, though, because it doesn’t replace or escape the slashes. For the whole thing to work, we need to pre-process the slahes on the final argument. But we can’t do that using bash string replace, because these commands are run under a dash shell. So I decided to use sed. My final command looks like this:

flatpak run --command=bottles-cli com.usebottles.bottles run -b 'Office2007' -e '/home/eduardo/.var/app/com.usebottles.bottles/data/bottles/bottles/Office2007/drive_c/Program Files/Microsoft Office/Office12/WINWORD.EXE' $(printf '%s' "%F" | sed 's/\//-a z:\\\\/' | sed 's/\//\\\\/g')

… the first sed substitutes the first / in the path with -a z:\\ while the second sed replaces every other instance of / with \\
… also notice that if %F is empty (as when we click on the app itself and not on an associated file), the whole printf results in an empty string.

  1. Now all that’s left is to associate the program with the MIME file extension. In Kubuntu, I simply right-click on a Word document (.docx), choose “Open with” then “Other application”, find the application I just created, and mark the checkbox “Remeber application association for all files of type”.

  2. Done. From now on, whenever you double-click on a docx file anywhere in Linux, Word will open and load that file.

Let me know if you use this; I welcome any additional insights.

Cheers.

1 Like

Thanks Ebaldino for your useful post. I applied the solution - it’s working perfectly.
The only thing preventing me from achieving Bottles nirvana is the ability to open files containing spaces in their names or paths. Hope someone comes up with a solution soon.

it doesn’t work for me. I don’t know why. It only opens WINWORD.EXE but doesn’t actually opens the file.
Here’s my command.
flatpak run --command=bottles-cli com.usebottles.bottles run -b 'Office2007' -e '/var/home/USERNAME/.var/app/com.usebottles.bottles/data/bottles/bottles/Office2007/drive_c/Program Files (x86)/Microsoft Office/Office12/WINWORD.EXE' $(printf '%s' "%F" | sed 's/\//-a z:\\\\/' | sed 's/\//\\\\/g')

Note that I am using Fedora Silverblue. So my Home directory is in /var/home/USERNAME

Hi John,

Your syntaxe seems correct… so I can only imagine there’s something amiss with the file extension association. In KDE I have an option to Open With / Other Application that lets me pick the application to open that file type. There’s also an option to “Run in terminal” which will open a terminal window and input the command on the command prompt.
Actually, you might want to try to just copy the whole command and run it from the command prompt, it may point you to where the problem is…

Additionally, I found a quick-and-dirty Word macro that retrieves the command used to open Word. To use this, open Word on a blank document, press Alt+F11, open the Normal/ThisDocument VB screen, paste the code below there, then put the cursor anywhere in the code and hit the “play” icon up on top. It should list the command that was used to open Word on the blank document.

Sub ReadCmdLine()
Dim pCmdLine As Long ’ Pointer to the string
Dim strCmdLine As String ’ Command line string
’ Get the pointer to the command line string
pCmdLine = GetCommandLineA
’ Fill the string with zeros
’ 300 characters for command line seems to be enough
strCmdLine = String$(300, vbNullChar)
’ Copy from the pointer to VBA-style string
lstrcpynA strCmdLine, pCmdLine, Len(strCmdLine)
’ At this point we got the string
’ But rest of it filled with 0 characters.
strCmdLine = Left(strCmdLine, InStr(1, strCmdLine, _
vbNullChar) - 1)
'Insert the string at current position
Selection.Text = strCmdLine
End Sub

Hope this helps.
Cheers.

Not to necro a thread, but is it possible to get the same thing working for URLs instead of files? I have a program running in Bottles that uses a browser to auth with an API, and then redirects to the program in bottle. I’ve done all the required XDG stuff, but instead of opening the URL with the current running instance of the program, Bottles attempts to launch a new instance.