Bryan Tsang
Bryan Tsang

Reputation: 71

Run specific executable with conflicting name within clojure.java.shell

I have two executables named convert.exe in my PATH. One of them is from ImageMagick, the other is from Windows.

user=> (clojure.java.shell/sh "where" "convert")
{:exit 0, :out "E:\\Program Files\\ImageMagick-6.8.3-Q16\\convert.exe\r\nC:\\Windows\\System32\\convert.exe\r\n", :err ""}

I would like to run ImageMagick's convert.exe within clojure.java.shell/sh. Normally, I can do this within PowerShell.

PS E:\Users\bt> convert --version
Version: ImageMagick 6.8.3-8 2013-03-04 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2013 ImageMagick Studio LLC
Features: DPC OpenMP
Delegates: bzlib fontconfig freetype jng jp2 jpeg lcms lzma pango png ps tiff x xml zlib

However, this does not work within clojure.java.shell/sh.

user=> (clojure.java.shell/sh "convert" "--version" :dir "E:/Users/bt")
{:exit 4, :out "", :err "Invalid drive specification.\r\n"}

Initially, I thought that I needed to move the path to ImageMagick to the front of my PATH so that it would gain precedence over Windows' binary, but that didn't have any effect. Also, I moved it to the end of the PATH just for kicks. That also didn't work.

The only alternative I know that resolves this is to rename either of the executables. But this is undesired because I do not want others to rename their ImageMagick/Windows binaries just to make my code work.

If this information is of any use, opening a new command shell (not PowerShell, but cmd.exe) starts in C:\Windows\System32. I have a feeling that this might affect the choice of executable, but I'm not sure. This only happens if I run cmd.exe from Launchy. If I use the Start Menu, it'll start in my home directory.

Is there any way to do this? I feel like I'm missing something obvious.

Upvotes: 1

Views: 392

Answers (2)

firefrorefiddle
firefrorefiddle

Reputation: 3805

I can reproduce your results. Whatever the reason is, it's buried somewhere with Java's Runtime.exec which receives the PATH, but maybe it adds the Windows System dir in front? If you want to understand it thoroughly, this is where you should continue investigation.

See the call to it in sh:

  (let [...
        proc (.exec (Runtime/getRuntime)
          (into-array cmd)
          (as-env-string (:env opts))
          (as-file (:dir opts)))]

It does work if you give an absolute path to the executable, however. So, here are two options how you can solve the problem:

  • If it is safe to assume that the IM convert.exe is the first on the PATH, just execute "where" as you showed in your question, take the first path from the :out which is returned, append convert.exe to it and use the result as program to sh.
  • If you cannot assume a correct PATH, ask the user where Image Magick is installed and store the program path somewhere. Prepend this to the program path.

Upvotes: 1

anishsane
anishsane

Reputation: 20980

Can you try giving the absolute PATH for the executable?
like,

user=> (clojure.java.shell/sh "E:\\Program Files\\ImageMagick-6.8.3-Q16\\convert.exe" "--version" :dir "E:/Users/bt")

OR

user=> (clojure.java.shell/sh "E:\\Progra~1\\ImageMagick-6.8.3-Q16\\convert.exe" "--version" :dir "E:/Users/bt")

Upvotes: 1

Related Questions