@@ -40,10 +40,9 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance,
4040}
4141
4242namespace {
43- // Extracted from
44- // https://source.chromium.org/chromium/chromium/src/+/main:base/command_line.cc;l=109-159
45-
46- std::wstring QuoteForCommandLineArg (const std::wstring& arg) {
43+ // Extracted from
44+ // https://source.chromium.org/chromium/chromium/src/+/main:base/command_line.cc;l=109-159
45+ std::wstring QuoteForCommandLineArg (const std::wstring& arg) {
4746 // We follow the quoting rules of CommandLineToArgvW.
4847 // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
4948 std::wstring quotable_chars (L" \\\" " );
@@ -85,35 +84,83 @@ namespace {
8584 return out;
8685}
8786
87+ static int IsContextMenuEnabled () {
88+ static int enabled = -1 ;
89+ HKEY subhkey;
90+ int err;
91+ #if defined(INSIDER)
92+ const wchar_t kTitleRegkey [] = L" Software\\ Classes\\ VSCodeInsidersContextMenu" ;
93+ #else
94+ const wchar_t kTitleRegkey [] = L" Software\\ Classes\\ VSCodeContextMenu" ;
95+ #endif
96+
97+ if (enabled != -1 )
98+ return enabled;
99+
100+ // Check if the context menu is enabled in the registry.
101+ err = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
102+ kTitleRegkey ,
103+ 0 ,
104+ KEY_QUERY_VALUE | KEY_WOW64_64KEY,
105+ &subhkey);
106+ if (err != ERROR_SUCCESS) {
107+ err = RegOpenKeyExW (HKEY_CURRENT_USER,
108+ kTitleRegkey ,
109+ 0 ,
110+ KEY_QUERY_VALUE | KEY_WOW64_64KEY,
111+ &subhkey);
112+ }
113+
114+ if (err != ERROR_SUCCESS) {
115+ enabled = 0 ;
116+ } else {
117+ enabled = 1 ;
118+ RegCloseKey (subhkey);
119+ }
120+
121+ return enabled;
122+ }
123+
88124}
89125
90126class __declspec (uuid(DLL_UUID)) ExplorerCommandHandler final : public RuntimeClass<RuntimeClassFlags<ClassicCom | InhibitRoOriginateError>, IExplorerCommand> {
91127 public:
92128 // IExplorerCommand implementation:
93129 IFACEMETHODIMP GetTitle (IShellItemArray* items, PWSTR* name) {
94- const size_t kMaxStringLength = 1024 ;
95- wchar_t value_w[kMaxStringLength ];
96- wchar_t expanded_value_w[kMaxStringLength ];
97- DWORD value_size_w = sizeof (value_w);
130+ static std::wstring cached_title;
131+ static bool title_cached = false ;
132+
133+ if (!title_cached) {
134+ const size_t kMaxStringLength = 1024 ;
135+ wchar_t value_w[kMaxStringLength ];
136+ wchar_t expanded_value_w[kMaxStringLength ];
137+ DWORD value_size_w = sizeof (value_w);
98138#if defined(INSIDER)
99- const wchar_t kTitleRegkey [] = L" Software\\ Classes\\ VSCodeInsidersContextMenu" ;
139+ const wchar_t kTitleRegkey [] = L" Software\\ Classes\\ VSCodeInsidersContextMenu" ;
100140#else
101- const wchar_t kTitleRegkey [] = L" Software\\ Classes\\ VSCodeContextMenu" ;
141+ const wchar_t kTitleRegkey [] = L" Software\\ Classes\\ VSCodeContextMenu" ;
102142#endif
103- HKEY subhkey = nullptr ;
104- LONG result = RegOpenKeyEx (HKEY_LOCAL_MACHINE, kTitleRegkey , 0 , KEY_READ, &subhkey);
105- if (result != ERROR_SUCCESS) {
106- result = RegOpenKeyEx (HKEY_CURRENT_USER, kTitleRegkey , 0 , KEY_READ, &subhkey);
107- }
143+ HKEY subhkey = nullptr ;
144+ LONG result = RegOpenKeyEx (HKEY_LOCAL_MACHINE, kTitleRegkey , 0 , KEY_READ, &subhkey);
145+ if (result != ERROR_SUCCESS) {
146+ result = RegOpenKeyEx (HKEY_CURRENT_USER, kTitleRegkey , 0 , KEY_READ, &subhkey);
147+ }
108148
109- DWORD type = REG_EXPAND_SZ;
110- RegQueryValueEx (subhkey, L" Title" , nullptr , &type,
111- reinterpret_cast <LPBYTE>(&value_w), &value_size_w);
112- RegCloseKey (subhkey);
113- value_size_w = ExpandEnvironmentStrings (value_w, expanded_value_w, kMaxStringLength );
114- return (value_size_w && value_size_w < kMaxStringLength )
115- ? SHStrDup (expanded_value_w, name)
116- : SHStrDup (L" UnExpected Title" , name);
149+ DWORD type = REG_EXPAND_SZ;
150+ RegQueryValueEx (subhkey, L" Title" , nullptr , &type,
151+ reinterpret_cast <LPBYTE>(&value_w), &value_size_w);
152+ RegCloseKey (subhkey);
153+ value_size_w = ExpandEnvironmentStrings (value_w, expanded_value_w, kMaxStringLength );
154+
155+ if (value_size_w && value_size_w < kMaxStringLength ) {
156+ cached_title = expanded_value_w;
157+ } else {
158+ cached_title = L" UnExpected Title" ;
159+ }
160+ title_cached = true ;
161+ }
162+
163+ return SHStrDup (cached_title.c_str (), name);
117164 }
118165
119166 IFACEMETHODIMP GetIcon (IShellItemArray* items, PWSTR* icon) {
@@ -134,7 +181,11 @@ class __declspec(uuid(DLL_UUID)) ExplorerCommandHandler final : public RuntimeCl
134181 }
135182
136183 IFACEMETHODIMP GetState (IShellItemArray* items, BOOL okToBeSlow, EXPCMDSTATE* cmdState) {
137- *cmdState = ECS_ENABLED;
184+ #if defined(INSIDER)
185+ *cmdState = IsContextMenuEnabled () ? ECS_ENABLED : ECS_HIDDEN;
186+ #else
187+ *cmdState = ECS_HIDDEN;
188+ #endif
138189 return S_OK;
139190 }
140191
0 commit comments