Skip to content

Commit

Permalink
Merge pull request #86 from synhershko/35-unauthorized-exception-fix
Browse files Browse the repository at this point in the history
#35 Added delay in case there is a lock on files that are to be updated
  • Loading branch information
robinwassen authored Jul 5, 2016
2 parents c617fd3 + b992efe commit 5d4a964
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 13 deletions.
37 changes: 30 additions & 7 deletions src/NAppUpdate.Framework/Tasks/FileUpdateTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,21 @@ public override TaskExecutionStatus Execute(bool coldRun)
}

var dirName = Path.GetDirectoryName(_destinationFile);

if (!Directory.Exists(dirName))
{
Utils.FileSystem.CreateDirectoryStructure(dirName, false);
}

// Create a backup copy if target exists
if (_backupFile == null && File.Exists(_destinationFile))
{
if (!Directory.Exists(Path.GetDirectoryName(Path.Combine(UpdateManager.Instance.Config.BackupFolder, LocalPath))))
Utils.FileSystem.CreateDirectoryStructure(
Path.GetDirectoryName(Path.Combine(UpdateManager.Instance.Config.BackupFolder, LocalPath)), false);
{
string backupPath = Path.GetDirectoryName(Path.Combine(UpdateManager.Instance.Config.BackupFolder, LocalPath));
Utils.FileSystem.CreateDirectoryStructure(backupPath, false);
}

_backupFile = Path.Combine(UpdateManager.Instance.Config.BackupFolder, LocalPath);
File.Copy(_destinationFile, _backupFile, true);
}
Expand All @@ -94,11 +100,7 @@ public override TaskExecutionStatus Execute(bool coldRun)
{
if (File.Exists(_destinationFile))
{
//if (FileSystem.IsExeRunning(_destinationFile))
//{
// UpdateManager.Instance.Logger.Log(Logger.SeverityLevel.Warning, "Process {0} is still running", _destinationFile);
// Thread.Sleep(1000); // TODO: retry a few times and throw after a while
//}
FileLockWait();

if (!PermissionsCheck.HaveWritePermissionsForFileOrFolder(_destinationFile))
{
Expand All @@ -114,7 +116,10 @@ public override TaskExecutionStatus Execute(bool coldRun)
try
{
if (File.Exists(_destinationFile))
{
File.Delete(_destinationFile);
}

File.Move(_tempFile, _destinationFile);
_tempFile = null;
}
Expand Down Expand Up @@ -155,5 +160,23 @@ public override bool Rollback()

return true;
}

/// <summary>
/// To mitigate problems with the files being locked even though the application mutex has been released.
/// https://github.com/synhershko/NAppUpdate/issues/35
/// </summary>
private void FileLockWait()
{
int attempt = 0;
while (FileSystem.IsFileLocked(new FileInfo(_destinationFile)))
{
Thread.Sleep(500);
attempt++;
if (attempt == 10)
{
throw new UpdateProcessFailedException("Failed to update, the file is locked: " + _destinationFile);
}
}
}
}
}
32 changes: 26 additions & 6 deletions src/NAppUpdate.Framework/Utils/FileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,36 @@ public static IEnumerable<string> GetFiles(string path, string searchPattern, Se
return files;
}

public static bool IsExeRunning(string path)
/// <summary>
/// Returns true if read/write lock exists on the file, otherwise false
/// From http://stackoverflow.com/a/937558
/// </summary>
/// <param name="file">The file to check for a lock</param>
/// <returns></returns>
public static bool IsFileLocked(FileInfo file)
{
var processes = Process.GetProcesses();
foreach (Process p in processes)
FileStream stream = null;

try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
if (p.MainModule.FileName.StartsWith(path, StringComparison.InvariantCultureIgnoreCase))
return true;
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
return true;
}
finally
{
if (stream != null)
stream.Close();
}

//file is not locked
return false;
}

}
}

0 comments on commit 5d4a964

Please sign in to comment.