Bug #38374 --> more updates for external helper application support. (NOT PART OF THE BUILD)

code review will come when this is done and gets turned on.

Add external application implementation.
Add windows registry sniffying code to find the right external helper application for a given file extension.
Add windows registry code for launching the application.
This commit is contained in:
mscott%netscape.com 2000-06-17 23:06:23 +00:00
parent 7264918d4e
commit cbf35f6dfc
2 changed files with 146 additions and 6 deletions

View File

@ -21,6 +21,86 @@
*/
#include "nsOSHelperAppService.h"
#include "nsISupports.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#include "nsIURL.h"
#include "nsILocalFile.h"
// we need windows.h to read out registry information...
#include <windows.h>
// this is a platform specific class that abstracts an application.
// we treat this object as a cookie when we pass it to an external app handler..
// the handler will present this cookie back to the helper app service along with a
// an argument (the temp file).
class nsExternalApplication : public nsISupports
{
public:
NS_DECL_ISUPPORTS
nsExternalApplication();
virtual ~nsExternalApplication();
// the app registry name is the key we got from the registry for the
// application. We should be able to just call ::ShellExecute on this name
// in order to launch the application.
void SetAppRegistryName(const char * aAppRegistryName);
// used to launch the application passing in the location of the temp file
// to be associated with this app.
nsresult LaunchApplication(nsIFile * aTempFile);
protected:
nsCString mAppRegistryName;
};
NS_IMPL_THREADSAFE_ADDREF(nsExternalApplication)
NS_IMPL_THREADSAFE_RELEASE(nsExternalApplication)
NS_INTERFACE_MAP_BEGIN(nsExternalApplication)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISupports)
NS_INTERFACE_MAP_END_THREADSAFE
nsExternalApplication::nsExternalApplication()
{
NS_INIT_ISUPPORTS();
}
nsExternalApplication::~nsExternalApplication()
{}
void nsExternalApplication::SetAppRegistryName(const char * aAppRegistryName)
{
mAppRegistryName = aAppRegistryName;
}
nsresult nsExternalApplication::LaunchApplication(nsIFile * aTempFile)
{
nsresult rv = NS_OK;
if (!mAppRegistryName.IsEmpty() && aTempFile)
{
nsXPIDLCString path;
aTempFile->GetPath(getter_Copies(path));
// use the app registry name to launch a shell execute....
LONG r = (LONG) ::ShellExecute( NULL, "open", (const char *) path, NULL, NULL, SW_SHOWNORMAL);
if (r < 32)
{
rv = NS_ERROR_FAILURE;
}
else
rv = NS_OK;
}
return rv;
}
// helper method:
BYTE * GetValueBytes( HKEY hKey, const char *pValueName);
nsOSHelperAppService::nsOSHelperAppService() : nsExternalHelperAppService()
{
@ -50,18 +130,77 @@ NS_IMETHODIMP nsOSHelperAppService::DoContent(const char *aMimeContentType, nsIU
// download...create a nsExternalAppHandler, bind the application token to it (as a nsIFile??) and return this
// as the stream listener to use...
// this code is incomplete and just here to get things started..
nsExternalAppHandler * handler = CreateNewExternalHandler();
handler->QueryInterface(NS_GET_IID(nsIStreamListener), (void **) aStreamListener);
// eventually when we start trying to hook up some UI we may need to insert code here to throw up a dialog
// and ask the user if they wish to use this app to open this content type...
// now bind the handler to the application we want to launch when we the handler is done
// receiving all the data...
handler->Init(nsnull /* this should be a nsIFile that represents the app */);
// ACK!!! we've done all this work to discover the content type just to find out that windows
// registery uses the extension to figure out the right helper app....that's a bummer...
nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
if (url)
{
nsXPIDLCString fileExtension;
url->GetFileExtension(getter_Copies(fileExtension));
nsCAutoString reg = ".";
reg.Append(fileExtension);
nsCAutoString appName;
HKEY hKey;
LONG err = ::RegOpenKeyEx( HKEY_CLASSES_ROOT, reg, 0, KEY_QUERY_VALUE, &hKey);
if (err == ERROR_SUCCESS)
{
LPBYTE pBytes = GetValueBytes( hKey, NULL);
appName = (char *) pBytes;
delete [] pBytes;
// create an application that represents this app name...
nsExternalApplication * application = nsnull;
NS_NEWXPCOM(application, nsExternalApplication);
if (application)
application->SetAppRegistryName(appName);
nsCOMPtr<nsISupports> appSupports = do_QueryInterface(application);
// this code is incomplete and just here to get things started..
nsExternalAppHandler * handler = CreateNewExternalHandler(appSupports);
handler->QueryInterface(NS_GET_IID(nsIStreamListener), (void **) aStreamListener);
} // if we got an entry out of the registry...
} // if url
return NS_OK;
}
NS_IMETHODIMP nsOSHelperAppService::LaunchAppWithTempFile(nsIFile * aTempFile, nsISupports * aAppCookie)
{
if (aAppCookie)
{
nsExternalApplication * application = NS_STATIC_CAST(nsExternalApplication *, aAppCookie);
return application->LaunchApplication(aTempFile);
}
else
return NS_ERROR_FAILURE;
}
BYTE * GetValueBytes( HKEY hKey, const char *pValueName)
{
LONG err;
DWORD bufSz;
LPBYTE pBytes = NULL;
err = ::RegQueryValueEx( hKey, pValueName, NULL, NULL, NULL, &bufSz);
if (err == ERROR_SUCCESS) {
pBytes = new BYTE[bufSz];
err = ::RegQueryValueEx( hKey, pValueName, NULL, NULL, pBytes, &bufSz);
if (err != ERROR_SUCCESS) {
delete [] pBytes;
pBytes = NULL;
}
}
return( pBytes);
}

View File

@ -40,6 +40,7 @@ public:
// override nsIExternalHelperAppService methods....
NS_IMETHOD CanHandleContent(const char *aMimeContentType, nsIURI * aURI, PRBool *_retval);
NS_IMETHOD DoContent(const char *aMimeContentType, nsIURI *aURI, nsISupports *aWindowContext, PRBool *aAbortProcess, nsIStreamListener **_retval);
NS_IMETHOD LaunchAppWithTempFile(nsIFile * aTempFile, nsISupports * aAppCookie);
protected: