Files
PowerShell/host/main.cpp
T

153 lines
4.9 KiB
C++
Raw Normal View History

#include <unistd.h>
#include <string>
#include <iostream>
2015-10-25 12:03:49 -07:00
#include "coreclrutil.h"
namespace Cmdline
{
2015-10-21 15:22:57 -07:00
void printHelp()
{
2015-10-25 12:09:49 -07:00
std::cerr << "PowerShell on Linux host" << std::endl
<< "Usage: powershell assembly [...]" << std::endl
2015-10-21 15:22:57 -07:00
<< std::endl
<< "What it does:" << std::endl
2015-10-22 18:17:27 -07:00
<< "- the host assumes that CoreCLR is located $CORE_ROOT" << std::endl
<< "- the host assumes that the assembly named" << std::endl
2015-10-22 18:17:27 -07:00
<< " Microsoft.PowerShell.CoreCLR.AssemblyLoadContext is " << std::endl
<< " located in $PWRSH_ROOT" << std::endl
2015-10-21 15:22:57 -07:00
<< "- all additional parameters at the end of the command line are forwarded" << std::endl
<< " to the Main function in the assembly" << std::endl
<< "- the host will execute the Main function in the specified assembly" << std::endl
<< " + this assembly has to be located in the search path" << std::endl
<< "- the host will add $PWRSH_ROOT to the assembly search path" << std::endl
2015-10-21 15:22:57 -07:00
<< "- the function signature of the Main function that gets executed must be:" << std::endl
<< " static void Main(string[] args)" << std::endl
<< std::endl
<< "Options:" << std::endl
2015-10-22 18:17:15 -07:00
<< "-v verbose output" << std::endl
2015-10-21 15:22:57 -07:00
<< "assembly the path of the assembly to execute relative to current directory" << std::endl
<< std::endl
<< "Example:" << std::endl
2015-10-22 18:17:27 -07:00
<< "CORE_ROOT=/test/coreclr PWRSH_ROOT=/test/powershell ./host_cmdline -s /test/ps powershell-simple 'get-process'" << std::endl;
}
2015-10-21 15:22:57 -07:00
struct Args
{
2015-10-21 15:22:57 -07:00
Args() :
argc(0),
argv(nullptr),
verbose(false)
{
}
2015-10-21 15:22:57 -07:00
std::string searchPaths;
std::string entryAssemblyPath;
int argc;
char** argv;
bool verbose;
void debugPrint() const
{
std::cerr << "Args:" << std::endl
<< "- entryAssemblyPath " << entryAssemblyPath << std::endl
<< "- argc " << argc << std::endl
<< "- verbose " << (verbose ? "true" : "false") << std::endl;
}
};
// this is implemented without any 3rd party lib to keep the list
// of dependencies low
bool parseCmdline(const int argc, char** argv, Args& args)
{
2015-10-21 15:22:57 -07:00
if (argc <= 1)
{
std::cerr << "error: missing arguments" << std::endl;
return false;
}
for (int i = 1; i < argc; ++i)
{
const std::string arg = argv[i];
const bool hasNextArg = i+1 < argc;
const std::string nextArg = hasNextArg ? std::string(argv[i+1]) : std::string("");
if (hasNextArg && arg == "--File")
2015-10-21 15:22:57 -07:00
{
std::cerr << "TODO: should launch script " << nextArg << std::endl;
2015-10-21 15:22:57 -07:00
++i;
}
else if (arg == "-v")
{
args.verbose = true;
}
else if (args.entryAssemblyPath == "")
{
args.entryAssemblyPath = arg;
}
else
{
// forward command line parameters
args.argc = argc-i;
args.argv = &argv[i];
// explicitly break here because the lines above consume all remaining arguments
break;
}
}
// check for mandatory parameters
if (args.entryAssemblyPath == "")
{
std::cerr << "error: assembly_name argument missing" << std::endl;
}
return true;
}
}
int main(int argc, char** argv)
{
// parse the command line arguments
Cmdline::Args args;
if (!Cmdline::parseCmdline(argc,argv,args))
{
Cmdline::printHelp();
return 1;
}
if (args.verbose)
args.debugPrint();
// get the absolute path of the current directory
std::string cwd(getcwd(nullptr, 0));
void* hostHandle;
unsigned int domainId;
2015-10-22 13:31:22 -07:00
int status = startCoreCLR(
2015-10-21 15:22:57 -07:00
"ps_cmdline_host",
&hostHandle,
&domainId);
2015-10-23 00:01:48 -07:00
if (!SUCCEEDED(status))
{
std::cerr << "could not start CoreCLR" << std::endl;
return -1;
}
2015-10-22 18:17:27 -07:00
// call into Main of assembly
2015-08-21 16:17:16 -07:00
unsigned int exitCode;
2015-10-22 18:17:27 -07:00
executeAssembly(
hostHandle, domainId, args.argc,
(const char**)args.argv,
(cwd + "/" + args.entryAssemblyPath).c_str(),
2015-10-22 18:17:27 -07:00
&exitCode);
2015-10-22 13:31:22 -07:00
status = stopCoreCLR(hostHandle, domainId);
2015-10-23 00:01:48 -07:00
if (!SUCCEEDED(status))
{
std::cerr << "could not stop CoreCLR" << std::endl;
return -1;
}
return exitCode;
}