Skip to content

Commit c75522f

Browse files
committed
Merge remote-tracking branch 'upstream/main' into gh-50
2 parents 5596ff6 + 0e16136 commit c75522f

File tree

7 files changed

+487
-59
lines changed

7 files changed

+487
-59
lines changed

_msbuild_test.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,23 @@
5252
CFunction('reg_rename_key'),
5353
source='src/_native',
5454
),
55+
DllPackage('_shellext_test',
56+
PyFile('_native/__init__.py'),
57+
ItemDefinition('ClCompile',
58+
PreprocessorDefinitions=Prepend("PYSHELLEXT_TEST=1;"),
59+
LanguageStandard='stdcpp20',
60+
),
61+
ItemDefinition('Link', AdditionalDependencies=Prepend("RuntimeObject.lib;")),
62+
CSourceFile('pyshellext/shellext.cpp'),
63+
CSourceFile('pyshellext/shellext_test.cpp'),
64+
IncludeFile('pyshellext/shellext.h'),
65+
CSourceFile('_native/helpers.cpp'),
66+
IncludeFile('_native/helpers.h'),
67+
CFunction('shellext_RegReadStr'),
68+
CFunction('shellext_ReadIdleInstalls'),
69+
CFunction('shellext_ReadAllIdleInstalls'),
70+
CFunction('shellext_PassthroughTitle'),
71+
CFunction('shellext_IdleCommand'),
72+
source='src',
73+
)
5574
)

src/pyshellext/shellext.cpp

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,7 @@
66

77
using namespace Microsoft::WRL;
88

9-
#include <windows.h>
10-
#include <shlobj.h>
11-
#include <shlwapi.h>
12-
#include <olectl.h>
13-
14-
#include <string>
15-
#include <vector>
9+
#include "shellext.h"
1610

1711
static HINSTANCE hModule;
1812

@@ -21,14 +15,7 @@ static HINSTANCE hModule;
2115
#define CLSID_COMMAND_ENUMERATOR "{F82C8CD5-A69C-45CC-ADC6-87FC5F4A7429}"
2216

2317

24-
struct IdleData {
25-
std::wstring title;
26-
std::wstring exe;
27-
std::wstring idle;
28-
};
29-
30-
31-
static LRESULT RegReadStr(HKEY key, LPCWSTR valueName, std::wstring& result)
18+
LRESULT RegReadStr(HKEY key, LPCWSTR valueName, std::wstring& result)
3219
{
3320
DWORD reg_type;
3421
while (true) {
@@ -57,7 +44,7 @@ static LRESULT RegReadStr(HKEY key, LPCWSTR valueName, std::wstring& result)
5744
}
5845

5946

60-
static HRESULT ReadIdleInstalls(std::vector<IdleData> &idles, HKEY hkPython, LPCWSTR company, REGSAM flags)
47+
HRESULT ReadIdleInstalls(std::vector<IdleData> &idles, HKEY hkPython, LPCWSTR company, REGSAM flags)
6148
{
6249
HKEY hkCompany = NULL, hkTag = NULL, hkInstall = NULL;
6350
LSTATUS err = RegOpenKeyExW(
@@ -119,6 +106,8 @@ static HRESULT ReadIdleInstalls(std::vector<IdleData> &idles, HKEY hkPython, LPC
119106
data.idle += L"Lib\\idlelib\\idle.pyw";
120107
}
121108
}
109+
} else {
110+
err = 0;
122111
}
123112
}
124113
if (err) {
@@ -152,11 +141,11 @@ static HRESULT ReadIdleInstalls(std::vector<IdleData> &idles, HKEY hkPython, LPC
152141
return S_OK;
153142
}
154143

155-
static HRESULT ReadAllIdleInstalls(std::vector<IdleData> &idles, HKEY hive, REGSAM flags)
144+
HRESULT ReadAllIdleInstalls(std::vector<IdleData> &idles, HKEY hive, LPCWSTR root, REGSAM flags)
156145
{
157146
HKEY hkPython = NULL;
158147
HRESULT hr = S_OK;
159-
LSTATUS err = RegOpenKeyExW(hive, L"Software\\Python", 0, KEY_READ | flags, &hkPython);
148+
LSTATUS err = RegOpenKeyExW(hive, root ? root : L"", 0, KEY_READ | flags, &hkPython);
160149

161150
for (DWORD i = 0; !err && hr == S_OK && i < 64; ++i) {
162151
wchar_t name[512];
@@ -347,12 +336,12 @@ class DECLSPEC_UUID(CLSID_IDLE_COMMAND) IdleCommand
347336
iconPath += L",-4";
348337
}
349338

350-
hr = ReadAllIdleInstalls(idles, HKEY_LOCAL_MACHINE, KEY_WOW64_32KEY);
339+
hr = ReadAllIdleInstalls(idles, HKEY_LOCAL_MACHINE, L"Software\\Python", KEY_WOW64_32KEY);
351340
if (SUCCEEDED(hr)) {
352-
hr = ReadAllIdleInstalls(idles, HKEY_LOCAL_MACHINE, KEY_WOW64_64KEY);
341+
hr = ReadAllIdleInstalls(idles, HKEY_LOCAL_MACHINE, L"Software\\Python", KEY_WOW64_64KEY);
353342
}
354343
if (SUCCEEDED(hr)) {
355-
hr = ReadAllIdleInstalls(idles, HKEY_CURRENT_USER, 0);
344+
hr = ReadAllIdleInstalls(idles, HKEY_CURRENT_USER, L"Software\\Python", 0);
356345
}
357346

358347
if (FAILED(hr)) {
@@ -363,6 +352,29 @@ class DECLSPEC_UUID(CLSID_IDLE_COMMAND) IdleCommand
363352
}
364353
}
365354

355+
#ifdef PYSHELLEXT_TEST
356+
IdleCommand(HKEY hive, LPCWSTR root) : title(L"Edit in &IDLE")
357+
{
358+
HRESULT hr;
359+
360+
DWORD cch = 260;
361+
while (iconPath.size() < cch) {
362+
iconPath.resize(cch);
363+
cch = GetModuleFileNameW(hModule, iconPath.data(), iconPath.size());
364+
}
365+
iconPath.resize(cch);
366+
if (cch) {
367+
iconPath += L",-4";
368+
}
369+
370+
hr = ReadAllIdleInstalls(idles, hive, root, 0);
371+
372+
if (FAILED(hr)) {
373+
idles.clear();
374+
}
375+
}
376+
#endif
377+
366378
// IExplorerCommand
367379
IFACEMETHODIMP GetTitle(IShellItemArray *psiItemArray, LPWSTR *ppszName)
368380
{
@@ -425,6 +437,19 @@ class DECLSPEC_UUID(CLSID_IDLE_COMMAND) IdleCommand
425437

426438
CoCreatableClass(IdleCommand);
427439

440+
#ifdef PYSHELLEXT_TEST
441+
IExplorerCommand *MakeLaunchCommand(std::wstring title, std::wstring exe, std::wstring idle)
442+
{
443+
IdleData data = { .title = title, .exe = exe, .idle = idle };
444+
return Make<LaunchCommand>(data).Detach();
445+
}
446+
447+
448+
IExplorerCommand *MakeIdleCommand(HKEY hive, LPCWSTR root)
449+
{
450+
return Make<IdleCommand>(hive, root).Detach();
451+
}
452+
428453

429454
class OutOfProcModule : public Module<OutOfProc, OutOfProcModule>
430455
{ };
@@ -448,4 +473,4 @@ int WINAPI wWinMain(
448473
CoUninitialize();
449474
return 0;
450475
}
451-
476+
#endif

src/pyshellext/shellext.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include <windows.h>
4+
#include <shlobj.h>
5+
#include <shlwapi.h>
6+
#include <olectl.h>
7+
8+
#include <string>
9+
#include <vector>
10+
11+
LRESULT RegReadStr(HKEY key, LPCWSTR valueName, std::wstring& result);
12+
13+
struct IdleData {
14+
std::wstring title;
15+
std::wstring exe;
16+
std::wstring idle;
17+
};
18+
19+
HRESULT ReadIdleInstalls(std::vector<IdleData> &idles, HKEY hkPython, LPCWSTR company, REGSAM flags);
20+
HRESULT ReadAllIdleInstalls(std::vector<IdleData> &idles, HKEY hive, LPCWSTR root, REGSAM flags);
21+
22+
IExplorerCommand *MakeIdleCommand(HKEY hive, LPCWSTR root);
23+
IExplorerCommand *MakeLaunchCommand(std::wstring title, std::wstring exe, std::wstring idle);

0 commit comments

Comments
 (0)