/// <summary>
/// </summary>
private int Run(Assembly integrationAgentAssembly, string integrationAgentExeFileName, string integrationAgentExeDirectory, string[] args)
{
var parameters = Program.ParseArguments(args);
var fileVersion = FileVersionInfo.GetVersionInfo(integrationAgentAssembly.Location).FileVersion;
if (parameters.ShowVersion || parameters.ShowHelp)
{
Console.WriteLine("IntegrationAgent v" + fileVersion);
}
if (parameters.ShowHelp)
{
Program.ShowHelp();
}
if (parameters.ShowVersion || parameters.ShowHelp)
{
return 0;
}
// Verify that assembly is signed and uses the correct key
var traceWriter = Program.CreateTraceWriter(parameters.TraceLevel);
traceWriter(TraceLevel.Verbose, "Checking assembly strong name.");
if (!integrationAgentAssembly.HasValidStrongName())
{
traceWriter(TraceLevel.Error, "Unsigned assembly!");
return 1;
}
traceWriter(TraceLevel.Verbose, "Verifying assembly signature.");
if (!integrationAgentAssembly.PublicKeyTokenEqualsTo(Token.Bytes))
{
traceWriter(TraceLevel.Error, "Invalid assembly!");
return 2;
}
// If no JSON config file name provided as paramter uses the application name
traceWriter(TraceLevel.Verbose, "Looking for JSON config file.");
var configFile = Path.Combine(integrationAgentExeDirectory, Path.GetFileNameWithoutExtension(integrationAgentExeFileName) + ".json");
if (!string.IsNullOrEmpty(parameters.Config))
{
if (!parameters.Config.EndsWith(".json"))
{
parameters.Config = parameters.Config + ".json";
}
configFile = Path.Combine(integrationAgentExeDirectory, parameters.Config);
}
// Check and reads the configuration file
var configuration = new Configuration();
if (File.Exists(configFile))
{
traceWriter(TraceLevel.Verbose, "Reading the JSON config file.");
var configJson = File.ReadAllText(configFile);
var jsonSerializer = new JavaScriptSerializer();
configuration = jsonSerializer.Deserialize<Configuration>(configJson) ?? configuration;
traceWriter(TraceLevel.Verbose, "JSON config file loaded.");
}
// Merges config file and command line parameters. Command line paramters have precedence.
configuration.package = parameters.Package ?? configuration.package;
configuration.token = parameters.Token ?? configuration.token;
configuration.repository = parameters.Repository ?? configuration.repository;
configuration.repositoryUsername = parameters.RepositoryUsername ?? configuration.repositoryUsername;
configuration.repositoryPassword = parameters.RepositoryPassword ?? configuration.repositoryPassword;
traceWriter(TraceLevel.Verbose, "Checking input parameters.");
if (string.IsNullOrWhiteSpace(configuration.package) && string.IsNullOrEmpty(configuration.token))
{
traceWriter(TraceLevel.Error, "Invalid configuration!");
return 3;
}
// Initializes NuGet repositories
traceWriter(TraceLevel.Verbose, "Initializing NuGet repositories.");
var nugetRepository = new DataServicePackageRepository(new Uri(NuGetRepository));
var aggregateRepository = new AggregateRepository(new[] { nugetRepository });
if (Uri.IsWellFormedUriString(configuration.repository, UriKind.Absolute))
{
if (!string.IsNullOrWhiteSpace(configuration.repositoryUsername) &&
!string.IsNullOrWhiteSpace(configuration.repositoryPassword))
{
HttpClient.DefaultCredentialProvider = new NugetCredentialProvider(
configuration.repositoryUsername, configuration.repositoryPassword);
}
var client = new HttpClient(new Uri(configuration.repository));
var customRepository = new DataServicePackageRepository(client);
aggregateRepository = new AggregateRepository(new[] { customRepository, nugetRepository });
}
// Perform auto-update if not disabled
if (!parameters.DisableUpdates)
{
traceWriter(TraceLevel.Verbose, "Checking for self update.");
var integrationAgentAssemblyName = integrationAgentAssembly.GetName();
var version = new SemanticVersion(integrationAgentAssemblyName.Version);
var package = aggregateRepository
.GetUpdates(new[] { new PackageName(integrationAgentAssemblyName.Name, version) }, includePrerelease: false, includeAllVersions: false)
.OrderBy(p => p.Version)
.LastOrDefault();
if (package != null && package.Version > version)
{
traceWriter(TraceLevel.Verbose, "Newer version found. Updating files.");
var filename = Path.GetFileName(integrationAgentExeFileName);
var file = package.GetFiles().FirstOrDefault(f => !string.IsNullOrEmpty(f.Path) && Path.GetFileName(f.Path).Equals(filename, StringComparison.OrdinalIgnoreCase));
if (file != null)
{
File.Delete(integrationAgentExeFileName + ".bak");
File.Move(integrationAgentExeFileName, integrationAgentExeFileName + ".bak");
using (Stream fromStream = file.GetStream(), toStream = File.Create(integrationAgentExeFileName))
{
fromStream.CopyTo(toStream);
}
Process.Start(integrationAgentExeFileName, string.Join(" ", args) + " -disableupdates");
Environment.Exit(0);
}
}
else
{
traceWriter(TraceLevel.Verbose, "Version is up to date.");
}
}
// Install the package to run including its dependencies
traceWriter(TraceLevel.Verbose, "Checking for execution package.");
var packagesPath = Path.Combine(integrationAgentExeDirectory, "packages");
var remotePackage = aggregateRepository.FindPackagesById(configuration.package).OrderBy(p => p.Version).LastOrDefault();
var localRepository = new SharedPackageRepository(packagesPath);
if (!localRepository.Exists(remotePackage))
{
traceWriter(TraceLevel.Verbose, "Execution package not found localy. Installing remote.");
var packageManager = new PackageManager(aggregateRepository, packagesPath);
packageManager.InstallPackage(remotePackage, ignoreDependencies: false, allowPrereleaseVersions: false);
}
var localPackage = localRepository.FindPackagesById(configuration.package).OrderBy(p => p.Version).LastOrDefault();
if (localPackage == null)
{
traceWriter(TraceLevel.Error, "Package not found!");
return 4;
}
// Build a dictionary list of assemblies based on assembly fully qualified name for dynamically resolving from the loaded package
traceWriter(TraceLevel.Verbose, "Resolving execution package dependencies.");
var allAssemblies = localRepository
.GetPackages()
.ToArray()
.SelectMany(p => p.AssemblyReferences.Select(a =>
{
var path = Path.Combine(packagesPath, p.Id + "." + p.Version, a.Path);
var aname = AssemblyName.GetAssemblyName(path);
return new { key = aname.FullName, value = path };
}))
.DistinctBy(i => i.key)
.ToDictionary(i => i.key, i => i.value);
AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) =>
{
var aname = new AssemblyName(eventArgs.Name);
if (allAssemblies.ContainsKey(aname.FullName))
{
return Assembly.LoadFile(allAssemblies[aname.FullName]);
}
return null;
};
// Run the package export delegate if found
var assemblies = localPackage.AssemblyReferences.Select(a => new AssemblyCatalog(Path.Combine(packagesPath, localPackage.Id + "." + localPackage.Version, a.Path)));
using (var catalog = new AggregateCatalog(assemblies))
using (var container = new CompositionContainer(catalog))
{
traceWriter(TraceLevel.Verbose, "Resolving execution package entry point.");
container.SatisfyImportsOnce(this);
if (this.RunAssembly == null)
{
traceWriter(TraceLevel.Error, "Execution package extry point not found!");
return 5;
}
traceWriter(TraceLevel.Verbose, "Invoking execution package extry point.");
this.RunAssembly(configuration.token, traceWriter);
traceWriter(TraceLevel.Verbose, "Execution package finished successfully.");
return 0;
}
}