<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0-preview.3.22175.4" />

WriteFileContext

sealed class WriteFileContext
using System.IO; using System.IO.Internal; using System.Threading; namespace System.Configuration.Internal { internal sealed class WriteFileContext { private const int SavingTimeout = 10000; private const int SavingRetryInterval = 100; private readonly string _templateFilename; private TempFileCollection _tempFiles; internal string TempNewFilename { get; } internal WriteFileContext(string filename, string templateFilename) { string directoryOrRootName = UrlPath.GetDirectoryOrRootName(filename); _templateFilename = templateFilename; _tempFiles = new TempFileCollection(directoryOrRootName); try { TempNewFilename = _tempFiles.AddExtension("newcfg"); } catch { ((IDisposable)_tempFiles).Dispose(); _tempFiles = null; throw; } } internal void Complete(string filename, bool success) { try { if (success) { if (File.Exists(filename)) { ValidateWriteAccess(filename); DuplicateFileAttributes(filename, TempNewFilename); } else if (_templateFilename != null) { DuplicateTemplateAttributes(_templateFilename, TempNewFilename); } ReplaceFile(TempNewFilename, filename); _tempFiles.KeepFiles = true; } } finally { ((IDisposable)_tempFiles).Dispose(); _tempFiles = null; } } private void DuplicateFileAttributes(string source, string destination) { FileAttributes attributes = File.GetAttributes(source); File.SetAttributes(destination, attributes); DateTime creationTimeUtc = File.GetCreationTimeUtc(source); File.SetCreationTimeUtc(destination, creationTimeUtc); DuplicateTemplateAttributes(source, destination); } private void DuplicateTemplateAttributes(string source, string destination) { FileAttributes attributes = File.GetAttributes(source); File.SetAttributes(destination, attributes); } private void ValidateWriteAccess(string filename) { FileStream fileStream = null; try { fileStream = new FileStream(filename, FileMode.Open, FileAccess.Write, FileShare.ReadWrite); } catch (IOException) { } finally { fileStream?.Close(); } } private void ReplaceFile(string source, string target) { int num = 0; bool flag = AttemptMove(source, target); while (!flag && num < 10000 && File.Exists(target) && !FileIsWriteLocked(target)) { Thread.Sleep(100); num += 100; flag = AttemptMove(source, target); } if (!flag) throw new ConfigurationErrorsException(System.SR.Format(System.SR.Config_write_failed, target)); } private bool AttemptMove(string source, string target) { try { if (File.Exists(target)) File.Replace(source, target, null); else File.Move(source, target); return true; } catch { return false; } } private static bool FileIsWriteLocked(string fileName) { Stream stream = null; if (File.Exists(fileName)) try { stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete); return false; } catch { return true; } finally { stream?.Close(); } return false; } } }