using System; using System.Drawing; using System.IO; using System.Linq; using Semver; using TsudaKageyu; using Vestris.ResourceLib; namespace KattekerCreator { public class AssemblyFileInfo { private readonly string _company; private readonly string _copyright; private readonly string _description; private readonly string _productName; public AssemblyFileInfo(ApplicationArguments appArguments, string tempDir) { FileInfo = new FileInfo(appArguments.ProgramFile); using (var resourceInfo = new ResourceInfo()) { resourceInfo.Load(appArguments.ProgramFile); if (resourceInfo.ResourceTypes.All(x => x.ResourceType != Kernel32.ResourceTypes.RT_VERSION)) return; var versionResource = (VersionResource) resourceInfo[Kernel32.ResourceTypes.RT_VERSION].First(); var stringFileInfo = ((StringFileInfo) versionResource[nameof(StringFileInfo)]).Strings .FirstOrDefault().Value; AssemblyIconPath = GetAssemblyIcon(appArguments.ProgramFile, tempDir); if (stringFileInfo.Strings.ContainsKey("CompanyName")) _company = stringFileInfo.Strings["CompanyName"].StringValue.TrimEnd('\0'); if (stringFileInfo.Strings.ContainsKey("FileDescription")) _description = stringFileInfo.Strings["FileDescription"].StringValue.TrimEnd('\0'); if (stringFileInfo.Strings.ContainsKey("LegalCopyright")) _copyright = stringFileInfo.Strings["LegalCopyright"].StringValue.TrimEnd('\0'); if (stringFileInfo.Strings.ContainsKey("ProductName")) _productName = stringFileInfo.Strings["ProductName"].StringValue.TrimEnd('\0'); if (!stringFileInfo.Strings.ContainsKey("ProductVersion")) return; AssemblyVersion = appArguments.Version != null ? GetSemanticVersion(appArguments.Version) : GetSemanticVersion(stringFileInfo.Strings["ProductVersion"].StringValue.TrimEnd('\0')); } } public string AssemblyIconPath { get; } public SemVersion AssemblyVersion { get; } public string Company => _company ?? string.Empty; public string Copyright => _copyright ?? string.Empty; public string Description => _description ?? string.Empty; public FileInfo FileInfo { get; } public string ProductName => _productName ?? Description; private static string GetAssemblyIcon(string programFile, string tempDir) { var applicationIcon = Path.Combine(tempDir, "application.ico"); if (string.IsNullOrWhiteSpace(programFile)) throw new ApplicationException("Program not set."); if (!File.Exists(programFile)) throw new ApplicationException("Program not found."); if (File.Exists(applicationIcon)) File.Delete(applicationIcon); using (var fileStream = new FileStream(applicationIcon, FileMode.CreateNew)) { try { var ie = new IconExtractor(programFile); using (var icon = ie.GetIcon(0)) { icon?.Save(fileStream); } } catch (Exception) { using (var icon = Icon.ExtractAssociatedIcon(programFile)) { icon?.Save(fileStream); } } } return applicationIcon; } private static SemVersion GetSemanticVersion(string productVersion) { productVersion = productVersion.Replace(',', '.'); if (SemVersion.TryParse(productVersion, out var semanticVersion)) return semanticVersion?.Change(build: string.Empty); Version.TryParse(productVersion, out var version); return SemVersion.Parse(version.ToString(3)); } } }