add descriptive error for PathTooLongException which crashes SMAPI or the installer
This commit is contained in:
parent
36cb8e8fcb
commit
0ed46c0910
|
@ -9,8 +9,9 @@
|
||||||
|
|
||||||
## Upcoming release
|
## Upcoming release
|
||||||
* For players:
|
* For players:
|
||||||
* Fixed console showing _found 1 mod with warnings_ with no mods listed.
|
|
||||||
* If the installer crashes, the window now stays open if possible so you can read the error and ask for help.
|
* If the installer crashes, the window now stays open if possible so you can read the error and ask for help.
|
||||||
|
* Added descriptive error if possible when a `PathTooLongException` crashes SMAPI or the installer.
|
||||||
|
* Fixed console showing _found 1 mod with warnings_ with no mods listed.
|
||||||
|
|
||||||
* For mod authors:
|
* For mod authors:
|
||||||
* Added three stages to the `LoadStageChanged` event: `CreatedInitialLocations`/`SaveAddedLocations` (raised immediately after the game adds locations but before they're initialized), and `ReturningToTitle` (raised before exiting to the title screen).
|
* Added three stages to the `LoadStageChanged` event: `CreatedInitialLocations`/`SaveAddedLocations` (raised immediately after the game adds locations but before they're initialized), and `ReturningToTitle` (raised before exiting to the title screen).
|
||||||
|
|
|
@ -279,6 +279,7 @@ namespace StardewModdingApi.Installer
|
||||||
/*********
|
/*********
|
||||||
** Step 4: validate assumptions
|
** Step 4: validate assumptions
|
||||||
*********/
|
*********/
|
||||||
|
// executable exists
|
||||||
if (!File.Exists(paths.ExecutablePath))
|
if (!File.Exists(paths.ExecutablePath))
|
||||||
{
|
{
|
||||||
this.PrintError("The detected game install path doesn't contain a Stardew Valley executable.");
|
this.PrintError("The detected game install path doesn't contain a Stardew Valley executable.");
|
||||||
|
@ -286,6 +287,17 @@ namespace StardewModdingApi.Installer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// game folder doesn't contain paths beyond the max limit
|
||||||
|
{
|
||||||
|
string[] tooLongPaths = PathUtilities.GetTooLongPaths(Path.Combine(paths.GamePath, "Mods")).ToArray();
|
||||||
|
if (tooLongPaths.Any())
|
||||||
|
{
|
||||||
|
this.PrintError($"SMAPI can't install to the detected game folder, because some of its files exceed the maximum {context.Platform} path length.\nIf you need help fixing this error, see https://smapi.io/help\n\nAffected paths:\n {string.Join("\n ", tooLongPaths)}");
|
||||||
|
Console.ReadLine();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
** Step 5: ask what to do
|
** Step 5: ask what to do
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("StardewModdingAPI")]
|
[assembly: InternalsVisibleTo("StardewModdingAPI")]
|
||||||
|
[assembly: InternalsVisibleTo("SMAPI.Installer")]
|
||||||
[assembly: InternalsVisibleTo("SMAPI.Web")]
|
[assembly: InternalsVisibleTo("SMAPI.Web")]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.Contracts;
|
using System.Diagnostics.Contracts;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -133,5 +134,29 @@ namespace StardewModdingAPI.Toolkit.Utilities
|
||||||
{
|
{
|
||||||
return !Regex.IsMatch(str, "[^a-z0-9_.-]", RegexOptions.IgnoreCase);
|
return !Regex.IsMatch(str, "[^a-z0-9_.-]", RegexOptions.IgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Get the paths which exceed the OS length limit.</summary>
|
||||||
|
/// <param name="rootPath">The root path to search.</param>
|
||||||
|
internal static IEnumerable<string> GetTooLongPaths(string rootPath)
|
||||||
|
{
|
||||||
|
return Directory
|
||||||
|
.EnumerateFileSystemEntries(rootPath, "*.*", SearchOption.AllDirectories)
|
||||||
|
.Where(PathUtilities.IsPathTooLong);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Get whether a file or directory path exceeds the OS path length limit.</summary>
|
||||||
|
/// <param name="path">The path to test.</param>
|
||||||
|
internal static bool IsPathTooLong(string path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_ = Path.GetFullPath(path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (PathTooLongException)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,11 +252,22 @@ namespace StardewModdingAPI.Framework.Logging
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// missing content folder exception
|
// missing content folder exception
|
||||||
case FileNotFoundException ex when ex.Message == "Could not find file 'C:\\Program Files (x86)\\Steam\\SteamApps\\common\\Stardew Valley\\Content\\XACT\\FarmerSounds.xgs'.": // path in error is hardcoded regardless of install path
|
case FileNotFoundException ex when ex.Message == "Couldn't find file 'C:\\Program Files (x86)\\Steam\\SteamApps\\common\\Stardew Valley\\Content\\XACT\\FarmerSounds.xgs'.": // path in error is hardcoded regardless of install path
|
||||||
this.Monitor.Log("The game can't find its Content\\XACT\\FarmerSounds.xgs file. You can usually fix this by resetting your content files (see https://smapi.io/troubleshoot#reset-content ), or by uninstalling and reinstalling the game.", LogLevel.Error);
|
this.Monitor.Log("The game can't find its Content\\XACT\\FarmerSounds.xgs file. You can usually fix this by resetting your content files (see https://smapi.io/troubleshoot#reset-content ), or by uninstalling and reinstalling the game.", LogLevel.Error);
|
||||||
this.Monitor.Log($"Technical details: {ex.GetLogSummary()}");
|
this.Monitor.Log($"Technical details: {ex.GetLogSummary()}");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// path too long exception
|
||||||
|
case PathTooLongException:
|
||||||
|
{
|
||||||
|
string[] affectedPaths = PathUtilities.GetTooLongPaths(Constants.ModsPath).ToArray();
|
||||||
|
string message = affectedPaths.Any()
|
||||||
|
? $"SMAPI can't launch because some of your mod files exceed the maximum path length on {Constants.Platform}.\nIf you need help fixing this error, see https://smapi.io/help\n\nAffected paths:\n {string.Join("\n ", affectedPaths)}"
|
||||||
|
: $"The game failed to launch: {exception.GetLogSummary()}";
|
||||||
|
this.MonitorForGame.Log(message, LogLevel.Error);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// generic exception
|
// generic exception
|
||||||
default:
|
default:
|
||||||
this.MonitorForGame.Log($"The game failed to launch: {exception.GetLogSummary()}", LogLevel.Error);
|
this.MonitorForGame.Log($"The game failed to launch: {exception.GetLogSummary()}", LogLevel.Error);
|
||||||
|
|
Loading…
Reference in New Issue