From 5edaa5ebb0b01f063a9df87236e8365d7c3886f4 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 2 Dec 2012 23:50:33 +0000 Subject: [PATCH] Correct lookup of Explorer-specific file association information. The code added in r52154 never worked because it was looking for the Progid value in a wrong place, look for it under UserChoice subkey where it really is. Also add a way to look up the command to open files with the given extension to the exec sample. Closes #12302. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73106 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- samples/exec/exec.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/msw/mimetype.cpp | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/samples/exec/exec.cpp b/samples/exec/exec.cpp index 4cb5b21803..d72c89a7ad 100644 --- a/samples/exec/exec.cpp +++ b/samples/exec/exec.cpp @@ -55,6 +55,7 @@ #include "wx/numdlg.h" #include "wx/textdlg.h" #include "wx/ffile.h" +#include "wx/scopedptr.h" #include "wx/stopwatch.h" #include "wx/process.h" @@ -122,6 +123,7 @@ public: void OnFileExec(wxCommandEvent& event); void OnFileLaunch(wxCommandEvent& event); void OnOpenURL(wxCommandEvent& event); + void OnShowCommandForExt(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); @@ -321,6 +323,7 @@ enum Exec_Shell, Exec_POpen, Exec_OpenFile, + Exec_ShowCommandForExt, Exec_LaunchFile, Exec_OpenURL, Exec_DDEExec, @@ -365,6 +368,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(Exec_POpen, MyFrame::OnPOpen) EVT_MENU(Exec_OpenFile, MyFrame::OnFileExec) + EVT_MENU(Exec_ShowCommandForExt, MyFrame::OnShowCommandForExt) EVT_MENU(Exec_LaunchFile, MyFrame::OnFileLaunch) EVT_MENU(Exec_OpenURL, MyFrame::OnOpenURL) @@ -459,6 +463,9 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) menuFile->AppendSeparator(); menuFile->Append(Exec_OpenFile, wxT("Open &file...\tCtrl-F"), wxT("Launch the command to open this kind of files")); + menuFile->Append(Exec_ShowCommandForExt, + "Show association for extension...\tShift-Ctrl-A", + "Show the command associated with the given extension"); menuFile->Append(Exec_LaunchFile, wxT("La&unch file...\tShift-Ctrl-F"), wxT("Launch the default application associated with the file")); menuFile->Append(Exec_OpenURL, wxT("Open &URL...\tCtrl-U"), @@ -1098,6 +1105,41 @@ void MyFrame::OnFileExec(wxCommandEvent& WXUNUSED(event)) DoAsyncExec(cmd); } +void MyFrame::OnShowCommandForExt(wxCommandEvent& WXUNUSED(event)) +{ + static wxString s_ext; + + wxString ext = wxGetTextFromUser + ( + "Enter the extension without leading dot", + "Exec sample", + s_ext, + this + ); + if ( ext.empty() ) + return; + + s_ext = ext; + + wxScopedPtr + ft(wxTheMimeTypesManager->GetFileTypeFromExtension(ext)); + if ( !ft ) + { + wxLogError("Information for extension \"%s\" not found", ext); + return; + } + + const wxString cmd = ft->GetOpenCommand("file." + ext); + if ( cmd.empty() ) + { + wxLogWarning("Open command for extension \"%s\" not defined.", ext); + return; + } + + wxLogMessage("Open command for files of extension \"%s\" is\n%s", + ext, cmd); +} + void MyFrame::OnFileLaunch(wxCommandEvent& WXUNUSED(event)) { if ( !AskUserForFileName() ) diff --git a/src/msw/mimetype.cpp b/src/msw/mimetype.cpp index 10ee1d0954..70312302ab 100644 --- a/src/msw/mimetype.cpp +++ b/src/msw/mimetype.cpp @@ -227,17 +227,36 @@ wxString wxFileTypeImpl::GetCommand(const wxString& verb) const 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\\Explorer\\FileExts\\") + m_ext); - if (explorerKey.Exists()) + 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) ) { - if (explorerKey.Open(wxRegKey::Read)) - { - if (explorerKey.QueryValue(wxT("Progid"), strKey)) - { - strKey = wxFileTypeImplGetCurVer(strKey); - } - } + strKey = wxFileTypeImplGetCurVer(strKey); } } -- 2.45.2