// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
namespace WixToolset.Mba.Core
{
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
///
/// Default implementation of .
///
public sealed class BootstrapperCommand : IBootstrapperCommand
{
private readonly string commandLine;
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
public BootstrapperCommand(
LaunchAction action,
Display display,
Restart restart,
string commandLine,
int cmdShow,
ResumeType resume,
IntPtr splashScreen,
RelationType relation,
bool passthrough,
string layoutDirectory,
string bootstrapperWorkingFolder,
string bootstrapperApplicationDataPath)
{
this.Action = action;
this.Display = display;
this.Restart = restart;
this.commandLine = commandLine;
this.CmdShow = cmdShow;
this.Resume = resume;
this.SplashScreen = splashScreen;
this.Relation = relation;
this.Passthrough = passthrough;
this.LayoutDirectory = layoutDirectory;
this.BootstrapperWorkingFolder = bootstrapperWorkingFolder;
this.BootstrapperApplicationDataPath = bootstrapperApplicationDataPath;
}
///
public LaunchAction Action { get; }
///
public Display Display { get; }
///
public Restart Restart { get; }
///
public string[] CommandLineArgs => GetCommandLineArgs(this.commandLine);
///
public int CmdShow { get; }
///
public ResumeType Resume { get; }
///
public IntPtr SplashScreen { get; }
///
public RelationType Relation { get; }
///
public bool Passthrough { get; }
///
public string LayoutDirectory { get; }
///
public string BootstrapperWorkingFolder { get; }
///
public string BootstrapperApplicationDataPath { get; }
///
/// Gets the command line arguments as a string array.
///
///
/// Array of command line arguments.
///
/// The command line could not be parsed into an array.
///
/// This method uses the same parsing as the operating system which handles quotes and spaces correctly.
///
public static string[] GetCommandLineArgs(string commandLine)
{
if (null == commandLine)
{
return new string[0];
}
// Parse the filtered command line arguments into a native array.
int argc = 0;
// CommandLineToArgvW tries to treat the first argument as the path to the process,
// which fails pretty miserably if your first argument is something like
// FOO="C:\Program Files\My Company". So give it something harmless to play with.
IntPtr argv = NativeMethods.CommandLineToArgvW("ignored " + commandLine, out argc);
if (IntPtr.Zero == argv)
{
// Throw an exception with the last error.
throw new Win32Exception();
}
// Marshal each native array pointer to a managed string.
try
{
// Skip "ignored" argument/hack.
string[] args = new string[argc - 1];
for (int i = 1; i < argc; ++i)
{
IntPtr argvi = Marshal.ReadIntPtr(argv, i * IntPtr.Size);
args[i - 1] = Marshal.PtrToStringUni(argvi);
}
return args;
}
finally
{
NativeMethods.LocalFree(argv);
}
}
}
}