Dont use win32com to get file associations

This commit is contained in:
Kovid Goyal 2019-06-11 15:57:12 +05:30
parent edd44a559a
commit 57572d977a
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 23 additions and 18 deletions

View File

@ -10,7 +10,7 @@ from functools import partial
from PyQt5.Qt import Qt, QAction, pyqtSignal from PyQt5.Qt import Qt, QAction, pyqtSignal
from calibre.constants import isosx, iswindows from calibre.constants import isosx, iswindows, plugins
from calibre.gui2 import ( from calibre.gui2 import (
error_dialog, Dispatcher, question_dialog, config, open_local_file, error_dialog, Dispatcher, question_dialog, config, open_local_file,
info_dialog, elided_text) info_dialog, elided_text)
@ -18,6 +18,7 @@ from calibre.gui2.dialogs.choose_format import ChooseFormatDialog
from calibre.utils.config import prefs, tweaks from calibre.utils.config import prefs, tweaks
from calibre.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
from calibre.gui2.actions import InterfaceAction from calibre.gui2.actions import InterfaceAction
from polyglot.builtins import unicode_type
class HistoryAction(QAction): class HistoryAction(QAction):
@ -125,11 +126,11 @@ class ViewAction(InterfaceAction):
kwargs=dict(args=args)) kwargs=dict(args=args))
else: else:
if iswindows: if iswindows:
from calibre.utils.file_associations import file_assoc_windows winutil = plugins['winutil'][0]
ext = name.rpartition('.')[-1] ext = name.rpartition('.')[-1]
if ext: if ext:
try: try:
prog = file_assoc_windows(ext) prog = winutil.file_association(unicode_type('.' + ext))
except Exception: except Exception:
prog = None prog = None
if prog and prog.lower().endswith('calibre.exe'): if prog and prog.lower().endswith('calibre.exe'):

View File

@ -1,15 +0,0 @@
#!/usr/bin/env python2
# vim:fileencoding=utf-8
from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
def file_assoc_windows(ft):
# See the IQueryAssociations::GetString method documentation on MSDN
from win32com.shell import shell, shellcon
a = shell.AssocCreate()
a.Init(0, '.' + ft.lower())
return a.GetString(0, shellcon.ASSOCSTR_EXECUTABLE)

View File

@ -23,6 +23,10 @@ class TestWinutil(unittest.TestCase):
self.winutil.add_to_recent_docs(path, None) self.winutil.add_to_recent_docs(path, None)
self.winutil.add_to_recent_docs(path, 'some-app-uid') self.winutil.add_to_recent_docs(path, 'some-app-uid')
def test_file_association(self):
self.assertIn('notepad.exe', self.winutil.file_association('.txt'))
self.assertIsNone(self.winutil.file_association('.mkjsfks'))
def find_tests(): def find_tests():
return unittest.defaultTestLoader.loadTestsFromTestCase(TestWinutil) return unittest.defaultTestLoader.loadTestsFromTestCase(TestWinutil)

View File

@ -376,6 +376,7 @@ winutil_strftime(PyObject *self, PyObject *args)
static char winutil_doc[] = "Defines utility methods to interface with windows."; static char winutil_doc[] = "Defines utility methods to interface with windows.";
extern PyObject *add_to_recent_docs(PyObject *self, PyObject *args); extern PyObject *add_to_recent_docs(PyObject *self, PyObject *args);
extern PyObject *file_association(PyObject *self, PyObject *args);
static PyMethodDef winutil_methods[] = { static PyMethodDef winutil_methods[] = {
{"special_folder_path", winutil_folder_path, METH_VARARGS, {"special_folder_path", winutil_folder_path, METH_VARARGS,
@ -447,6 +448,10 @@ be a unicode string. Returns unicode strings."
"add_to_recent_docs()\n\nAdd a path to the recent documents list" "add_to_recent_docs()\n\nAdd a path to the recent documents list"
}, },
{"file_association", (PyCFunction)file_association, METH_VARARGS,
"file_association()\n\nGet the executable associated with the given file extension"
},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View File

@ -10,6 +10,7 @@
#include <Windows.h> #include <Windows.h>
#include <combaseapi.h> #include <combaseapi.h>
#include <shlobj.h> #include <shlobj.h>
#include <shlwapi.h>
#include <atlbase.h> // for CComPtr #include <atlbase.h> // for CComPtr
#include <Python.h> #include <Python.h>
@ -60,4 +61,13 @@ add_to_recent_docs(PyObject *self, PyObject *args) {
} }
PyObject *
file_association(PyObject *self, PyObject *args) {
wchar_t *ext, buf[2048];
DWORD sz = sizeof(buf);
if (!PyArg_ParseTuple(args, "O&", py_to_wchar, &ext)) return NULL;
HRESULT hr = AssocQueryStringW(0, ASSOCSTR_EXECUTABLE, ext, NULL, buf, &sz);
free_wchar_buffer(&ext);
if (!SUCCEEDED(hr)) Py_RETURN_NONE;
return Py_BuildValue("u#", buf, (int)sz);
} }