Selaa lähdekoodia

Handle main log file being locked, to allow multiple game instances

Bepis 5 vuotta sitten
vanhempi
commit
56d90d9340
2 muutettua tiedostoa jossa 43 lisäystä ja 5 poistoa
  1. 27 5
      BepInEx/Logging/DiskLogListener.cs
  2. 16 0
      BepInEx/Utility.cs

+ 27 - 5
BepInEx/Logging/DiskLogListener.cs

@@ -13,12 +13,34 @@ namespace BepInEx.Logging
 	{
 		protected LogLevel DisplayedLogLevel = (LogLevel)Enum.Parse(typeof(LogLevel), ConfigConsoleDisplayedLevel.Value, true);
 
-		protected TextWriter LogWriter = TextWriter.Synchronized(new StreamWriter(Path.Combine(Paths.BepInExRootPath, "LogOutput.log"), ConfigAppendLog.Value, Encoding.UTF8));
+		protected TextWriter LogWriter { get; set; }
 
-		protected Timer FlushTimer;
+		protected Timer FlushTimer { get; set; }
 
 		public DiskLogListener()
 		{
+			int counter = 1;
+			string localPath = "LogOutput.log";
+
+			FileStream fileStream;
+
+			while (!Utility.TryOpenFileStream(Path.Combine(Paths.BepInExRootPath, localPath), ConfigAppendLog.Value ? FileMode.Append : FileMode.Create, out fileStream, share: FileShare.Read))
+			{
+				if (counter == 5)
+				{
+					Logger.LogError("Couldn't open a log file for writing. Skipping log file creation");
+
+					return;
+				}
+
+				Logger.LogWarning($"Couldn't open log file '{localPath}' for writing, trying another...");
+
+				localPath = $"LogOutput.log.{counter++}";
+			}
+
+			LogWriter = TextWriter.Synchronized(new StreamWriter(fileStream, Encoding.UTF8));
+			
+
 			FlushTimer = new Timer(o =>
 			{
 				LogWriter?.Flush();
@@ -38,9 +60,9 @@ namespace BepInEx.Logging
 
 		public void Dispose()
 		{
-			FlushTimer.Dispose();
-			LogWriter.Flush();
-			LogWriter.Dispose();
+			FlushTimer?.Dispose();
+			LogWriter?.Flush();
+			LogWriter?.Dispose();
 		}
 
 		~DiskLogListener()

+ 16 - 0
BepInEx/Utility.cs

@@ -136,5 +136,21 @@ namespace BepInEx
 
 			return false;
 		}
+
+		public static bool TryOpenFileStream(string path, FileMode mode, out FileStream fileStream, FileAccess access = FileAccess.ReadWrite, FileShare share = FileShare.None)
+		{
+			try
+			{
+				fileStream = new FileStream(path, mode, access, share);
+
+				return true;
+			}
+			catch (IOException)
+			{
+				fileStream = null;
+
+				return false;
+			}
+		}
 	}
 }