157 lines
5.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using KattekerCreator.Exceptions;
using Minimatch;
using Vestris.ResourceLib;
namespace KattekerCreator.Helper
{
public static class Utils
{
public static bool CheckFileExistens(string filePath)
{
if (File.Exists(filePath)) return true;
var file = filePath.Replace(Directory.GetParent(filePath) + "\\", "");
Console.WriteLine("Checking the prerequisites has failed.");
Console.WriteLine($"{file} is missing. Program exits now.");
Console.ReadKey();
return false;
}
public static bool IsFilesizeWrong(string filename)
{
var file = new FileInfo(filename);
return !file.Exists || file.Length < 524288;
}
public static void CopyResources(string inFile, string outFile)
{
using (var ri = new ResourceInfo())
{
ri.Load(inFile);
if (ri.ResourceTypes.Any(x => x.ResourceType == Kernel32.ResourceTypes.RT_GROUP_ICON))
{
var groupIcon = ri[Kernel32.ResourceTypes.RT_GROUP_ICON];
var iconDictionary = groupIcon.FirstOrDefault() as IconDirectoryResource;
iconDictionary?.SaveTo(outFile);
}
if (ri.ResourceTypes.Any(x => x.ResourceType == Kernel32.ResourceTypes.RT_VERSION))
{
var versionResource = (VersionResource)ri[Kernel32.ResourceTypes.RT_VERSION].First();
versionResource.Language = 0;
versionResource.SaveTo(outFile);
}
}
}
/// <summary>
/// Get the signtool.exe command line. Returns "" if no certificate string is provided.
/// </summary>
/// <param name="certificate"></param>
/// <param name="password"></param>
/// <param name="filename"></param>
/// <returns></returns>
public static string GetSignToolCommandLine(string certificate, string password, string filename)
{
return string.IsNullOrWhiteSpace(certificate)
? string.Empty
: $"\"{GetSignTool()}\" {GetSignToolParameters(certificate, password, filename)}";
}
public static string GetSignToolParameters(string certificate, string password, string filename)
{
return $"sign /fd SHA256 /t http://timestamp.digicert.com /f \"{certificate}\" /p {password} {filename}";
}
public static string GetSignTool()
{
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "contrib", "signtool.exe");
}
public static void DeleteTempDir(string tempDir)
{
#if !DEBUG
try
{
Directory.Delete(tempDir, true);
}
catch
{
//silently ignore
}
#endif
}
public static IList<FileInfo> EnumerateFiles(string path, IEnumerable<string> userdefinedFileExclusions = null)
{
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullException(nameof(path));
var result = new DirectoryInfo(path).EnumerateFiles("*.*", SearchOption.AllDirectories).ToList();
var minimatchOptions = new Options { AllowWindowsPaths = true };
foreach (var pattern in FileExclusions(userdefinedFileExclusions))
{
var matcher = new Minimatcher(pattern, minimatchOptions);
for (var index = result.Count - 1; index >= 0; index--)
{
if (matcher.IsMatch(result[index].Name))
{
result.Remove(result[index]);
}
}
}
return result;
}
private static IEnumerable<string> FileExclusions(IEnumerable<string> userdefinedfileExclusions = null)
{
yield return "*.pdb";
yield return "*.tmp";
yield return "*.obj";
yield return "*.pch";
yield return "*.vshost.exe*";
yield return "squirrelHelperInfo.json";
yield return "Katteker.config";
if (userdefinedfileExclusions == null) yield break;
foreach (var fileExclusion in userdefinedfileExclusions)
{
yield return fileExclusion;
}
}
public static void SignExecutable(string certificate, string password, string filename)
{
if (!string.IsNullOrWhiteSpace(certificate))
{
var exitCode = ExecuteProcess(GetSignTool(), GetSignToolParameters(certificate, password, filename));
if (exitCode != 0) throw new KattekerCreatorException("AppStub could not signed.");
}
}
public static int ExecuteProcess(string executable, string arguments)
{
int exitCode;
using (var p = new Process())
{
p.StartInfo = new ProcessStartInfo
{
FileName = executable,
Arguments = arguments,
UseShellExecute = false
};
var sw = Stopwatch.StartNew();
p.Start();
p.WaitForExit();
exitCode = p.ExitCode;
Log.WriteInfoLine($"{Path.GetFileName(executable)} has exited with exit code: {exitCode} (Took: {sw.ElapsedMilliseconds}ms)");
}
return exitCode;
}
}
}