/*
Myrtille: A native HTML4/5 Remote Desktop Protocol client.
Copyright(c) 2014-2021 Cedric Coste
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using System.Xml;
using Myrtille.Helpers;
using Myrtille.PdfScribe;
namespace Myrtille.Services
{
[RunInstaller(true)]
public class ServicesInstaller : Installer
{
public override void Install(
IDictionary stateSaver)
{
// enable the line below to debug this installer; disable otherwise
//MessageBox.Show("Attach the .NET debugger to the 'MSI Debug' msiexec.exe process now for debug. Click OK when ready...", "MSI Debug");
// if the installer is running in repair mode, it will try to re-install Myrtille... which is fine
// problem is, it won't uninstall it first... which is not fine because some components can't be installed twice!
// thus, prior to any install, try to uninstall first
Context.LogMessage("Myrtille.Services is being installed, cleaning first");
try
{
Uninstall(null);
}
catch (Exception exc)
{
Context.LogMessage(string.Format("Failed to clean Myrtille.Services ({0})", exc));
}
Context.LogMessage("Installing Myrtille.Services");
base.Install(stateSaver);
try
{
var process = new Process();
bool debug = true;
#if !DEBUG
debug = false;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
#endif
process.StartInfo.FileName = string.Format(@"{0}\WindowsPowerShell\v1.0\powershell.exe", Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess ? Environment.SystemDirectory.ToLower().Replace("system32", "sysnative") : Environment.SystemDirectory);
process.StartInfo.Arguments = "-ExecutionPolicy Bypass" +
" -Command \"& '" + Path.Combine(Path.GetFullPath(Context.Parameters["targetdir"]), "bin", "Myrtille.Services.Install.ps1") + "'" +
" -BinaryPath '" + Path.Combine(Path.GetFullPath(Context.Parameters["targetdir"]), "bin", "Myrtille.Services.exe") + "'" +
" -DebugMode " + (debug ? "1" : "0") +
" | Tee-Object -FilePath '" + Path.Combine(Path.GetFullPath(Context.Parameters["targetdir"]), "log", "Myrtille.Services.Install.log") + "'" + "\"";
process.Start();
process.WaitForExit();
if (process.ExitCode != 0)
{
throw new Exception(string.Format("An error occured while running {0}. See {1} for more information.",
Path.Combine(Path.GetFullPath(Context.Parameters["targetdir"]), "bin", "Myrtille.Services.Install.ps1"),
Path.Combine(Path.GetFullPath(Context.Parameters["targetdir"]), "log", "Myrtille.Services.Install.log")));
}
// load config
var config = new XmlDocument();
var configPath = Path.Combine(Path.GetFullPath(Context.Parameters["targetdir"]), "bin", "Myrtille.Services.exe.config");
config.Load(configPath);
var navigator = config.CreateNavigator();
// services port
int servicesPort = 8080;
if (!string.IsNullOrEmpty(Context.Parameters["SERVICESPORT"]))
{
int.TryParse(Context.Parameters["SERVICESPORT"], out servicesPort);
}
if (servicesPort != 8080)
{
// services endpoints
var services = XmlTools.GetNode(navigator, "/configuration/system.serviceModel/services");
if (services != null)
{
services.InnerXml = services.InnerXml.Replace("8080", servicesPort.ToString());
}
}
// multifactor authentication
string oasisApiKey = null;
if (!string.IsNullOrEmpty(Context.Parameters["OASISAPIKEY"]))
{
oasisApiKey = Context.Parameters["OASISAPIKEY"];
}
string oasisAppKey = null;
if (!string.IsNullOrEmpty(Context.Parameters["OASISAPPKEY"]))
{
oasisAppKey = Context.Parameters["OASISAPPKEY"];
}
string oasisAppId = null;
if (!string.IsNullOrEmpty(Context.Parameters["OASISAPPID"]))
{
oasisAppId = Context.Parameters["OASISAPPID"];
}
// enterprise mode
string enterpriseAdminGroup = null;
if (!string.IsNullOrEmpty(Context.Parameters["ENTERPRISEADMINGROUP"]))
{
enterpriseAdminGroup = Context.Parameters["ENTERPRISEADMINGROUP"];
}
string enterpriseDomain = null;
if (!string.IsNullOrEmpty(Context.Parameters["ENTERPRISEDOMAIN"]))
{
enterpriseDomain = Context.Parameters["ENTERPRISEDOMAIN"];
}
string enterpriseNetbiosDomain = null;
if (!string.IsNullOrEmpty(Context.Parameters["ENTERPRISENETBIOSDOMAIN"]))
{
enterpriseNetbiosDomain = Context.Parameters["ENTERPRISENETBIOSDOMAIN"];
}
// app settings
var appSettings = XmlTools.GetNode(navigator, "/configuration/appSettings");
if (appSettings != null)
{
// MFAAuthAdapter
if (!string.IsNullOrEmpty(oasisApiKey) && !string.IsNullOrEmpty(oasisAppKey) && !string.IsNullOrEmpty(oasisAppId))
{
XmlTools.UncommentConfigKey(config, appSettings, "MFAAuthAdapter");
XmlTools.WriteConfigKey(appSettings, "OASISApiKey", oasisApiKey);
XmlTools.WriteConfigKey(appSettings, "OASISAppKey", oasisAppKey);
XmlTools.WriteConfigKey(appSettings, "OASISAppID", oasisAppId);
}
// EnterpriseAdapter
if (!string.IsNullOrEmpty(enterpriseAdminGroup) && !string.IsNullOrEmpty(enterpriseDomain))
{
XmlTools.UncommentConfigKey(config, appSettings, "EnterpriseAdapter");
XmlTools.WriteConfigKey(appSettings, "EnterpriseAdminGroup", enterpriseAdminGroup);
XmlTools.WriteConfigKey(appSettings, "EnterpriseDomain", enterpriseDomain);
XmlTools.WriteConfigKey(appSettings, "EnterpriseNetbiosDomain", enterpriseNetbiosDomain);
}
}
// save config
config.Save(configPath);
// pdf printer
if (!string.IsNullOrEmpty(Context.Parameters["PDFPRINTER"]))
{
// install Myrtille PDF printer
var scribeInstaller = new PdfScribeInstaller(Context);
var printerDir = Path.Combine(Path.GetFullPath(Context.Parameters["targetdir"]), "bin");
var driversDir = Path.Combine(printerDir, Environment.Is64BitOperatingSystem ? "amd64" : "x86");
if (!scribeInstaller.InstallPdfScribePrinter(driversDir, Path.Combine(printerDir, "Myrtille.Printer.exe"), string.Empty))
{
MessageBox.Show(
ActiveWindow.Active,
"the myrtille virtual pdf printer could not be installed. Please check logs (into the install log folder)",
"Myrtille.Services",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
}
}
Context.LogMessage("Installed Myrtille.Services");
}
catch (Exception exc)
{
Context.LogMessage(string.Format("Failed to install Myrtille.Services ({0})", exc));
throw;
}
}
public override void Commit(
IDictionary savedState)
{
base.Commit(savedState);
// insert code as needed
}
public override void Rollback(
IDictionary savedState)
{
base.Rollback(savedState);
DoUninstall();
}
public override void Uninstall(
IDictionary savedState)
{
base.Uninstall(savedState);
DoUninstall();
}
private void DoUninstall()
{
// enable the line below to debug this installer; disable otherwise
//MessageBox.Show("Attach the .NET debugger to the 'MSI Debug' msiexec.exe process now for debug. Click OK when ready...", "MSI Debug");
Context.LogMessage("Uninstalling Myrtille.Services");
try
{
var process = new Process();
bool debug = true;
#if !DEBUG
debug = false;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
#endif
process.StartInfo.FileName = string.Format(@"{0}\WindowsPowerShell\v1.0\powershell.exe", Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess ? Environment.SystemDirectory.ToLower().Replace("system32", "sysnative") : Environment.SystemDirectory);
process.StartInfo.Arguments = "-ExecutionPolicy Bypass" +
" -Command \"& '" + Path.Combine(Path.GetFullPath(Context.Parameters["targetdir"]), "bin", "Myrtille.Services.Uninstall.ps1") + "'" +
" -DebugMode " + (debug ? "1" : "0") +
" | Tee-Object -FilePath '" + Path.Combine(Path.GetFullPath(Context.Parameters["targetdir"]), "log", "Myrtille.Services.Uninstall.log") + "'" + "\"";
process.Start();
process.WaitForExit();
if (process.ExitCode != 0)
{
throw new Exception(string.Format("An error occured while running {0}. See {1} for more information.",
Path.Combine(Path.GetFullPath(Context.Parameters["targetdir"]), "bin", "Myrtille.Services.Uninstall.ps1"),
Path.Combine(Path.GetFullPath(Context.Parameters["targetdir"]), "log", "Myrtille.Services.Uninstall.log")));
}
// uninstall Myrtille PDF printer, if exists
var scribeInstaller = new PdfScribeInstaller(Context);
scribeInstaller.UninstallPdfScribePrinter();
Context.LogMessage("Uninstalled Myrtille.Services");
}
catch (Exception exc)
{
// in case of any error, don't rethrow the exception or myrtille won't be uninstalled otherwise (rollback action)
// if myrtille can't be uninstalled, it can't be re-installed either! (at least, with an installer of the same product code)
Context.LogMessage(string.Format("Failed to uninstall Myrtille.Services ({0})", exc));
}
}
}
}