@@ -31,6 +31,8 @@ public unsafe class JumpListManager : IDisposable
3131 private FileSystemWatcher ? _filesADLStoreFileWatcher ;
3232 private FileSystemWatcher ? _filesCDLStoreFileWatcher ;
3333
34+ private readonly Lock _updateJumpListLock = new ( ) ;
35+
3436 public static event EventHandler ? ExplorerJumpListChanged ;
3537 public static event EventHandler ? FilesJumpListChanged ;
3638
@@ -53,7 +55,9 @@ public HRESULT PullJumpListFromExplorer(int maxCount = 200)
5355 {
5456 try
5557 {
56- // This method changes the jump list of Files, so we disable the watcher temporarily
58+ // Disable all watchers that could be triggered by this operation
59+ if ( _explorerADLStoreFileWatcher is not null && _explorerADLStoreFileWatcher . EnableRaisingEvents )
60+ _explorerADLStoreFileWatcher . EnableRaisingEvents = false ;
5761 if ( _filesADLStoreFileWatcher is not null && _filesADLStoreFileWatcher . EnableRaisingEvents )
5862 _filesADLStoreFileWatcher . EnableRaisingEvents = false ;
5963 if ( _filesCDLStoreFileWatcher is not null && _filesCDLStoreFileWatcher . EnableRaisingEvents )
@@ -178,6 +182,9 @@ public HRESULT PullJumpListFromExplorer(int maxCount = 200)
178182 }
179183 finally
180184 {
185+ // Re-enable all watchers
186+ if ( _explorerADLStoreFileWatcher is not null && ! _explorerADLStoreFileWatcher . EnableRaisingEvents )
187+ _explorerADLStoreFileWatcher . EnableRaisingEvents = true ;
181188 if ( _filesADLStoreFileWatcher is not null && ! _filesADLStoreFileWatcher . EnableRaisingEvents )
182189 _filesADLStoreFileWatcher . EnableRaisingEvents = true ;
183190 if ( _filesCDLStoreFileWatcher is not null && ! _filesCDLStoreFileWatcher . EnableRaisingEvents )
@@ -189,8 +196,13 @@ public HRESULT PushJumpListToExplorer(int maxCount = 200)
189196 {
190197 try
191198 {
199+ // Disable all watchers that could be triggered by this operation
192200 if ( _explorerADLStoreFileWatcher is not null && _explorerADLStoreFileWatcher . EnableRaisingEvents )
193201 _explorerADLStoreFileWatcher . EnableRaisingEvents = false ;
202+ if ( _filesADLStoreFileWatcher is not null && _filesADLStoreFileWatcher . EnableRaisingEvents )
203+ _filesADLStoreFileWatcher . EnableRaisingEvents = false ;
204+ if ( _filesCDLStoreFileWatcher is not null && _filesCDLStoreFileWatcher . EnableRaisingEvents )
205+ _filesCDLStoreFileWatcher . EnableRaisingEvents = false ;
194206
195207 HRESULT hr ;
196208
@@ -253,7 +265,7 @@ category.Type is not APPDESTCATEGORYTYPE.CUSTOM ||
253265 if ( FAILED ( hr ) ) return hr ;
254266
255267 // Get the count of items in the "Recent" category
256- uint countOfItems = 0U ;
268+ uint countOfItems = 0U ;
257269 hr = poc . Get ( ) ->GetCount ( & countOfItems ) ;
258270 if ( FAILED ( hr ) ) return hr ;
259271
@@ -333,8 +345,13 @@ category.Type is not APPDESTCATEGORYTYPE.CUSTOM ||
333345 }
334346 finally
335347 {
348+ // Re-enable all watchers
336349 if ( _explorerADLStoreFileWatcher is not null && ! _explorerADLStoreFileWatcher . EnableRaisingEvents )
337350 _explorerADLStoreFileWatcher . EnableRaisingEvents = true ;
351+ if ( _filesADLStoreFileWatcher is not null && ! _filesADLStoreFileWatcher . EnableRaisingEvents )
352+ _filesADLStoreFileWatcher . EnableRaisingEvents = true ;
353+ if ( _filesCDLStoreFileWatcher is not null && ! _filesCDLStoreFileWatcher . EnableRaisingEvents )
354+ _filesCDLStoreFileWatcher . EnableRaisingEvents = true ;
338355 }
339356 }
340357
@@ -399,7 +416,27 @@ public bool WatchJumpListChanges(string aumidCrcHash)
399416 }
400417 catch
401418 {
402- // Gracefully exit if we can't monitor the file
419+ if ( _explorerADLStoreFileWatcher is not null )
420+ {
421+ _explorerADLStoreFileWatcher . EnableRaisingEvents = false ;
422+ _explorerADLStoreFileWatcher . Changed -= ExplorerJumpListWatcher_Changed ;
423+ _explorerADLStoreFileWatcher . Dispose ( ) ;
424+ }
425+
426+ if ( _filesADLStoreFileWatcher is not null )
427+ {
428+ _filesADLStoreFileWatcher . EnableRaisingEvents = false ;
429+ _filesADLStoreFileWatcher . Changed -= FilesJumpListWatcher_Changed ;
430+ _filesADLStoreFileWatcher . Dispose ( ) ;
431+ }
432+
433+ if ( _filesCDLStoreFileWatcher is not null )
434+ {
435+ _filesCDLStoreFileWatcher . EnableRaisingEvents = false ;
436+ _filesCDLStoreFileWatcher . Changed -= FilesJumpListWatcher_Changed ;
437+ _filesCDLStoreFileWatcher . Dispose ( ) ;
438+ }
439+
403440 return false ;
404441 }
405442
@@ -462,7 +499,7 @@ private HRESULT CreateLinkFromItem(IShellItem* psi, IShellLinkW** ppsl)
462499 if ( FAILED ( hr ) ) return hr ;
463500
464501 hr = pps . Get ( ) ->Commit ( ) ;
465- if ( FAILED ( hr ) ) return hr ;
502+ if ( FAILED ( hr ) ) return hr ;
466503
467504 hr = PInvoke . PropVariantClear ( & PVAR_Title ) ;
468505 if ( FAILED ( hr ) ) return hr ;
@@ -490,31 +527,66 @@ private HRESULT GetFolderIconLocation(IShellItem* psi, PWSTR* pIconFilePath, uin
490527
491528 private void ExplorerJumpListWatcher_Changed ( object sender , FileSystemEventArgs e )
492529 {
493- PullJumpListFromExplorer ( ) ;
530+ _ = STATask . Run ( ( ) =>
531+ {
532+ if ( _updateJumpListLock . TryEnter ( ) )
533+ {
534+ try
535+ {
536+ Debug . WriteLine ( "in: ExplorerJumpListWatcher_Changed" ) ;
537+ PullJumpListFromExplorer ( ) ;
538+ Debug . WriteLine ( "out: ExplorerJumpListWatcher_Changed" ) ;
539+ }
540+ finally
541+ {
542+ _updateJumpListLock . Exit ( ) ;
543+ }
544+ }
545+ } ,
546+ null ) ;
494547 }
495548
496549 private void FilesJumpListWatcher_Changed ( object sender , FileSystemEventArgs e )
497550 {
498- PushJumpListToExplorer ( ) ;
551+ _ = STATask . Run ( ( ) =>
552+ {
553+ if ( _updateJumpListLock . TryEnter ( ) )
554+ {
555+ try
556+ {
557+ Debug . WriteLine ( "in: FilesJumpListWatcher_Changed" ) ;
558+ PushJumpListToExplorer ( ) ;
559+ Debug . WriteLine ( "out: FilesJumpListWatcher_Changed" ) ;
560+ }
561+ finally
562+ {
563+ _updateJumpListLock . Exit ( ) ;
564+ }
565+ }
566+ } ,
567+ null ) ;
499568 }
500569
501570 public void Dispose ( )
502571 {
503572 if ( _explorerADLStoreFileWatcher is not null )
504573 {
505574 _explorerADLStoreFileWatcher . EnableRaisingEvents = false ;
575+ _explorerADLStoreFileWatcher . Changed -= ExplorerJumpListWatcher_Changed ;
506576 _explorerADLStoreFileWatcher . Dispose ( ) ;
507577 }
508578
509579 if ( _filesADLStoreFileWatcher is not null )
510580 {
511581 _filesADLStoreFileWatcher . EnableRaisingEvents = false ;
582+ _filesADLStoreFileWatcher . Changed -= FilesJumpListWatcher_Changed ;
512583 _filesADLStoreFileWatcher . Dispose ( ) ;
513584 }
514585
515586 if ( _filesCDLStoreFileWatcher is not null )
516587 {
517588 _filesCDLStoreFileWatcher . EnableRaisingEvents = false ;
589+ _filesCDLStoreFileWatcher . Changed -= FilesJumpListWatcher_Changed ;
518590 _filesCDLStoreFileWatcher . Dispose ( ) ;
519591 }
520592 }
0 commit comments