Ejemplo n.º 1
0
wxString wxFileTypeImpl::GetCommand(const wxString& verb) const
{
    // suppress possible error messages
    wxLogNull nolog;
    wxString strKey;

    {
        wxRegKey explorerKey(wxRegKey::HKCU, wxT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\") + m_ext);
        if (explorerKey.Exists())
        {
            if (explorerKey.Open(wxRegKey::Read))
            {
                if (explorerKey.QueryValue(wxT("Progid"), strKey))
                {
                    strKey = wxFileTypeImplGetCurVer(strKey);
                }
            }
        }
    }

    if (!strKey && wxRegKey(wxRegKey::HKCR, m_ext + wxT("\\shell")).Exists())
        strKey = m_ext;

    if ( !strKey && !m_strFileType.empty())
    {
        wxString fileType = wxFileTypeImplGetCurVer(m_strFileType);
        if (wxRegKey(wxRegKey::HKCR, fileType + wxT("\\shell")).Exists())
            strKey = fileType;
    }

    if ( !strKey )
    {
        // no info
        return wxEmptyString;
    }

    strKey << wxT("\\shell\\") << verb;
    wxRegKey key(wxRegKey::HKCR, strKey + wxT("\\command"));
    wxString command;
    if ( key.Open(wxRegKey::Read) ) {
        // it's the default value of the key
        if ( key.QueryValue(wxEmptyString, command) ) {
            bool foundFilename = CanonicalizeParams(command);

#if wxUSE_IPC
            // look whether we must issue some DDE requests to the application
            // (and not just launch it)
            strKey += wxT("\\DDEExec");
            wxRegKey keyDDE(wxRegKey::HKCR, strKey);
            if ( keyDDE.Open(wxRegKey::Read) ) {
                wxString ddeCommand, ddeServer, ddeTopic;
                keyDDE.QueryValue(wxEmptyString, ddeCommand);
                ddeCommand.Replace(wxT("%1"), wxT("%s"));

                wxRegKey keyServer(wxRegKey::HKCR, strKey + wxT("\\Application"));
                keyServer.QueryValue(wxEmptyString, ddeServer);
                wxRegKey keyTopic(wxRegKey::HKCR, strKey + wxT("\\Topic"));
                keyTopic.QueryValue(wxEmptyString, ddeTopic);

                if (ddeTopic.empty())
                    ddeTopic = wxT("System");

                // HACK: we use a special feature of wxExecute which exists
                //       just because we need it here: it will establish DDE
                //       conversation with the program it just launched
                command.Prepend(wxT("WX_DDE#"));
                command << wxT('#') << ddeServer
                        << wxT('#') << ddeTopic
                        << wxT('#') << ddeCommand;
            }
            else
#endif // wxUSE_IPC
            if ( !foundFilename )
            {
                // we didn't find any '%1' - the application doesn't know which
                // file to open (note that we only do it if there is no DDEExec
                // subkey)
                //
                // HACK: append the filename at the end, hope that it will do
                command << wxT(" %s");
            }
        }
    }
    //else: no such file type or no value, will return empty string

    return command;
}
Ejemplo n.º 2
0
wxString wxFileTypeImpl::GetCommand(const wxString& verb) const
{
    // suppress possible error messages
    wxLogNull nolog;
    wxString strKey;

    // Since Windows Vista the association used by Explorer is different from
    // the association information stored in the traditional part of the
    // registry. Unfortunately the new schema doesn't seem to be documented
    // anywhere so using it involves a bit of guesswork:
    //
    // The information is stored under Explorer-specific key whose path is
    // below. The interesting part is UserChoice subkey which is the only one
    // we use so far but there is also OpenWithProgids subkey which can exist
    // even if UserChoice doesn't. However in practice there doesn't seem to be
    // any cases when OpenWithProgids values for the given extension are
    // different from those found directly under HKCR\.ext, so for now we don't
    // bother to use this, apparently the programs registering their file type
    // associations do it in both places. We do use UserChoice because when the
    // association is manually changed by the user it's only recorded there and
    // so must override whatever value was created under HKCR by the setup
    // program.

    {
        wxRegKey explorerKey
                 (
                    wxRegKey::HKCU,
                    wxT("Software\\Microsoft\\Windows\\CurrentVersion\\")
                    wxT("Explorer\\FileExts\\") +
                    m_ext +
                    wxT("\\UserChoice")
                 );
        if ( explorerKey.Open(wxRegKey::Read) &&
                explorerKey.QueryValue(wxT("Progid"), strKey) )
        {
            strKey = wxFileTypeImplGetCurVer(strKey);
        }
    }

    if (!strKey && wxRegKey(wxRegKey::HKCR, m_ext + wxT("\\shell")).Exists())
        strKey = m_ext;

    if ( !strKey && !m_strFileType.empty())
    {
        wxString fileType = wxFileTypeImplGetCurVer(m_strFileType);
        if (wxRegKey(wxRegKey::HKCR, fileType + wxT("\\shell")).Exists())
            strKey = fileType;
    }

    if ( !strKey )
    {
        // no info
        return wxEmptyString;
    }

    strKey << wxT("\\shell\\") << verb;
    wxRegKey key(wxRegKey::HKCR, strKey + wxT("\\command"));
    wxString command;
    if ( key.Open(wxRegKey::Read) ) {
        // it's the default value of the key
        if ( key.QueryValue(wxEmptyString, command) ) {
            bool foundFilename = CanonicalizeParams(command);

#if wxUSE_IPC
            // look whether we must issue some DDE requests to the application
            // (and not just launch it)
            strKey += wxT("\\DDEExec");
            wxRegKey keyDDE(wxRegKey::HKCR, strKey);
            if ( keyDDE.Open(wxRegKey::Read) ) {
                wxString ddeCommand, ddeServer, ddeTopic;
                keyDDE.QueryValue(wxEmptyString, ddeCommand);

                // in some cases "DDEExec" subkey exists but has no value, we
                // shouldn't use DDE in this case
                if ( !ddeCommand.empty() ) {
                    ddeCommand.Replace(wxT("%1"), wxT("%s"));

                    wxRegKey keyServer(wxRegKey::HKCR, strKey + wxT("\\Application"));
                    keyServer.QueryValue(wxEmptyString, ddeServer);
                    wxRegKey keyTopic(wxRegKey::HKCR, strKey + wxT("\\Topic"));
                    keyTopic.QueryValue(wxEmptyString, ddeTopic);

                    if (ddeTopic.empty())
                        ddeTopic = wxT("System");

                    // HACK: we use a special feature of wxExecute which exists
                    //       just because we need it here: it will establish DDE
                    //       conversation with the program it just launched
                    command.Prepend(wxT("WX_DDE#"));
                    command << wxT('#') << ddeServer
                            << wxT('#') << ddeTopic
                            << wxT('#') << ddeCommand;
                }
            }
            else
#endif // wxUSE_IPC
            if ( !foundFilename )
            {
                // we didn't find any '%1' - the application doesn't know which
                // file to open (note that we only do it if there is no DDEExec
                // subkey)
                //
                // HACK: append the filename at the end, hope that it will do
                command << wxT(" %s");
            }
        }
    }
    //else: no such file type or no value, will return empty string

    return command;
}
Ejemplo n.º 3
0
static bool wxLaunchDefaultBrowserBaseImpl(const wxString& url, int flags)
{
    wxUnusedVar(flags);

#if defined(__WXMSW__)

#if wxUSE_IPC
    if ( flags & wxBROWSER_NEW_WINDOW )
    {
        // ShellExecuteEx() opens the URL in an existing window by default so
        // we can't use it if we need a new window
        wxURI uri(url);
        wxRegKey key(wxRegKey::HKCR, uri.GetScheme() + _T("\\shell\\open"));
        if ( !key.Exists() )
        {
            // try default browser, it must be registered at least for http URLs
            key.SetName(wxRegKey::HKCR, _T("http\\shell\\open"));
        }

        if ( key.Exists() )
        {
            wxRegKey keyDDE(key, wxT("DDEExec"));
            if ( keyDDE.Exists() )
            {
                // we only know the syntax of WWW_OpenURL DDE request for IE,
                // optimistically assume that all other browsers are compatible
                // with it
                static const wxString TOPIC_OPEN_URL = wxT("WWW_OpenURL");
                wxString ddeCmd;
                wxRegKey keyTopic(keyDDE, wxT("topic"));
                bool ok = keyTopic.Exists() && (keyTopic.QueryDefaultValue() = TOPIC_OPEN_URL);
                if ( ok )
                {
                    ddeCmd = keyDDE.QueryDefaultValue();
                    ok = !ddeCmd.empty();
                }

                if ( ok )
                {
                    // for WWW_OpenURL, the index of the window to open the URL
                    // in is -1 (meaning "current") by default, replace it with
                    // 0 which means "new" (see KB article 160957)
                    ok = ddeCmd.Replace(wxT("-1"), wxT("0"),
                                        false /* only first occurence */) == 1;
                }

                if ( ok )
                {
                    // and also replace the parameters: the topic should
                    // contain a placeholder for the URL
                    ok = ddeCmd.Replace(wxT("%1"), url, false) == 1;
                }

                if ( ok )
                {
                    // try to send it the DDE request now but ignore the errors
                    wxLogNull noLog;

                    const wxString ddeServer = wxRegKey(keyDDE, wxT("application")).QueryDefaultValue();
                    if ( wxExecuteDDE(ddeServer, TOPIC_OPEN_URL, ddeCmd) )
                        return true;

                    // this is not necessarily an error: maybe browser is
                    // simply not running, but no matter, in any case we're
                    // going to launch it using ShellExecuteEx() below now and
                    // we shouldn't try to open a new window if we open a new
                    // browser anyhow
                }
            }
        }
    }
#endif // wxUSE_IPC

    WinStruct<SHELLEXECUTEINFO> sei;
    sei.lpFile = url.c_str();
    sei.lpVerb = _T("open");
    sei.nShow = SW_SHOWNORMAL;
    sei.fMask = SEE_MASK_FLAG_NO_UI; // we give error message ourselves

    BOOL nExecResult = ::ShellExecuteEx(&sei);

    //From MSDN for wince
    //hInstApp member is only valid if the function fails, in which case it
    //receives one of the following error values, which are less than or
    //equal to 32.
    const int nResult = (int) sei.hInstApp;

    // Firefox returns file not found for some reason, so make an exception
    // for it
    if ( nResult > 32 || nResult == SE_ERR_FNF  || nExecResult == TRUE )
    {
#ifdef __WXDEBUG__
        // Log something if SE_ERR_FNF happens
        if ( nResult == SE_ERR_FNF || nExecResult == FALSE )
            wxLogDebug(wxT("SE_ERR_FNF from ShellExecute -- maybe FireFox?"));
#endif // __WXDEBUG__
        return true;
    }
#elif defined(__WXMAC__)
    OSStatus err;
    ICInstance inst;
    long int startSel;
    long int endSel;

    err = ICStart(&inst, 'STKA'); // put your app creator code here
    if (err == noErr)
    {
#if !TARGET_CARBON
        err = ICFindConfigFile(inst, 0, NULL);
#endif
        if (err == noErr)
        {
            ConstStr255Param hint = 0;
            startSel = 0;
            endSel = url.length();
            err = ICLaunchURL(inst, hint, url.fn_str(), endSel, &startSel, &endSel);
            if (err != noErr)
                wxLogDebug(wxT("ICLaunchURL error %d"), (int) err);
        }
        ICStop(inst);
        return true;
    }
    else
    {
        wxLogDebug(wxT("ICStart error %d"), (int) err);
        return false;
    }
#else
    // (non-Mac, non-MSW)

#ifdef __UNIX__

    // Our best best is to use xdg-open from freedesktop.org cross-desktop
    // compatibility suite xdg-utils
    // (see http://portland.freedesktop.org/wiki/) -- this is installed on
    // most modern distributions and may be tweaked by them to handle
    // distribution specifics. Only if that fails, try to find the right
    // browser ourselves.
    wxString path, xdg_open;
    if ( wxGetEnv(_T("PATH"), &path) &&
         wxFindFileInPath(&xdg_open, path, _T("xdg-open")) )
    {
        if ( wxExecute(xdg_open + _T(" ") + url) )
            return true;
    }

    wxString desktop = wxTheApp->GetTraits()->GetDesktopEnvironment();

    // GNOME and KDE desktops have some applications which should be always installed
    // together with their main parts, which give us the
    if (desktop == wxT("GNOME"))
    {
        wxArrayString errors;
        wxArrayString output;

        // gconf will tell us the path of the application to use as browser
        long res = wxExecute( wxT("gconftool-2 --get /desktop/gnome/applications/browser/exec"),
                              output, errors, wxEXEC_NODISABLE );
        if (res >= 0 && errors.GetCount() == 0)
        {
            wxString cmd = output[0];
            cmd << _T(' ') << url;
            if (wxExecute(cmd))
                return true;
        }
    }
    else if (desktop == wxT("KDE"))
    {
        // kfmclient directly opens the given URL
        if (wxExecute(wxT("kfmclient openURL ") + url))
            return true;
    }
#endif

    bool ok = false;
    wxString cmd;

#if wxUSE_MIMETYPE
    wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(_T("html"));
    if ( ft )
    {
        wxString mt;
        ft->GetMimeType(&mt);

        ok = ft->GetOpenCommand(&cmd, wxFileType::MessageParameters(url));
        delete ft;
    }
#endif // wxUSE_MIMETYPE

    if ( !ok || cmd.empty() )
    {
        // fallback to checking for the BROWSER environment variable
        cmd = wxGetenv(wxT("BROWSER"));
        if ( !cmd.empty() )
            cmd << _T(' ') << url;
    }

    ok = ( !cmd.empty() && wxExecute(cmd) );
    if (ok)
        return ok;

    // no file type for HTML extension
    wxLogError(_T("No default application configured for HTML files."));

#endif // !wxUSE_MIMETYPE && !__WXMSW__
    return false;
}
Ejemplo n.º 4
0
bool wxDoLaunchDefaultBrowser(const wxString& url, const wxString& scheme, int flags)
{
    wxUnusedVar(flags);

#if wxUSE_IPC
    if ( flags & wxBROWSER_NEW_WINDOW )
    {
        // ShellExecuteEx() opens the URL in an existing window by default so
        // we can't use it if we need a new window
        wxRegKey key(wxRegKey::HKCR, scheme + wxT("\\shell\\open"));
        if ( !key.Exists() )
        {
            // try the default browser, it must be registered at least for http URLs
            key.SetName(wxRegKey::HKCR, wxT("http\\shell\\open"));
        }

        if ( key.Exists() )
        {
            wxRegKey keyDDE(key, wxT("DDEExec"));
            if ( keyDDE.Exists() )
            {
                // we only know the syntax of WWW_OpenURL DDE request for IE,
                // optimistically assume that all other browsers are compatible
                // with it
                static const wxChar *TOPIC_OPEN_URL = wxT("WWW_OpenURL");
                wxString ddeCmd;
                wxRegKey keyTopic(keyDDE, wxT("topic"));
                bool ok = keyTopic.Exists() &&
                            keyTopic.QueryDefaultValue() == TOPIC_OPEN_URL;
                if ( ok )
                {
                    ddeCmd = keyDDE.QueryDefaultValue();
                    ok = !ddeCmd.empty();
                }

                if ( ok )
                {
                    // for WWW_OpenURL, the index of the window to open the URL
                    // in is -1 (meaning "current") by default, replace it with
                    // 0 which means "new" (see KB article 160957)
                    ok = ddeCmd.Replace(wxT("-1"), wxT("0"),
                                        false /* only first occurrence */) == 1;
                }

                if ( ok )
                {
                    // and also replace the parameters: the topic should
                    // contain a placeholder for the URL
                    ok = ddeCmd.Replace(wxT("%1"), url, false) == 1;
                }

                if ( ok )
                {
                    // try to send it the DDE request now but ignore the errors
                    wxLogNull noLog;

                    const wxString ddeServer = wxRegKey(keyDDE, wxT("application"));
                    if ( wxExecuteDDE(ddeServer, TOPIC_OPEN_URL, ddeCmd) )
                        return true;

                    // this is not necessarily an error: maybe browser is
                    // simply not running, but no matter, in any case we're
                    // going to launch it using ShellExecuteEx() below now and
                    // we shouldn't try to open a new window if we open a new
                    // browser anyhow
                }
            }
        }
    }
#endif // wxUSE_IPC

    WinStruct<SHELLEXECUTEINFO> sei;
    sei.lpFile = url.c_str();
    sei.lpVerb = wxT("open");
    sei.nShow = SW_SHOWNORMAL;
    sei.fMask = SEE_MASK_FLAG_NO_UI; // we give error message ourselves

    if ( ::ShellExecuteEx(&sei) )
        return true;

    return false;
}