Shell executing a program

Deploying to Windows? Utilizing VB Script execution? This is the place to ask Windows-specific questions.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
massung
Posts: 93
Joined: Thu Mar 19, 2009 5:34 pm

Shell executing a program

Post by massung » Mon Dec 14, 2009 11:41 pm

I have an interesting problem here that I'm hoping someone here has solved already...

I have a URL to some media data that I want the user to watch/listen to. I also want Rev to just launch whatever application the user has bound to that file type. I can't just use the start command in shell() because - since the "file" is a URL - it will just launch IE (or whatever the default browser is) and many times it will prompt the user to download the media, which I don't want.

So, to get the associated application with the file, I've done the following (comments welcome if there's an easier way to do this):

Code: Select all

set the itemDelimiter to "."

-- get the file extension (lower cased)
get the lower of the last item of tURL

-- get the command line required to open the file of this file
get queryRegistry("HKEY_CLASSES_ROOT\" & it & "\")
get queryRegistry("HKEY_CLASSES_ROOT\" & it & "\shell\open\command\")
Up until this point, everything is good. But, the command line that gets sent back is something like this:

Code: Select all

c:\program files\quicktime\quicktime.exe "%1"
Replacing "%1" with tURL is simple. However, I still can't send this on to shell() because, c:\program files\quicktime\quicktime.exe isn't quoted. If I do, I - of course - get an error: "c:\program is not a recognized program...."

So, the question is: how can I figure out what exactly is the "program" in the command returned from the registry so I can quote it? Better still, anyone know of any other way of getting the application associated with a file type aside from bouncing around in the registry?

Jeff M.

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Shell executing a program

Post by mwieder » Tue Dec 15, 2009 7:54 am

Jeff-

You're working way too hard. Check out the "launch document" command. Place the following in a button script:

Code: Select all

on mouseUp pMouseBtnNo
    answer file "where is the file to launch?"
    if it is not empty then
        launch document it
    end if
end mouseUp

massung
Posts: 93
Joined: Thu Mar 19, 2009 5:34 pm

Re: Shell executing a program

Post by massung » Tue Dec 15, 2009 6:15 pm

Sadly, this won't work. Thanks for the suggestion, though.

It won't work (as expected) because the "document" is always a URL - hence, it will always launch a browser. I don't want that. Instead, I want to launch a local application that can open a URL as media. For example:

quicktime.exe "http://some.random.url.com/movie_trailer.mov"

If I just do launch document "http://.../movie_trailer.mov", IE will launch (or whatever the default browser is) and play the movie in the browser... not what I'm looking for.

Jeff M.

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Shell executing a program

Post by sturgis » Tue Dec 15, 2009 8:06 pm

Try converting it to the shortFilePath

Should change your example to c:\progra~1\quicktime\quicktime.exe which should work fine. Assuming windows OS later than 2k (the one i'm working with) still are backwards compatible with the 8.3 file path format.

edit:
Also, you can use the launch "whatever" with "program" file this way.
Don't use the url keyword as it seems to force to the default browser for me.

launch "http://the.Url.In.Question.Com/goober.mov" with "C:\PROGRA~1\myProgram\myprogram.exe"

massung
Posts: 93
Joined: Thu Mar 19, 2009 5:34 pm

Re: Shell executing a program

Post by massung » Tue Dec 15, 2009 10:38 pm

Again, I thank you for the reply, but I promise - I'm not overly complicating the problem. :D

I'd like the program launched to be whatever the user has selected as the one associated with that file type. So, while it would be nice to just say: launch "http://.../foo.mp4" with "quicktime.exe", I can't do that, because it's possible the user has GOM or VLC or some other program associated with mp4 videos.

The registry gives me this information (perhaps there is another way of getting it that's better, though?).

The problem with the registry, though, is that it gives me more information than just the application filename... it also gives me the command line to open it (which is also good). I'd love to use the short name for the application, which would get rid of my spaces problem, but that requires me to already know the application name, and - once I have that - the problem doesn't matter any more as I can just quote it. :)

To make matters worse, the registry isn't even all that consistent with itself. Many application associations quote the EXE filename in the registry. Others do not. Windows Media Player (for example) already quotes its own EXE in the association entry, while Apple's QuickTime does not.

Thanks again for the replies everyone. I was just hoping there was a way for me to easily figure out just the application name associated with a file type, and not the entire command line for launching it.

Jeff M.

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Shell executing a program

Post by sturgis » Tue Dec 15, 2009 11:19 pm

Right, thats what I meant by converting it to the short filepath. Do exactly what you were doing to begin with to get the path. At which point you convert it using shortFilePath which eliminates the spaces and makes it directly usable.

So, do your registry magic. It returns c:\program files\the app folder\theapp.exe, and put it in tFilePath

then do
put the shortFilePath of tFilePath into tShortPath.
So, using your example if you have "c:\program files\quicktime\quicktime.exe "%1"" into tFilePath
remove the %1 (easy to do) and run it through the shortFilePath function which converts it to
c:\progra~1\quicktime\quicktime.exe with no spaces which is perfectly usable. You can still do it as a shell call or whatever you want, was just pointing out that once you get to this point, launch works fine as long as you don't use the document keyword.
launch "http://theurl.com/here.mov" with tShortPath


the shortFilePath function doesn't go out and get the path, it just converts a string you feed it to the short windows version of the path. It also doesn't confirm that the supplied path or the resulting path actually exist, so that part is on you, but since you already have a method to get the long path to the file, shortFilePath should work fine.

As far as I can see the only exceptions to this would be if you had a folder "program files" and a folder "program somethingelse" in which case program somethingElse would most likely convert to progra~2 in windows, but I don't think the shortFilePath function can accomdate that situation, so shortFilePath would most likely still return progra~1 when doing the conversion.

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Shell executing a program

Post by mwieder » Tue Dec 15, 2009 11:28 pm

Now I see what you're trying to do. Why doesn't quoting work for you? There shouldn't be a problem with this. ShortFilePath should also do the trick unless you really need the full path.

Code: Select all

on mouseUp pMouseBtnNo
    local tCommand
    
    put quote & "c:\program files\quicktime\quicktime.exe" & quote into tCommand
    get shell(tCommand)
    put it
end mouseUp

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Shell executing a program

Post by sturgis » Tue Dec 15, 2009 11:51 pm

Yeah, like that! *points down* easier than doing the shortFilePath thingy by far. Think I need about a year of sleep.
mwieder wrote:Now I see what you're trying to do. Why doesn't quoting work for you? There shouldn't be a problem with this. ShortFilePath should also do the trick unless you really need the full path.

Code: Select all

on mouseUp pMouseBtnNo
    local tCommand
    
    put quote & "c:\program files\quicktime\quicktime.exe" & quote into tCommand
    get shell(tCommand)
    put it
end mouseUp

massung
Posts: 93
Joined: Thu Mar 19, 2009 5:34 pm

Re: Shell executing a program

Post by massung » Wed Dec 16, 2009 12:49 am

mwieder wrote:Now I see what you're trying to do. Why doesn't quoting work for you? There shouldn't be a problem with this. ShortFilePath should also do the trick unless you really need the full path.

Code: Select all

on mouseUp pMouseBtnNo
    local tCommand
    
    put quote & "c:\program files\quicktime\quicktime.exe" & quote into tCommand
    get shell(tCommand)
    put it
end mouseUp
LOL. It doesn't work because I don't know what I'm quoting... that's the whole point. /facepalm. Sorry :D

Code: Select all

put queryRegistry("HKEY_CLASSES_ROOT\QuickTime.mp4\shell\open\command\") -->
c:\program files\quicktime\quicktime.exe "%1"
The return value isn't the application name... the return value is the application name plus more random stuff. I need to figure out what the application name is within the returned string. For example, if it was Windows Media Player, the return value would be:

Code: Select all

C:\Program Files\Windows Media Player\wmplayer.exe /prefetch:6 /Open "%L"
Again, I need to figure out what the executable is from the returned string.

I can't look for ".exe", because applications could be ".bat", ".com", ".pyc", or many other types (albeit most of the time it'll be .exe). I've considered looking for the last "\" to find the executable name, but it's also possible to have "\" in a command line argument to the program. If I knew what to quote, I agree 1000% that this would be a dead simple problem :).

Anyway, I appreciate that everyone's trying to help and I'm always interested in simplifying the problem instead of complicating the solution.

SparkOut
Posts: 2943
Joined: Sun Sep 23, 2007 4:58 pm

Re: Shell executing a program

Post by SparkOut » Wed Dec 16, 2009 1:35 am

If you want to make it generic, it's harder still.

Do the registry lookup for a .mov file and you get:

Code: Select all

C:\Program Files\QuickTime\QuickTimePlayer.exe "%1"
as the return value if the default player is set to QT. Try and open a file .mpg and you may get something like

Code: Select all

"C:\Program Files\Windows Media Player\wmplayer.exe" /prefetch:9 /Open "%L"
Note that the program path is not quoted for QuickTime, but it is for Windows Media player.

Also if you try to launch most applications on Windows via shell ("start" && <etc>) when you have set the hideConsoleWindows to true, then you need to include a "spare" empty pair of double quotes before the target application path to act as the "title" for the "invisible" console window. If you try and launch QT via shell like that then you get an error on launch, so you have to exclude the console title placeholder. I had a little script that I was messing about with that had the launch line:

Code: Select all

get shell ("start" && tTitleHolder && tPseudoQuote & tTargetApp & tPseudoQuote && tTargetMedia)
where the script looked at the first char of the target app path returned from the registry and checked whether is was a quote to react accordingly by either emptying or setting the tTitleHolder and tPseudoQuote to be the inverse of the other. At the other end, I looked for some consistency and decided that the "most likely but by no means guaranteed" option was to check for offset of

Code: Select all

space & quote & "%"
and put empty into that part of the value returned from the reg from where the offset was found to the last char. That seemed to work in the (very limited) trial I did, but it's definitely something that you are fighting with in the inconsistencies of extracting this information from the Windows registry.

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Shell executing a program

Post by mwieder » Wed Dec 16, 2009 2:55 am

<g> Windows is such a pain...

How about something like this (untested) after you've gotten the registry entry into tRegEntry:

Code: Select all

repeat with x = 1 to the number of words in tRegEntry
  if char -4 of word x of tRegEntry is "." then
    delete word (x+1) to -1 of tRegEntry
    exit repeat
  end if
end repeat

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Shell executing a program

Post by sturgis » Wed Dec 16, 2009 3:13 am

Is the executable always the first part returned? If so, this should work.

Code: Select all

set the itemDelimiter to "."
put item 1 of tRegistryReturn & "." & word 1 of item 2 of tRegistryReturn into tPath
if char 1 of tPath <> quote then put quote before tPath
if the last char of tPath <> quote then put quote after tPath
put tPath

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Shell executing a program

Post by mwieder » Wed Dec 16, 2009 5:57 am

Yep, that looks good, too, and nicely adds the surrounding quotes for good measure. The only thing to watch for (and this affects both our solutions) is having subdirectory names with embedded periods, but they're rare enough that this shouldn't be an issue.

massung
Posts: 93
Joined: Thu Mar 19, 2009 5:34 pm

Re: Shell executing a program

Post by massung » Wed Dec 16, 2009 7:46 am

Thanks, everyone, for all the ideas. I've tried most of these (and many do work well - meaning >95% of the time). I was hoping for an API call I missed or some really nifty trick someone may have thought of.

Oh well, 95% may have to be "good enough" this time around.

Jeff M.

Post Reply