Improved ArkAngles Setup parser

This commit is contained in:
Michael Becker 2015-04-22 15:52:18 -04:00
parent 9910f2ba07
commit b9c247017d
10 changed files with 524 additions and 7 deletions

View File

@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using UniversalEditor.IO;
using UniversalEditor.ObjectModels.Setup.ArkAngles;
using UniversalEditor.ObjectModels.Setup.ArkAngles.Actions;
namespace UniversalEditor.DataFormats.Setup.ArkAngles
{
@ -41,6 +42,59 @@ namespace UniversalEditor.DataFormats.Setup.ArkAngles
setup.CatalogExecutableFileName = paramzLine;
break;
}
case "deletefromsfx":
{
setup.DeleteFromSFX = true;
break;
}
case "cols":
{
// top color, bottom color, title foreground, title background, title shadow offset in pixels, footer color, unknown
// ARK ANGLES picked the UGLIEST default colors for their setup program :-(
Color topColor = Colors.Cyan; // Colors.Blue;
Color bottomColor = Colors.Green; // Colors.Black;
Color titleForegroundColor = Colors.White;
Color titleBackgroundColor = Colors.Black;
int titleShadowOffset = 3;
Color footerColor = Colors.Black; // Colors.White;
Color buttonLabelColor = Colors.Black; // Colors.White;
if (paramz.Length > 0)
{
topColor = StringToColor(paramz[0]);
if (paramz.Length > 1)
{
bottomColor = StringToColor(paramz[1]);
if (paramz.Length > 2)
{
titleForegroundColor = StringToColor(paramz[2]);
if (paramz.Length > 3)
{
titleBackgroundColor = StringToColor(paramz[3]);
if (paramz.Length > 4)
{
titleShadowOffset = Int32.Parse(paramz[4]);
if (paramz.Length > 5)
{
footerColor = StringToColor(paramz[5]);
if (paramz.Length > 6)
{
buttonLabelColor = StringToColor(paramz[6]);
}
}
}
}
}
}
}
break;
}
case "dir":
{
setup.DefaultInstallationDirectory = paramzLine;
break;
}
case "doc":
{
// NOTE: the DOC command is found in install.set (DOS) but not
@ -48,6 +102,31 @@ namespace UniversalEditor.DataFormats.Setup.ArkAngles
setup.DocumentationFileName = paramzLine;
break;
}
case "function":
{
for (int i = 0; i < paramzLine.Length; i++)
{
switch (paramzLine[i])
{
case 'I':
{
setup.AutoStartCommands.Add(AutoStartCommand.Install);
break;
}
case 'C':
{
setup.AutoStartCommands.Add(AutoStartCommand.Catalog);
break;
}
case 'X':
{
setup.AutoStartCommands.Add(AutoStartCommand.Exit);
break;
}
}
}
break;
}
case "msg":
case "footer":
{
@ -70,11 +149,112 @@ namespace UniversalEditor.DataFormats.Setup.ArkAngles
}
}
}
}
protected override void SaveInternal(ObjectModel objectModel)
{
SetupObjectModel setup = (objectModel as SetupObjectModel);
if (setup == null) throw new ObjectModelNotSupportedException();
Writer writer = base.Accessor.Writer;
if (!String.IsNullOrEmpty(setup.Title)) writer.WriteLine("TITLE " + setup.Title);
if (setup.HeaderFontSize != null) writer.WriteLine("HEADFONT " + setup.HeaderFontSize.Value.ToString());
if (!String.IsNullOrEmpty(setup.FooterText)) writer.WriteLine("FOOTER " + setup.FooterText);
// not sure what ICON line does
if (!String.IsNullOrEmpty(setup.CatalogExecutableFileName)) writer.WriteLine("CATALOG " + setup.CatalogExecutableFileName);
// COLS
if (!String.IsNullOrEmpty(setup.DefaultInstallationDirectory)) writer.WriteLine("DIR " + setup.DefaultInstallationDirectory);
if (setup.DeleteFromSFX) writer.WriteLine("DELETEFROMSFX");
foreach (UniversalEditor.ObjectModels.Setup.ArkAngles.Action action in setup.Actions)
{
if (action is FileAction)
{
FileAction act = (action as FileAction);
writer.WriteLine("INSTALL " + act.SourceFileName + "," + act.DestinationFileName + ",4," + act.FileSize.ToString() + ",,," + act.Description);
}
else if (action is FontAction)
{
FontAction act = (action as FontAction);
writer.WriteLine("FONT " + act.Title + "," + act.FileName);
}
else if (action is ProgramGroupAction)
{
ProgramGroupAction act = (action as ProgramGroupAction);
writer.WriteLine("GROUP " + act.Title);
foreach (ProgramGroupShortcut item in act.Shortcuts)
{
writer.Write("ITEM " + item.FileName + "," + item.Title);
if (!String.IsNullOrEmpty(item.IconFileName) || item.IconIndex != null)
{
writer.Write(",");
if (!String.IsNullOrEmpty(item.IconFileName)) writer.Write(item.IconFileName);
if (item.IconIndex != null)
{
writer.Write(",");
writer.Write(item.IconIndex.Value.ToString());
}
}
writer.WriteLine();
}
}
}
writer.WriteLine();
if (setup.AutoStartCommands.Count > 0)
{
writer.Write("FUNCTION ");
foreach (AutoStartCommand cmd in setup.AutoStartCommands)
{
if (cmd == AutoStartCommand.Catalog) writer.Write("C");
if (cmd == AutoStartCommand.Exit) writer.Write("X");
if (cmd == AutoStartCommand.Install) writer.Write("I");
if (cmd == AutoStartCommand.Restart) writer.Write("S");
}
writer.WriteLine();
}
if (setup.RestartAfterInstallation)
{
writer.WriteLine("RESTART 1");
}
else
{
writer.WriteLine("RESTART 0");
}
if (!String.IsNullOrEmpty(setup.LogFileName))
{
writer.WriteLine("LOG " + setup.LogFileName);
}
}
private Color StringToColor(string colorStr)
{
if (!colorStr.StartsWith("$")) throw new ArgumentException("Color string must be a hexadecimal number beginning with $, like $A0B1C2");
colorStr = colorStr.Substring(1);
// $bbggrr format (delphi, perhaps?)
string blueStr = colorStr.Substring(0, 2);
string greenStr = colorStr.Substring(2, 2);
string redStr = colorStr.Substring(4, 2);
Color color = new Color();
color.Red = ((double)Int32.Parse(redStr) / 255);
color.Green = ((double)Int32.Parse(greenStr) / 255);
color.Blue = ((double)Int32.Parse(blueStr) / 255);
return color;
}
private string ColorToString(Color color)
{
StringBuilder sb = new StringBuilder();
sb.Append("$");
sb.Append(color.Red.ToString("X").ToLower().PadLeft(2, '0'));
sb.Append(color.Green.ToString("X").ToLower().PadLeft(2, '0'));
sb.Append(color.Blue.ToString("X").ToLower().PadLeft(2, '0'));
return sb.ToString();
}
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.ObjectModels.Setup.ArkAngles
{
public abstract class Action : ICloneable
{
public class ActionCollection
: System.Collections.ObjectModel.Collection<Action>
{
}
public abstract object Clone();
}
}

View File

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.ObjectModels.Setup.ArkAngles.Actions
{
public class FileAction : Action
{
private string mvarSourceFileName = String.Empty;
/// <summary>
/// The location of the source file to copy.
/// </summary>
public string SourceFileName { get { return mvarSourceFileName; } set { mvarSourceFileName = value; } }
private string mvarDestinationFileName = String.Empty;
/// <summary>
/// The location in which to place the copied file. If a directory is specified, the file name from the source file will be used.
/// </summary>
public string DestinationFileName { get { return mvarDestinationFileName; } set { mvarDestinationFileName = value; } }
private int mvarFileSize = 0;
/// <summary>
/// The size of the file on disk.
/// </summary>
public int FileSize { get { return mvarFileSize; } set { mvarFileSize = value; } }
private string mvarDescription = String.Empty;
public string Description { get { return mvarDescription; } set { mvarDescription = value; } }
public override object Clone()
{
FileAction clone = new FileAction();
clone.Description = (mvarDescription.Clone() as string);
clone.DestinationFileName = (mvarDestinationFileName.Clone() as string);
clone.FileSize = mvarFileSize;
clone.SourceFileName = (mvarSourceFileName.Clone() as string);
return clone;
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.ObjectModels.Setup.ArkAngles.Actions
{
/// <summary>
/// Installs a font to the user's computer.
/// </summary>
public class FontAction : Action
{
private string mvarFileName = String.Empty;
/// <summary>
/// The file name of the font to install.
/// </summary>
public string FileName { get { return mvarFileName; } set { mvarFileName = value; } }
private string mvarTitle = String.Empty;
/// <summary>
/// The title of the font to install.
/// </summary>
public string Title { get { return mvarTitle; } set { mvarTitle = value; } }
public override object Clone()
{
FontAction clone = new FontAction();
clone.FileName = (mvarFileName.Clone() as string);
clone.Title = (mvarTitle.Clone() as string);
return clone;
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.ObjectModels.Setup.ArkAngles.Actions
{
public class ProgramGroupAction : Action
{
private string mvarTitle = String.Empty;
/// <summary>
/// The title of the Program Group to create.
/// </summary>
public string Title { get { return mvarTitle; } set { mvarTitle = value; } }
private ProgramGroupShortcut.ProgramGroupShortcutCollection mvarShortcuts = new ProgramGroupShortcut.ProgramGroupShortcutCollection();
/// <summary>
/// The shortcuts added to this Program Group.
/// </summary>
public ProgramGroupShortcut.ProgramGroupShortcutCollection Shortcuts { get { return mvarShortcuts; } }
public override object Clone()
{
ProgramGroupAction clone = new ProgramGroupAction();
foreach (ProgramGroupShortcut item in mvarShortcuts)
{
clone.Shortcuts.Add(item.Clone() as ProgramGroupShortcut);
}
clone.Title = (mvarTitle.Clone() as string);
return clone;
}
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.ObjectModels.Setup.ArkAngles.Actions
{
public class PromptAction
{
private int mvarOrder = 0;
/// <summary>
/// 9 = before install directory, 11 = after install directory
/// </summary>
public int Order { get { return mvarOrder; } set { mvarOrder = value; } }
private string mvarTitle = String.Empty;
public string Title { get { return mvarTitle; } set { mvarTitle = value; } }
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.ObjectModels.Setup.ArkAngles
{
public class AutoStartCommand
{
private char _key = '\0';
private AutoStartCommand(char _key)
{
}
private static AutoStartCommand m_Install = new AutoStartCommand('I');
/// <summary>
/// Installs the application.
/// </summary>
public static AutoStartCommand Install { get { return m_Install; } }
private static AutoStartCommand m_Catalog = new AutoStartCommand('C');
/// <summary>
/// Displays the product catalog.
/// </summary>
public static AutoStartCommand Catalog { get { return m_Catalog; } }
private static AutoStartCommand m_Exit = new AutoStartCommand('X');
/// <summary>
/// Exits the Setup program.
/// </summary>
public static AutoStartCommand Exit { get { return m_Exit; } }
private static AutoStartCommand m_Restart = new AutoStartCommand('S');
/// <summary>
/// Restarts the operating system (actually just logs you off and back on again under Win2k).
/// </summary>
public static AutoStartCommand Restart { get { return m_Restart; } }
public class AutoStartCommandCollection
: System.Collections.ObjectModel.Collection<AutoStartCommand>
{
}
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.ObjectModels.Setup.ArkAngles
{
public class ProgramGroupShortcut : ICloneable
{
public class ProgramGroupShortcutCollection
: System.Collections.ObjectModel.Collection<ProgramGroupShortcut>
{
}
private string mvarTitle = String.Empty;
public string Title { get { return mvarTitle; } set { mvarTitle = value; } }
private string mvarFileName = String.Empty;
public string FileName { get { return mvarFileName; } set { mvarFileName = value; } }
private string mvarIconFileName = null;
/// <summary>
/// The file name of the icon to display in the shortcut.
/// </summary>
public string IconFileName { get { return mvarIconFileName; } set { mvarIconFileName = value; } }
private int? mvarIconIndex = null;
/// <summary>
/// The index of the icon to display in the shortcut.
/// </summary>
public int? IconIndex { get { return mvarIconIndex; } set { mvarIconIndex = value; } }
public object Clone()
{
ProgramGroupShortcut clone = new ProgramGroupShortcut();
clone.FileName = (mvarFileName.Clone() as string);
clone.IconFileName = (mvarIconFileName.Clone() as string);
clone.IconIndex = mvarIconIndex;
clone.Title = (mvarTitle.Clone() as string);
return clone;
}
}
}

View File

@ -7,32 +7,126 @@ namespace UniversalEditor.ObjectModels.Setup.ArkAngles
{
public class SetupObjectModel : ObjectModel
{
private static ObjectModelReference _omr = null;
protected override ObjectModelReference MakeReferenceInternal()
{
if (_omr == null)
{
_omr = base.MakeReferenceInternal();
_omr.Title = "Setup Script";
_omr.Path = new string[] { "Setup", "Ark Angles" };
}
return _omr;
}
private Action.ActionCollection mvarActions = new Action.ActionCollection();
/// <summary>
/// The actions taken during the installation process.
/// </summary>
public Action.ActionCollection Actions { get { return mvarActions; } }
private AutoStartCommand.AutoStartCommandCollection mvarAutoStartCommands = new AutoStartCommand.AutoStartCommandCollection();
/// <summary>
/// The commands to execute automatically when the setup program is launched.
/// </summary>
public AutoStartCommand.AutoStartCommandCollection AutoStartCommands { get { return mvarAutoStartCommands; } }
private string mvarCatalogExecutableFileName = String.Empty;
/// <summary>
/// The file name of the catalog executable to launch via the "Catalog" button. If this value is empty, the "Catalog" button is not displayed.
/// </summary>
public string CatalogExecutableFileName { get { return mvarCatalogExecutableFileName; } set { mvarCatalogExecutableFileName = value; } }
private string mvarDefaultInstallationDirectory = String.Empty;
/// <summary>
/// The default installation directory for this application.
/// </summary>
public string DefaultInstallationDirectory { get { return mvarDefaultInstallationDirectory; } set { mvarDefaultInstallationDirectory = value; } }
private bool mvarDeleteFromSFX = false;
/// <summary>
/// Determines whether the Setup program and its related files are deleted when the installation exits, regardless of success or failure.
/// </summary>
public bool DeleteFromSFX { get { return mvarDeleteFromSFX; } set { mvarDeleteFromSFX = value; } }
private string mvarDocumentationFileName = String.Empty;
/// <summary>
///
/// </summary>
public string DocumentationFileName { get { return mvarDocumentationFileName; } set { mvarDocumentationFileName = value; } }
private int? mvarFooterFontSize = null; // default ??
/// <summary>
/// The size of the font used for the footer of the installation program.
/// </summary>
public int? FooterFontSize { get { return mvarFooterFontSize; } set { mvarFooterFontSize = value; } }
private string mvarFooterText = String.Empty;
/// <summary>
/// The text to display at the bottom of the installer background window.
/// </summary>
public string FooterText { get { return mvarFooterText; } set { mvarFooterText = value; } }
private int? mvarHeaderFontSize = null; // default 23, KCHESS uses 48
/// <summary>
/// The size of the font used for the header of the installation program.
/// </summary>
public int? HeaderFontSize { get { return mvarHeaderFontSize; } set { mvarHeaderFontSize = value; } }
private string mvarLogFileName = String.Empty;
/// <summary>
/// The file name of the installation log to create upon installation.
/// </summary>
public string LogFileName { get { return mvarLogFileName; } set { mvarLogFileName = value; } }
private bool mvarRestartAfterInstallation = false;
/// <summary>
/// Determines whether the Restart command should be presented after installation (or the installer
/// should automatically restart the operating system if the AutoStartCommand.Restart is present).
/// </summary>
public bool RestartAfterInstallation { get { return mvarRestartAfterInstallation; } set { mvarRestartAfterInstallation = value; } }
private string mvarTitle = String.Empty;
public string Title { get { return mvarTitle; } set { mvarTitle = value; } }
public override void Clear()
{
throw new NotImplementedException();
mvarActions.Clear();
mvarAutoStartCommands.Clear();
mvarCatalogExecutableFileName = String.Empty;
mvarDefaultInstallationDirectory = String.Empty;
mvarDeleteFromSFX = false;
mvarDocumentationFileName = String.Empty;
mvarFooterFontSize = null;
mvarFooterText = String.Empty;
mvarHeaderFontSize = null;
mvarLogFileName = String.Empty;
mvarRestartAfterInstallation = false;
mvarTitle = String.Empty;
}
public override void CopyTo(ObjectModel where)
{
throw new NotImplementedException();
SetupObjectModel clone = (where as SetupObjectModel);
if (clone == null) throw new ObjectModelNotSupportedException();
foreach (Action action in mvarActions)
{
clone.Actions.Add(action.Clone() as Action);
}
foreach (AutoStartCommand cmd in mvarAutoStartCommands)
{
clone.AutoStartCommands.Add(cmd);
}
clone.CatalogExecutableFileName = (mvarCatalogExecutableFileName.Clone() as string);
clone.DefaultInstallationDirectory = (mvarDefaultInstallationDirectory.Clone() as string);
clone.DeleteFromSFX = mvarDeleteFromSFX;
clone.DocumentationFileName = (mvarDocumentationFileName.Clone() as string);
clone.FooterFontSize = mvarFooterFontSize;
clone.FooterText = (mvarFooterText.Clone() as string);
clone.HeaderFontSize = mvarHeaderFontSize;
clone.LogFileName = (mvarLogFileName.Clone() as string);
clone.RestartAfterInstallation = mvarRestartAfterInstallation;
clone.Title = (mvarTitle.Clone() as string);
}
}
}

View File

@ -35,6 +35,13 @@
</ItemGroup>
<ItemGroup>
<Compile Include="DataFormats\Setup\ArkAngles\SETDataFormat.cs" />
<Compile Include="ObjectModels\Setup\ArkAngles\Action.cs" />
<Compile Include="ObjectModels\Setup\ArkAngles\Actions\FileAction.cs" />
<Compile Include="ObjectModels\Setup\ArkAngles\Actions\FontAction.cs" />
<Compile Include="ObjectModels\Setup\ArkAngles\Actions\ProgramGroupAction.cs" />
<Compile Include="ObjectModels\Setup\ArkAngles\Actions\PromptAction.cs" />
<Compile Include="ObjectModels\Setup\ArkAngles\AutoStartCommand.cs" />
<Compile Include="ObjectModels\Setup\ArkAngles\ProgramGroupShortcut.cs" />
<Compile Include="ObjectModels\Setup\ArkAngles\SetupObjectModel.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
@ -47,10 +54,12 @@
<Project>{30467e5c-05bc-4856-aadc-13906ef4cadd}</Project>
<Name>UniversalEditor.Essential</Name>
</ProjectReference>
<ProjectReference Include="..\UniversalEditor.Plugins.Multimedia\UniversalEditor.Plugins.Multimedia.csproj">
<Project>{be4d0ba3-0888-42a5-9c09-fc308a4509d2}</Project>
<Name>UniversalEditor.Plugins.Multimedia</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="ObjectModels\Setup\ArkAngles\Actions\" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.