Initial commit
This commit is contained in:
213
Creator/Program.cs
Normal file
213
Creator/Program.cs
Normal file
@ -0,0 +1,213 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Katteker;
|
||||
using KattekerCreator.Helper;
|
||||
|
||||
namespace KattekerCreator
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
private const string _executable = @"C:\Program Files (x86)\NSIS\makensis.exe";
|
||||
private readonly string _baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
private ApplicationArguments _appArguments;
|
||||
private AssemblyFileInfo _assemblyFileInfo;
|
||||
private string _tempDir;
|
||||
private Releases _releases;
|
||||
|
||||
private static int Main(string[] args)
|
||||
{
|
||||
var program = new Program();
|
||||
try
|
||||
{
|
||||
return program.Run(args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.WriteErrorLine(ex.Message);
|
||||
if (ex.InnerException != null)
|
||||
Log.WriteErrorLine(ex.InnerException.Message);
|
||||
#if DEBUG
|
||||
throw;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private int Run(string[] args)
|
||||
{
|
||||
//Parse App-Arguments
|
||||
var parser = new SimpleCommandLineParser<ApplicationArguments>(args);
|
||||
|
||||
if (args.Length == 0)
|
||||
{
|
||||
parser.ShowHelp();
|
||||
return 1924;
|
||||
}
|
||||
|
||||
_appArguments = parser.GetObject();
|
||||
//Create tempdir
|
||||
_tempDir = Utils.CreateTempDirectory();
|
||||
_releases = new Releases(_appArguments.OutputDir);
|
||||
parser.ShowProgramArguments();
|
||||
//Modify AppStub
|
||||
var appStubFile = ModifyAppStub();
|
||||
//Acquire infos from Executable.
|
||||
_assemblyFileInfo = new AssemblyFileInfo(_appArguments.ProgramFile, _tempDir);
|
||||
var configFile = CreateConfigFile();
|
||||
|
||||
//Generate NSIS-Script
|
||||
var additionalFiles = new[]
|
||||
{
|
||||
new PhysicalFile(appStubFile, Path.GetFileName(_appArguments.ProgramFile)),
|
||||
new PhysicalFile(configFile, Path.Combine($"app-{_assemblyFileInfo.AssemblyVersion}", Path.GetFileName(configFile)))
|
||||
};
|
||||
var templateFile = GenerateNsisTemplate(additionalFiles);
|
||||
//Start makensis.exe
|
||||
var setupFilePath = CompileSetupScript(templateFile);
|
||||
//Copy to Output-Folder
|
||||
if (CopyToOutputFolder(setupFilePath))
|
||||
{
|
||||
//Create/Modify RELEASE File
|
||||
var releaseEntry = AddPackageToReleaseFile(setupFilePath);
|
||||
//Copy installer as setup.exe
|
||||
CopyAsSetup(setupFilePath, releaseEntry);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void CopyAsSetup(string setupFilePath, ReleaseEntry releaseEntry)
|
||||
{
|
||||
if (!_releases.IsLatestEntry(releaseEntry)) return;
|
||||
var target = Path.Combine(_appArguments.OutputDir, Constants.SetupFile);
|
||||
File.Delete(target);
|
||||
File.Copy(setupFilePath, target);
|
||||
}
|
||||
|
||||
private ReleaseEntry AddPackageToReleaseFile(string setupFilePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = _releases.Add(setupFilePath, _assemblyFileInfo.AssemblyVersion);
|
||||
_releases.WriteReleaseFile();
|
||||
return result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.WriteErrorLine(e.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private bool CopyToOutputFolder(string setupFilePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (setupFilePath == null) throw new ArgumentNullException(nameof(setupFilePath));
|
||||
var setupFile = Path.GetFileName(setupFilePath);
|
||||
if (string.IsNullOrEmpty(setupFile)) throw new ArgumentException();
|
||||
if (!File.Exists(setupFilePath)) throw new FileNotFoundException(setupFile);
|
||||
if (!string.IsNullOrEmpty(_appArguments.ChangeLog))
|
||||
{
|
||||
|
||||
var changeLogPath = Path.Combine(Path.GetDirectoryName(_appArguments.ProgramFile), _appArguments.ChangeLog);
|
||||
if (!File.Exists(changeLogPath)) throw new FileNotFoundException(changeLogPath);
|
||||
File.Copy(changeLogPath, Path.Combine(_appArguments.OutputDir, Path.GetFileName(_appArguments.ChangeLog) ?? throw new InvalidOperationException()), true);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(_appArguments.OutputDir)) Directory.CreateDirectory(_appArguments.OutputDir);
|
||||
File.Copy(setupFilePath, Path.Combine(_appArguments.OutputDir, setupFile), true);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.WriteErrorLine(e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static string CompileSetupScript(string templateFile)
|
||||
{
|
||||
if (!File.Exists(_executable)) throw new FileNotFoundException("NSIS not installed properly.");
|
||||
int exitcode;
|
||||
using (var p = new Process())
|
||||
{
|
||||
p.StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = _executable,
|
||||
Arguments = templateFile,
|
||||
UseShellExecute = false
|
||||
};
|
||||
var sw = Stopwatch.StartNew();
|
||||
p.Start();
|
||||
p.WaitForExit();
|
||||
exitcode = p.ExitCode;
|
||||
Log.WriteInfoLine($"{Path.GetFileName(_executable)} has exited with Exitcode: {exitcode} (Took: {sw.ElapsedMilliseconds}ms)");
|
||||
}
|
||||
|
||||
if (exitcode != 0) throw new Exception($"{Path.GetFileName(_executable)} has exited with Exitcode: {exitcode}");
|
||||
return Path.ChangeExtension(templateFile, "exe");
|
||||
}
|
||||
|
||||
private string CreateConfigFile()
|
||||
{
|
||||
var pathToFile = Path.Combine(_tempDir, Constants.KattekerConfig);
|
||||
var kattekerConfig = new KattekerConfig
|
||||
{
|
||||
PublishDir = _appArguments.PublishDir ?? _appArguments.OutputDir,
|
||||
Changelog = _appArguments.ChangeLog
|
||||
};
|
||||
kattekerConfig.WriteToFile(pathToFile);
|
||||
return pathToFile;
|
||||
}
|
||||
|
||||
private string ModifyAppStub()
|
||||
{
|
||||
var baseFile = new FileInfo(Path.Combine(_baseDirectory, Constants.ExecutionStub));
|
||||
var targetFile = baseFile.CopyTo(Path.Combine(_tempDir, Constants.ExecutionStub));
|
||||
Utils.CopyResources(_appArguments.ProgramFile, targetFile.FullName);
|
||||
return targetFile.FullName;
|
||||
}
|
||||
|
||||
private static string GenerateFilename(string name, string version, string extension, bool isDelta = false) => $"{name}-{version}-{(isDelta ? "delta" : "full")}.{extension}";
|
||||
|
||||
private string GenerateNsisTemplate(IEnumerable<PhysicalFile> additionalFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
var outFile = Path.Combine(_tempDir, GenerateFilename(_assemblyFileInfo.ProductName, _assemblyFileInfo.AssemblyVersion.ToString(), "nsi"));
|
||||
var setupTmpl = new SetupTmpl
|
||||
{
|
||||
Executable = _assemblyFileInfo.FileInfo.Name,
|
||||
AppName = _assemblyFileInfo.ProductName,
|
||||
CompanyName = _assemblyFileInfo.Company,
|
||||
Description = _assemblyFileInfo.Description,
|
||||
IconPath = _assemblyFileInfo.AssemblyIconPath,
|
||||
Version = _assemblyFileInfo.AssemblyVersion,
|
||||
HelpUrl = "http://example.org", //Not used at the moment.
|
||||
UserInterface = Path.Combine(_baseDirectory, "contrib", "LoadingBar_Icon.exe"),
|
||||
UninstallIcon = Path.Combine(_baseDirectory, "contrib", "uninstall.ico"),
|
||||
OutFile = Path.GetFileName(Path.ChangeExtension(outFile, "exe")),
|
||||
ReleaseChannel = _appArguments.Channel
|
||||
};
|
||||
var path = Path.GetDirectoryName(_appArguments.ProgramFile) ?? string.Empty;
|
||||
setupTmpl.Files.AddRange(additionalFiles);
|
||||
var files = Utils.EnumerateFiles(_appArguments.ProgramFile).ToArray();
|
||||
setupTmpl.InstallSize = (long) Math.Floor(files.Sum(x => x.Length) / 1024f);
|
||||
setupTmpl.Files.AddRange(files.Select(x => new PhysicalFile(x.FullName, x.FullName.Replace(path, $"app-{_assemblyFileInfo.AssemblyVersion}"))));
|
||||
var transformText = setupTmpl.TransformText();
|
||||
File.WriteAllText(outFile, transformText);
|
||||
return outFile;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.WriteErrorLine(e.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user