88
99using namespace Microsoft ::WRL;
1010
11- #include < windows.h>
12- #include < shlobj.h>
13- #include < shlwapi.h>
14- #include < olectl.h>
15-
16- #include < string>
17- #include < vector>
11+ #include " shellext.h"
1812
1913static HINSTANCE hModule;
2014
@@ -23,14 +17,7 @@ static HINSTANCE hModule;
2317#define CLSID_COMMAND_ENUMERATOR " {F82C8CD5-A69C-45CC-ADC6-87FC5F4A7429}"
2418
2519
26- struct IdleData {
27- std::wstring title;
28- std::wstring exe;
29- std::wstring idle;
30- };
31-
32-
33- static LRESULT RegReadStr (HKEY key, LPCWSTR valueName, std::wstring& result)
20+ LRESULT RegReadStr (HKEY key, LPCWSTR valueName, std::wstring& result)
3421{
3522 DWORD reg_type;
3623 while (true ) {
@@ -59,7 +46,7 @@ static LRESULT RegReadStr(HKEY key, LPCWSTR valueName, std::wstring& result)
5946}
6047
6148
62- static HRESULT ReadIdleInstalls (std::vector<IdleData> &idles, HKEY hkPython, LPCWSTR company, REGSAM flags)
49+ HRESULT ReadIdleInstalls (std::vector<IdleData> &idles, HKEY hkPython, LPCWSTR company, REGSAM flags)
6350{
6451 HKEY hkCompany = NULL , hkTag = NULL , hkInstall = NULL ;
6552 LSTATUS err = RegOpenKeyExW (
@@ -121,6 +108,8 @@ static HRESULT ReadIdleInstalls(std::vector<IdleData> &idles, HKEY hkPython, LPC
121108 data.idle += L" Lib\\ idlelib\\ idle.pyw" ;
122109 }
123110 }
111+ } else {
112+ err = 0 ;
124113 }
125114 }
126115 if (err) {
@@ -154,11 +143,11 @@ static HRESULT ReadIdleInstalls(std::vector<IdleData> &idles, HKEY hkPython, LPC
154143 return S_OK;
155144}
156145
157- static HRESULT ReadAllIdleInstalls (std::vector<IdleData> &idles, HKEY hive, REGSAM flags)
146+ HRESULT ReadAllIdleInstalls (std::vector<IdleData> &idles, HKEY hive, LPCWSTR root , REGSAM flags)
158147{
159148 HKEY hkPython = NULL ;
160149 HRESULT hr = S_OK;
161- LSTATUS err = RegOpenKeyExW (hive, L" Software \\ Python " , 0 , KEY_READ | flags, &hkPython);
150+ LSTATUS err = RegOpenKeyExW (hive, root ? root : L" " , 0 , KEY_READ | flags, &hkPython);
162151
163152 for (DWORD i = 0 ; !err && hr == S_OK && i < 64 ; ++i) {
164153 wchar_t name[512 ];
@@ -349,12 +338,12 @@ class DECLSPEC_UUID(CLSID_IDLE_COMMAND) IdleCommand
349338 iconPath += L" ,-4" ;
350339 }
351340
352- hr = ReadAllIdleInstalls (idles, HKEY_LOCAL_MACHINE, KEY_WOW64_32KEY);
341+ hr = ReadAllIdleInstalls (idles, HKEY_LOCAL_MACHINE, L" Software \\ Python " , KEY_WOW64_32KEY);
353342 if (SUCCEEDED (hr)) {
354- hr = ReadAllIdleInstalls (idles, HKEY_LOCAL_MACHINE, KEY_WOW64_64KEY);
343+ hr = ReadAllIdleInstalls (idles, HKEY_LOCAL_MACHINE, L" Software \\ Python " , KEY_WOW64_64KEY);
355344 }
356345 if (SUCCEEDED (hr)) {
357- hr = ReadAllIdleInstalls (idles, HKEY_CURRENT_USER, 0 );
346+ hr = ReadAllIdleInstalls (idles, HKEY_CURRENT_USER, L" Software \\ Python " , 0 );
358347 }
359348
360349 if (FAILED (hr)) {
@@ -365,6 +354,29 @@ class DECLSPEC_UUID(CLSID_IDLE_COMMAND) IdleCommand
365354 }
366355 }
367356
357+ #ifdef PYSHELLEXT_TEST
358+ IdleCommand (HKEY hive, LPCWSTR root) : title (L" Edit in &IDLE" )
359+ {
360+ HRESULT hr;
361+
362+ DWORD cch = 260 ;
363+ while (iconPath.size () < cch) {
364+ iconPath.resize (cch);
365+ cch = GetModuleFileNameW (hModule, iconPath.data (), iconPath.size ());
366+ }
367+ iconPath.resize (cch);
368+ if (cch) {
369+ iconPath += L" ,-4" ;
370+ }
371+
372+ hr = ReadAllIdleInstalls (idles, hive, root, 0 );
373+
374+ if (FAILED (hr)) {
375+ idles.clear ();
376+ }
377+ }
378+ #endif
379+
368380 // IExplorerCommand
369381 IFACEMETHODIMP GetTitle (IShellItemArray *psiItemArray, LPWSTR *ppszName)
370382 {
@@ -427,6 +439,20 @@ class DECLSPEC_UUID(CLSID_IDLE_COMMAND) IdleCommand
427439
428440CoCreatableClass (IdleCommand);
429441
442+ #ifdef PYSHELLEXT_TEST
443+ IExplorerCommand *MakeLaunchCommand (std::wstring title, std::wstring exe, std::wstring idle)
444+ {
445+ IdleData data = { .title = title, .exe = exe, .idle = idle };
446+ return Make<LaunchCommand>(data).Detach ();
447+ }
448+
449+
450+ IExplorerCommand *MakeIdleCommand (HKEY hive, LPCWSTR root)
451+ {
452+ return Make<IdleCommand>(hive, root).Detach ();
453+ }
454+ #endif
455+
430456
431457STDAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, _COM_Outptr_ void ** ppv)
432458{
@@ -439,7 +465,7 @@ STDAPI DllCanUnloadNow()
439465 return Module<InProc>::GetModule ().Terminate () ? S_OK : S_FALSE;
440466}
441467
442-
468+ # ifndef PYSHELLEXT_TEST
443469STDAPI_ (BOOL) DllMain(_In_opt_ HINSTANCE hinst, DWORD reason, _In_opt_ void *)
444470{
445471 if (reason == DLL_PROCESS_ATTACH) {
@@ -448,3 +474,4 @@ STDAPI_(BOOL) DllMain(_In_opt_ HINSTANCE hinst, DWORD reason, _In_opt_ void*)
448474 }
449475 return TRUE ;
450476}
477+ #endif
0 commit comments