Subject: Re: browse-url

From: Andrew Innes <[email-masked]>
Date: Fri, 1 Nov 1996 13:25:44 GMT

On Thu, 31 Oct 1996 14:14:44 -0800, David Jeffers <[email-masked]> said:
>>>>>>"George" == George D Hadden <[email-masked]> writes:
>
George>has anyone gotten the browse-url described in the new
George>(10/10) ntemacs web page to work with w95?  it bombed out
George>asking for
George>"/ProgramFiles/Netscape/Navigator/Program/reg.ini" i
George>provided a blank one, but the system still doesn't work.
George>if i try to execute shelex.exe at the command line, it
George>tells me that it can't run in dos, which make me think
George>that it's bombing out the same way when emacs calls it
George>with call-process.

The shelex.exe/shell-execute-url method does work (I am using it
successfully with IE3), but there is a bug in the Netscape installation
program which means that Netscape doesn't register itself correctly as
the system handler for URLs.

Someone on comp.os.ms-windows.programmer.win32 recently posted about
precisely this problem using ShellExecute to control Netscape.  The
problem is that Netscape creates the correct registry key, but in the
wrong location - HKEY_CURRENT_USER instead of HKEY_LOCAL_MACHINE.

I've appended the post below - do an AltaVista search of Usenet for
"shellexec +url +final +solution" to get more details on the follow-up
to this post.

AndrewI

-----------------------------------------------------------------
ShellExecuting a URL: Final Solution (?) & Bug Fix

------------------------------------------------------------------------

>From           [email-masked] (John Grant)
Organization   Natural Resources Canada, Ottawa
Date           Mon, 21 Oct 1996 05:42:58 GMT
Newsgroups     comp.os.ms-windows.programmer.win32,comp.os.ms-windows.programmer.winhelp
Message-ID     <[email-masked]>

------------------------------------------------------------------------

Synopsis:
--------
ShellExecuting a URL on Windows '95 will work for either Win16 or Win32 apps,
if your browser installed URL.DLL with the correct registry keys. Netscape
does it wrong, so you have to fix it first.

HCW breaks the ShellExecute() macro, so use the ExecFile() macro instead.

Introduction
------------
I'm finally getting around to posting this information. It concerns the
use of ShellExecute() to 'run' a URL on Windows '95 (not 3.x).  There are
5 parts:
  0. requirement
  1. false solutions
  2. the real solution
  3. Netscape installation bug
  4. WinHelp & ShellExecute + HCW bug

0. Requirement
   -----------
   A long time ago, the question of ShellExecuting a URL came up. Several
   solutions were posted. Raymond Chen (unofficial Microsoft guru here)
   said something like:

   "just use ShellExecute(hwnd,0,"http://your.web.page/here",0,0,SW_NORMAL)"

   There were also several other answers. So I tried ShellExecute() on a
   Windows '95 system and I could *not* get it to work. So I asked again.

1. False Solutions
   ---------------
   Several solutions were posted here and I received some by e-mail.
   But Ray Chen had stated quite clearly that ShellExecute() would work.
   Here are Ray's comments (marked RC) on some of the answers that appeared
   here:

   (a) "Create a .url file that looks like:
	[internetShortcut]
	URL=http://your.web.page/here"

        RC: Don't do this. The format of an internal shortcut file may change
	    in the future. If you need to access the contents of .URL files,
	    use the IUniformResourceLocator interface. But if all you want
	    to do is exec a URL, just pass the URL to ShellExecute().

   (b)	"Use ShellExecuteEx instead"
	RC: ShellExecuteEx() also works, but isn't required

   (c)	"it only only works if you have Plus! or Internet Explorer"
		&
   	"It will only launch Microsoft Internet Explorer, not Netscape"
	RC: Microsoft Internet Explorer installs URL.DLL, but is hardly
	    the only program that does so.
	    Internet Explorer 1.0 came with Plus!

   (d)	"You need wininet.dll"
	RC: red herring

   (e)	"It only works if you execute a shortcut"
	RC: it works with a shortcut, but it also works with a plain URL

   (f)	"You have to look up HKEY_CLASSES_ROOT\http\shell\open\command to
	get "c:\program files\plus!\Micros~`\iexplorer.exe -nohome %1"
  	and then fiddle with that"
	RC: This is one of the registry steps that is supposed to have
	    been done by the browser. This is one of the places where
	    the default browser is registered, and it's one of the places
	    where URL.DLL looks (you also register the browser in the
	    DDEExec section of the http\shell\open key if your browser
	    supports DDE). Normal applications shouldn't care.

   (g)	"You have to look up .html or .htm or http in the registry and
	WinExec it yourself"
	RC: sheer desperation

2. The Real Solution
   -----------------
   Here's what Ray said in earlier comments here:

    "ShellExecute recognizes the http://, ftp://, telnet://, news://, etc.
     prefixes and runs the program that is recorded in the registry as "the
     program that handles this type of URL".  (Actually, ShellExecute asks
     URL.DLL to do this work, so if you don't have URL.DLL on your system,
     then ShellExecute'ing a URL won't work.  But all the popular web
     browsers install URL.DLL, so there shouldn't be a problem there)"

   and here he provides much more detail:

   "The file that teaches ShellExecute how to handle URLs is URL.DLL.
    URL.DLL is a redistributable DLL that IE and Netscape both install.

    URL.DLL weasels into the ShellExecute function by adding itself
    to HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\
    Explorer\ShellExecuteHooks.

    None of this information is supposed to concern you.

    The basic answer is: Any browser that is designed for Windows 95
    (or Windows NT 4.0) will install URL.DLL and do the magic registry goo.
    At which point, ShellExecute of a URL will launch the browser.

    If this isn't working, then it means that some step in the installation
    procedure isn't working."
		---

  Ok, so I had installed Netscape and sure enough URL.DLL was there. But it
  *still* would *NOT* work for me. Why not? Well, because Netscape put the
  magic key in the wrong place! Read on.

3. Netscape Installation Bug
   -------------------------
   Fire up Regedit and do a search for ShellExecuteHooks. If you have
   installed Netscape you will find it in:
	HKEY_CURRENT_USER
	HKEY_USERS

   But Ray clearly states that the key must be located in HKEY_LOCAL_MACHINE.

   If you have installed Plus!, Internet Explorer or possibly Microsoft
   Office?), you will probably also find it in HKEY_LOCAL_MACHINE.

   If this works for you:
	c:\> start http://www.microsoft.com

   then you probably have the key in HKEY_LOCAL_MACHINE where Ray says it
   is supposed to be.  If not, then you need to fix it by putting the
   same key you find in HKEY_CURRENT_USER in the correct location, i.e.
   HKEY_LOCAL_MACHINE.

   I don't know what this looks like on a single-user Netscape setup, but
   for our network-licenced version, the file containing the error is in
	...netscape\_istmp0.dir\reg.url

   There are 4 HKEY_CURRENT_USER keys in there. I don't know about all of
   them, but ShellExecuteHooks should be in HKEY_LOCAL_MACHINE.

   I have tried out several W95 systems around here. Some of them were ok
   (had installed Microsoft Office which probably fixed it), but most were
   broken because of this key.  When I fixed it, everything worked ok,
   including:
	- a Win16 program calling ShellExecute(.."http://...")
	- a Win32 program calling ShellExecute(.."http://...")
	c:\> start http://...

   where *NONE* of these worked before.

4. WinHelp, ShellExecute & HCW Bug
   -------------------------------
   First of all, none of this URL.DLL magic works on Windows 3.x. There
   are ways around that which involve a custom DLL function, but they
   do not concern me here (apparently there is a recent article in DDJ
   on doing this magic in Windows 3.x). I'm only concerned about Windows
   '95 & URL.DLL

   (a)	for a Win16 .HLP file on Windows '95
	add this to your .hpj:
		[config]
		RegisterRoutine("shell","ShellExecute","USSSSi")

	and in your .HLP file, just call the ShellExecute API function
	like so:
		!ShellExecute(hwndApp,"open","http://...","","",1)

	For some reason, "" doesn't work - use "open". The docs for
  	the ShellExecute() API function say that NULL will give you the
	default verb which is "open", but they don't say that "" will also
	give you "open". NULL is not the same as "": it all depends on
	how ShellExecute() is written. Anyway the explicit "open" works.

	*IF* you have the ShellExecuteHooks key in the correct
	HKEY_LOCAL_MACHINE, you should be able to click on that link and
	run the browser. It works for me.

   (b)	for a Win32 .HLP file on Windows '95
	Remove any RegisterRoutine for ShellExecute from your .HPJ. You
	don't need it because there is a built-in ShellExecute() macro.

	This is where I had a lot of problems. I tried all combinations
	that I could imagine for ShellExecute() args and I couldn't even
	get it to ShellExecute() a 'hello.wri' file(!), let alone get it
	to work with a URL. Everytime I clicked on it, I got a runtime
	error: "missing ')' 1031".

	BaDge helped me out on this one. He pointed out the following bug
	(#19) from the WH 4 buglist:

	"Internal ShellExecute commands that use the 4th, 5th or 6th
	parameters (operation, path or topic ID) do not work. Only
	the first three parameters can be used. Reported by Microsoft"

	Well, not quite. I couldn't even get it to work using a single
	argument...

	My problems weren't related to incorrect operation of ShellExecute.
	The problems are caused by HCW screwing up when it compiles the
	code. It adds bogus `' arguments at the end of the macro call.
	For example, if I used:
		!ShellExecute("hello.wri")
	the .HLP file ended up containing:
		SE(`hello.wri'`'5)	(HCW translates it to SE)

	No compilation errors, but when you click on it, you get something
	like "missing ')' (1031)". I wasted several days on that before BaDge
	looked in the .HLP file and found it. HCW had inserted '`' and
	effectively trashed the .HLP file. I'm not sure if that's what bug
	#19 is referring to or not.

	If you're really a mechanic, you can fix the .HLP by using a hex
	editor on it, *if* you're really careful and know what you're doing.
	Not recommended.

	My solution? I discarded ShellExecute() & ended up using ExecFile()
	instead. Presumably it calls the ShellExecute API function which
	is what the ShellExecute() macro would do anyway.

	Once again: it won't work unless ShellExecuteHooks is in
	HKEY_LOCAL_MACHINE

	I shold note here that this is version 4.00.0950 of HCW that came
	with the Watcom compiler. What is the current version? Is there
	a way to obtain a newer version? From Watcom or Microsoft?
	
Summary:
-------
1. check your registry and make sure ShellExecuteHooks() is in
   HKEY_LOCAL_MACHINE. If not, copy it and insert it there.

2. c:\> start http://... should work ok

3. your Win16 or Win32 .exe apps can now ShellExecute() a URL directly

4. your Win16 .HLP files can also ShellExecute a URL directly (use
   RegisterRoutine in your .hpj)

5. your Win32 .HLP files can also 'shellexecute' a URL, but HCW is broken
   and generates bogus code for the ShellExecute() macro, so use the
   ExecFile() macro instead.

Thanks to Ray Chen and BaDge for their help.

Of course, I could be entirely wrong. If so, please set me straight.
-- 
John A. Grant       * I speak only for myself *            [email-masked]
Airborne Geophysics, Geological Survey of Canada, Ottawa
If you followup, please do NOT e-mail me a copy: I will read it here.