private static string GetMetadataCacheFilePath(out string[] alternates)
{
var exePath = Process.GetCurrentProcess().MainModule.FileName;
using (var sha = new SHA256CryptoServiceProvider2())
{
// since this is used to generate a file path, we must limit the length of the generated name so it doesn't exceed max path length
// we don't simply use MD5 because it throws an exception if the OS has strict cryptographic policies in place (e.g. FIPS)
// note: truncation of SHA256 seems to be an accepted method of producing a shorter hash - see notes in HashUtilities
var hash = StringUtilities.ToHexString(sha.ComputeHash(Encoding.Unicode.GetBytes(exePath)), 0, 16);
// alternate locations are treated as read-only pre-generated cache files (e.g. for Portable workstation)
alternates = new[] {Path.Combine(Platform.PluginDirectory, "pxpx", hash)};
// return the main location, which must be writable
return Path.Combine(Platform.ApplicationDataDirectory, "pxpx", hash);
}
}