mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Get rid of the last use of win32com
This commit is contained in:
parent
9844394258
commit
ea74df97ec
@ -2,6 +2,8 @@
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
# License: GPLv3 Copyright: 2010, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import errno
|
||||
import json
|
||||
import numbers
|
||||
@ -53,45 +55,26 @@ if iswindows and not isportable:
|
||||
startup_path = winutil.special_folder_path(winutil.CSIDL_STARTUP)
|
||||
return os.path.join(startup_path, "calibre.lnk")
|
||||
|
||||
class Shortcut(object):
|
||||
|
||||
def __enter__(self):
|
||||
import pythoncom
|
||||
from win32com.shell import shell
|
||||
pythoncom.CoInitialize()
|
||||
self.instance = pythoncom.CoCreateInstance(shell.CLSID_ShellLink, None, pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink)
|
||||
self.persist_file = self.instance.QueryInterface(pythoncom.IID_IPersistFile)
|
||||
return self
|
||||
|
||||
def __exit__(self, *a):
|
||||
import pythoncom
|
||||
del self.instance
|
||||
del self.persist_file
|
||||
pythoncom.CoUninitialize()
|
||||
|
||||
def create_at(self, shortcut_path, target, description, *args):
|
||||
shortcut = self.instance
|
||||
shortcut.SetPath(target)
|
||||
shortcut.SetIconLocation(target, 0)
|
||||
shortcut.SetDescription(description)
|
||||
def create_shortcut(shortcut_path, target, description, *args):
|
||||
quoted_args = None
|
||||
if args:
|
||||
quoted_args = []
|
||||
for arg in args:
|
||||
quoted_args.append('"{}"'.format(arg))
|
||||
shortcut.SetArguments(' '.join(quoted_args))
|
||||
self.persist_file.Save(shortcut_path, 0)
|
||||
quoted_args = ' '.join(quoted_args)
|
||||
plugins['winutil'][0].manage_shortcut(shortcut_path, target, description, quoted_args)
|
||||
|
||||
def exists_at(self, shortcut_path, target):
|
||||
def shortcut_exists_at(shortcut_path, target):
|
||||
if not os.access(shortcut_path, os.R_OK):
|
||||
return False
|
||||
self.persist_file.Load(shortcut_path)
|
||||
name = self.instance.GetPath(8)[0]
|
||||
return os.path.normcase(os.path.abspath(name)) == os.path.normcase(os.path.abspath(get_exe()))
|
||||
name = plugins['winutil'][0].manage_shortcut(shortcut_path, None, None, None)
|
||||
if name is None:
|
||||
return False
|
||||
return os.path.normcase(os.path.abspath(name)) == os.path.normcase(os.path.abspath(target))
|
||||
|
||||
def set_run_at_startup(run_at_startup=True):
|
||||
if run_at_startup:
|
||||
with Shortcut() as shortcut:
|
||||
shortcut.create_at(startup_shortcut_path(), get_exe(), 'calibre - E-book management', '--start-in-tray')
|
||||
create_shortcut(startup_shortcut_path(), get_exe(), 'calibre - E-book management', '--start-in-tray')
|
||||
else:
|
||||
shortcut_path = startup_shortcut_path()
|
||||
if os.path.exists(shortcut_path):
|
||||
@ -99,8 +82,7 @@ if iswindows and not isportable:
|
||||
|
||||
def is_set_to_run_at_startup():
|
||||
try:
|
||||
with Shortcut() as shortcut:
|
||||
return shortcut.exists_at(startup_shortcut_path(), get_exe())
|
||||
return shortcut_exists_at(startup_shortcut_path(), get_exe())
|
||||
except Exception:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
@ -380,6 +380,7 @@ extern PyObject *winutil_file_association(PyObject *self, PyObject *args);
|
||||
extern PyObject *winutil_friendly_name(PyObject *self, PyObject *args);
|
||||
extern PyObject *winutil_notify_associations_changed(PyObject *self, PyObject *args);
|
||||
extern PyObject *winutil_move_to_trash(PyObject *self, PyObject *args);
|
||||
extern PyObject *winutil_manage_shortcut(PyObject *self, PyObject *args);
|
||||
|
||||
static PyMethodDef winutil_methods[] = {
|
||||
{"special_folder_path", winutil_folder_path, METH_VARARGS,
|
||||
@ -467,6 +468,10 @@ be a unicode string. Returns unicode strings."
|
||||
"move_to_trash()\n\nMove the specified path to trash"
|
||||
},
|
||||
|
||||
{"manage_shortcut", (PyCFunction)winutil_manage_shortcut, METH_VARARGS,
|
||||
"manage_shortcut()\n\nManage a shortcut"
|
||||
},
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -79,13 +79,15 @@ class wchar_raii { // {{{
|
||||
wchar_raii() : handle(NULL) {}
|
||||
|
||||
~wchar_raii() {
|
||||
if (handle) {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyMem_Free(*handle);
|
||||
#endif
|
||||
*handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
wchar_t *ptr() { return *handle; }
|
||||
wchar_t *ptr() { return handle ? *handle : NULL; }
|
||||
void set_ptr(wchar_t **val) { handle = val; }
|
||||
}; // }}}
|
||||
|
||||
@ -215,4 +217,68 @@ winutil_move_to_trash(PyObject *self, PyObject *args) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
winutil_manage_shortcut(PyObject *self, PyObject *args) {
|
||||
wchar_raii path, target, description, quoted_args;
|
||||
if (!PyArg_ParseTuple(args, "O&O&O&O&", py_to_wchar, &path, py_to_wchar, &target, py_to_wchar, &description, py_to_wchar, "ed_args)) return NULL;
|
||||
if (!path.ptr()) {
|
||||
PyErr_SetString(PyExc_TypeError, "Path must not be None");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scoped_com_initializer com;
|
||||
if (!com.succeded()) { PyErr_SetString(PyExc_OSError, "Failed to initialize COM"); return NULL; }
|
||||
|
||||
CComPtr<IShellLink> shell_link;
|
||||
if (FAILED(CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shell_link)))) {
|
||||
PyErr_SetString(PyExc_OSError, "Failed to create IShellLink instance");
|
||||
return NULL;
|
||||
}
|
||||
CComPtr<IPersistFile> persist_file;
|
||||
if (FAILED(shell_link->QueryInterface(IID_PPV_ARGS(&persist_file)))) {
|
||||
PyErr_SetString(PyExc_OSError, "Failed to create IPersistFile instance");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!target.ptr()) {
|
||||
wchar_t buf[2048];
|
||||
if (FAILED(persist_file->Load(path.ptr(), 0))) Py_RETURN_NONE;
|
||||
if (FAILED(shell_link->GetPath(buf, sizeof(buf), NULL, 0))) Py_RETURN_NONE;
|
||||
return Py_BuildValue("u", buf);
|
||||
}
|
||||
|
||||
if (FAILED(shell_link->SetPath(target.ptr()))) {
|
||||
PyErr_SetString(PyExc_OSError, "Failed to set shortcut target");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (FAILED(shell_link->SetIconLocation(target.ptr(), 0))) {
|
||||
PyErr_SetString(PyExc_OSError, "Failed to set shortcut icon");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (description.ptr()) {
|
||||
if (FAILED(shell_link->SetDescription(description.ptr()))) {
|
||||
PyErr_SetString(PyExc_OSError, "Failed to set shortcut description");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (quoted_args.ptr()) {
|
||||
if (FAILED(shell_link->SetArguments(quoted_args.ptr()))) {
|
||||
PyErr_SetString(PyExc_OSError, "Failed to set shortcut arguments");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(persist_file->Save(path.ptr(), FALSE))) {
|
||||
PyErr_SetString(PyExc_OSError, "Failed to save the shortcut");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
|
||||
}
|
||||
|
||||
// end extern "C"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user