@@ -16,6 +16,7 @@ using namespace NppShell::Helpers;
16
16
using namespace NppShell ::Installer;
17
17
18
18
extern HMODULE thisModule;
19
+ extern thread ensureRegistrationThread;
19
20
20
21
const wstring SparsePackageName = L" NotepadPlusPlus" ;
21
22
constexpr int FirstWindows11BuildNumber = 22000 ;
@@ -255,6 +256,33 @@ void ResetAclPermissionsOnApplicationFolder()
255
256
aclHelper.ResetAcl (applicationPath);
256
257
}
257
258
259
+ Package GetSparsePackage ()
260
+ {
261
+ PackageManager packageManager;
262
+ IIterable<Package> packages;
263
+
264
+ try
265
+ {
266
+ packages = packageManager.FindPackagesForUser (L" " );
267
+ }
268
+ catch (winrt::hresult_error)
269
+ {
270
+ return NULL ;
271
+ }
272
+
273
+ for (const Package& package : packages)
274
+ {
275
+ if (package.Id ().Name () != SparsePackageName)
276
+ {
277
+ continue ;
278
+ }
279
+
280
+ return package;
281
+ }
282
+
283
+ return NULL ;
284
+ }
285
+
258
286
HRESULT NppShell::Installer::RegisterSparsePackage ()
259
287
{
260
288
PackageManager packageManager;
@@ -284,32 +312,20 @@ HRESULT NppShell::Installer::UnregisterSparsePackage()
284
312
PackageManager packageManager;
285
313
IIterable<Package> packages;
286
314
287
- try
288
- {
289
- packages = packageManager.FindPackagesForUser (L" " );
290
- }
291
- catch (winrt::hresult_error const & ex)
315
+ Package package = GetSparsePackage ();
316
+
317
+ if (package == NULL )
292
318
{
293
- return ex. code () ;
319
+ return S_FALSE ;
294
320
}
295
321
296
- for (const Package& package : packages)
297
- {
298
- if (package.Id ().Name () != SparsePackageName)
299
- {
300
- continue ;
301
- }
302
-
303
- winrt::hstring fullName = package.Id ().FullName ();
304
- auto deploymentOperation = packageManager.RemovePackageAsync (fullName, RemovalOptions::None);
305
- auto deployResult = deploymentOperation.get ();
306
-
307
- if (!SUCCEEDED (deployResult.ExtendedErrorCode ()))
308
- {
309
- return deployResult.ExtendedErrorCode ();
310
- }
322
+ winrt::hstring fullName = package.Id ().FullName ();
323
+ auto deploymentOperation = packageManager.RemovePackageAsync (fullName, RemovalOptions::None);
324
+ auto deployResult = deploymentOperation.get ();
311
325
312
- break ;
326
+ if (!SUCCEEDED (deployResult.ExtendedErrorCode ()))
327
+ {
328
+ return deployResult.ExtendedErrorCode ();
313
329
}
314
330
315
331
// After unregistering the sparse package, we reset the folder permissions of the folder where we are installed.
@@ -409,6 +425,41 @@ HRESULT NppShell::Installer::Uninstall()
409
425
return S_OK;
410
426
}
411
427
428
+ void EnsureRegistrationOnCurrentUserWorker ()
429
+ {
430
+ // Initialize the WinRT apartment.
431
+ winrt::init_apartment ();
432
+
433
+ // Get the package to check if it is already installed for the current user.
434
+ Package existingPackage = GetSparsePackage ();
435
+
436
+ if (existingPackage == NULL )
437
+ {
438
+ // The package is not installed for the current user - but we know that Notepad++ is.
439
+ // If it wasn't, this code wouldn't be running, so it is safe to just register the package.
440
+ RegisterSparsePackage ();
441
+
442
+ // Finally we notify the shell that we have made changes, so it reloads the right click menu items.
443
+ SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0 , 0 );
444
+ }
445
+ }
446
+
447
+ void NppShell::Installer::EnsureRegistrationOnCurrentUser ()
448
+ {
449
+ // First we find the name of the process the DLL is being loaded into.
450
+ wstring moduleName = GetExecutingModuleName ();
451
+
452
+ if (moduleName == L" explorer.exe" )
453
+ {
454
+ // We are being loaded into explorer.exe, so we can continue.
455
+ // Explorer.exe only loads the DLL on the first time a user right-clicks a file
456
+ // after that it stays in memory for the rest of their session.
457
+ // Since we are here, we spawn a thread and call the EnsureRegistrationOnCurrentUserWorker function.
458
+ ensureRegistrationThread = thread (EnsureRegistrationOnCurrentUserWorker);
459
+ ensureRegistrationThread.detach ();
460
+ }
461
+ }
462
+
412
463
STDAPI CleanupDll ()
413
464
{
414
465
wstring currentFilePath (MAX_PATH, L' \0 ' );
0 commit comments