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