diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Storage/Win32ProgramRepositoryTest.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Storage/Win32ProgramRepositoryTest.cs index 74ba4aa874..48e86e9850 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Storage/Win32ProgramRepositoryTest.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Storage/Win32ProgramRepositoryTest.cs @@ -7,7 +7,7 @@ using System.Diagnostics; using System.IO; using System.IO.Abstractions; using System.Linq; - +using System.Threading.Tasks; using Microsoft.Plugin.Program.Storage; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -114,7 +114,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage [DataTestMethod] [DataRow("directory", "oldpath.appref-ms", "newpath.appref-ms")] - public void Win32ProgramRepositoryMustCallOnAppRenamedForApprefAppsWhenRenamedEventIsRaised(string directory, string oldpath, string newpath) + public async Task Win32ProgramRepositoryMustCallOnAppRenamedForApprefAppsWhenRenamedEventIsRaised(string directory, string oldpath, string newpath) { // Arrange Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); @@ -130,6 +130,9 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage // Act _fileSystemMocks[0].Raise(m => m.Renamed += null, e); + // We need to wait more than one second to make sure our test can pass + await Task.Delay(2 * Win32ProgramRepository.OnRenamedEventWaitTime).ConfigureAwait(false); + // Assert Assert.AreEqual(1, win32ProgramRepository.Count()); Assert.IsTrue(win32ProgramRepository.Contains(newitem)); @@ -183,7 +186,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage [DataTestMethod] [DataRow("directory", "oldpath.appref-ms", "newpath.appref-ms")] - public void Win32ProgramRepositoryMustCallOnAppRenamedForExeAppsWhenRenamedEventIsRaised(string directory, string oldpath, string newpath) + public async Task Win32ProgramRepositoryMustCallOnAppRenamedForExeAppsWhenRenamedEventIsRaised(string directory, string oldpath, string newpath) { // Arrange Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); @@ -204,6 +207,9 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage // Act _fileSystemMocks[0].Raise(m => m.Renamed += null, e); + // We need to wait more than one second to make sure our test can pass + await Task.Delay(2 * Win32ProgramRepository.OnRenamedEventWaitTime).ConfigureAwait(false); + // Assert Assert.AreEqual(1, win32ProgramRepository.Count()); Assert.IsTrue(win32ProgramRepository.Contains(newitem)); @@ -287,7 +293,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage [DataTestMethod] [DataRow("directory", "oldpath.url", "newpath.url")] - public void Win32ProgramRepositoryMustCallOnAppRenamedForUrlAppsWhenRenamedEventIsRaised(string directory, string oldpath, string newpath) + public async Task Win32ProgramRepositoryMustCallOnAppRenamedForUrlAppsWhenRenamedEventIsRaised(string directory, string oldpath, string newpath) { // Arrange Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); @@ -308,6 +314,9 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage // Act _fileSystemMocks[0].Raise(m => m.Renamed += null, e); + // We need to wait more than one second to make sure our test can pass + await Task.Delay(2 * Win32ProgramRepository.OnRenamedEventWaitTime).ConfigureAwait(false); + // Assert Assert.AreEqual(1, win32ProgramRepository.Count()); Assert.IsTrue(win32ProgramRepository.Contains(newitem)); @@ -347,7 +356,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage [DataTestMethod] [DataRow("directory", "oldpath.lnk", "path.lnk")] - public void Win32ProgramRepositoryMustCallOnAppRenamedForLnkAppsWhenRenamedEventIsRaised(string directory, string oldpath, string path) + public async Task Win32ProgramRepositoryMustCallOnAppRenamedForLnkAppsWhenRenamedEventIsRaised(string directory, string oldpath, string path) { // Arrange Win32ProgramRepository win32ProgramRepository = new Win32ProgramRepository(_fileSystemWatchers, _settings, _pathsToWatch); @@ -382,6 +391,9 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage // Act _fileSystemMocks[0].Raise(m => m.Renamed += null, e); + // We need to wait more than one second to make sure our test can pass + await Task.Delay(2 * Win32ProgramRepository.OnRenamedEventWaitTime).ConfigureAwait(false); + // Assert Assert.AreEqual(1, win32ProgramRepository.Count()); Assert.IsTrue(win32ProgramRepository.Contains(newitem)); diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/Win32ProgramRepository.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/Win32ProgramRepository.cs index d0cb0a9390..e43f85bcfd 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/Win32ProgramRepository.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/Win32ProgramRepository.cs @@ -33,6 +33,8 @@ namespace Microsoft.Plugin.Program.Storage private static ConcurrentQueue commonEventHandlingQueue = new ConcurrentQueue(); + public static readonly int OnRenamedEventWaitTime = 1000; + public Win32ProgramRepository(IList fileSystemWatcherHelpers, ProgramPluginSettings settings, string[] pathsToWatch) { _fileSystemWatcherHelpers = fileSystemWatcherHelpers; @@ -91,7 +93,7 @@ namespace Microsoft.Plugin.Program.Storage } } - private void OnAppRenamed(object sender, RenamedEventArgs e) + private async Task DoOnAppRenamedAsync(object sender, RenamedEventArgs e) { string oldPath = e.OldFullPath; string newPath = e.FullPath; @@ -100,7 +102,7 @@ namespace Microsoft.Plugin.Program.Storage // the msi installer creates a shortcut, which is detected by the PT Run and ends up in calling this OnAppRenamed method // the thread needs to be halted for a short time to avoid locking the new shortcut file as we read it, otherwise the lock causes // in the issue scenario that a warning is popping up during the msi install process. - System.Threading.Thread.Sleep(1000); + await Task.Delay(OnRenamedEventWaitTime).ConfigureAwait(false); string extension = Path.GetExtension(newPath); Win32Program.ApplicationType oldAppType = Win32Program.GetAppTypeFromPath(oldPath); @@ -124,7 +126,7 @@ namespace Microsoft.Plugin.Program.Storage } catch (Exception ex) { - Log.Exception($"OnAppRenamed-{extension} Program|{e.OldName}|Unable to create program from {oldPath}", ex, GetType()); + Log.Exception($"DoOnAppRenamedAsync-{extension} Program|{e.OldName}|Unable to create program from {oldPath}", ex, GetType()); } // To remove the old app which has been renamed and to add the new application. @@ -146,6 +148,21 @@ namespace Microsoft.Plugin.Program.Storage } } + private void OnAppRenamed(object sender, RenamedEventArgs e) + { + Task.Run(async () => + { + try + { + await DoOnAppRenamedAsync(sender, e).ConfigureAwait(false); + } + catch (Exception e) + { + Log.Exception($"OnAppRenamed throw exception.", e, e.GetType()); + } + }).ConfigureAwait(false); + } + private void OnAppDeleted(object sender, FileSystemEventArgs e) { string path = e.FullPath;