namespace Pilz.IO; public partial class FileLocker : IDisposable { private FileStream fsLock = null; /// /// Defines the file path to the file that should be locked. /// public string FilePath { get; private set; } /// /// Defines the file path to the lock file that is used to identify the file lock. /// public string LockFile { get; private set; } /// /// Defines if the file is locked privatly by this instance. /// public bool LockedPrivate { get; private set; } = false; /// /// Defines if the file is locked by an other instance/program/user. /// public bool LockedExternal { get { if (LockedPrivate) return false; else { string lockFile = FilePath + ".lock"; bool isLocked = false; if (File.Exists(lockFile)) { try { var fs = new FileStream(lockFile, FileMode.Open, FileAccess.Read); fs.Close(); } catch (IOException) { isLocked = true; } } return isLocked; } } } /// /// Generate a new instance of and locks the given file automatically. /// /// The file path to the file that should be locked. public FileLocker(string filePath) : this(filePath, true) { } /// /// Generate a new instance of /// /// The file path to the file that should be locked. /// Defines if the file should be locked automatically right after creating this instance. public FileLocker(string filePath, bool autoLock) { FilePath = filePath; LockFile = filePath + ".lock"; if (autoLock) Lock(); } /// /// Locks the file, if not already locked privatly. /// public void Lock() { if (!LockedPrivate) { fsLock = new FileStream(LockFile, FileMode.Create, FileAccess.ReadWrite); LockedPrivate = true; } } /// /// Unlocks the file, if locked privatly. /// public void Unlock() { if (LockedPrivate) { fsLock.Close(); fsLock.Dispose(); fsLock = null; File.Delete(LockFile); LockedPrivate = false; } } #region IDisposable private bool disposedValue; protected virtual void Dispose(bool disposing) { if (!disposedValue) Unlock(); } public void Dispose() { Dispose(true); disposedValue = true; } #endregion }