Exemple #1
0
        public static Collection <PSObject> CompileStandard(CallerProxy caller, string sourceFile, string outputName, ApplicationData appdata)
        {
            caller.WriteVerbose("Setting up working directory..");
            string tempDir = Path.Combine(Path.GetTempPath(), "SPSH--" + Guid.NewGuid().ToString());

            Directory.CreateDirectory(tempDir);

            return(Compile(caller, sourceFile, outputName, appdata, tempDir));
        }
Exemple #2
0
        private static Collection <PSObject> Compile(CallerProxy caller, string sourceFile, string outputName, ApplicationData appdata, string tempDir)
        {
            // Make a manifest
            StringBuilder        manifestContent = new StringBuilder();
            List <ParameterItem> parameters      = new List <ParameterItem>();

            // Get some common metadata from the registry

            // Create list of all assemblies that needs to be embedded into code
            caller.WriteVerbose("Loading assemblies..");
            List <string> assemblyList = new List <string>();

            assemblyList.Add(GetDLLLocation("System"));
            assemblyList.Add(GetDLLLocation("System.Management"));
            assemblyList.Add(GetDLLLocation("System.Management.Automation"));
            assemblyList.Add(GetDLLLocation("System.Windows.Forms"));
            if (appdata.GetType() == typeof(ServiceData))
            {
                assemblyList.Add(GetDLLLocation("System.ServiceProcess"));
                assemblyList.Add(GetDLLLocation("System.Configuration.Install"));
            }
            if (appdata.Framework == Framework.Framework40)
            {
                assemblyList.Add(GetDLLLocation("System.Core"));
            }
            foreach (string assName in appdata.AdditionalAssemblies)
            {
                assemblyList.Add(GetDLLLocation(assName));
            }


            // Setup the compiller
            caller.WriteVerbose("Configuring compiler..");
            CompilerParameters compilerParameters = new CompilerParameters(assemblyList.ToArray(), outputName, appdata.DebugBuild);

            compilerParameters.TempFiles          = new TempFileCollection(tempDir, appdata.DebugBuild);
            compilerParameters.GenerateExecutable = true;
            compilerParameters.GenerateInMemory   = false;

            if (appdata.Icon == null)
            {
                compilerParameters.CompilerOptions = string.Format(" /platform:{1} /target:{0} /optimize", (appdata.GetType() == typeof(ServiceData)) || appdata.HideConsole ? "winexe" : "exe", appdata.Platform);
            }
            else
            {
                caller.WriteVerbose("Creating icon..");
                string iconPath = Path.Combine(tempDir, "app.ico");

                IntPtr     hiconPtr   = appdata.Icon.GetHicon();
                Icon       realIcon   = Icon.FromHandle(hiconPtr);
                FileStream iconStream = new System.IO.FileStream(iconPath, FileMode.OpenOrCreate);
                realIcon.Save(iconStream);
                iconStream.Close();
                USER32.DestroyIcon(hiconPtr);

                compilerParameters.CompilerOptions = string.Format(" /platform:{2} /target:{1} /win32icon:{0} /optimize", iconPath, (appdata.GetType() == typeof(ServiceData)) || appdata.HideConsole ? "winexe" : "exe", appdata.Platform);
            }


            // embedding script,core and modules
            caller.WriteVerbose("Embedding resources..");
            if (appdata.EmbedCore)
            {
                caller.WriteVerbose("Get core-dll..");
                Collection <PSObject> modulePathResult = caller.InvokeScript("(Get-Module -All Sorlov.Powershell).Path");
                if (modulePathResult.Count == 1)
                {
                    manifestContent.AppendLine(EmbedResource(compilerParameters, modulePathResult[0].ToString(), tempDir, "CoreDLL", "Module"));
                }
            }

            caller.WriteVerbose("Embedding extra resources..");
            {
                foreach (string extraResource in appdata.AdditionalFiles)
                {
                    manifestContent.AppendLine(EmbedResource(compilerParameters, extraResource, tempDir, Path.GetFileName(extraResource), "Copy"));
                }
            }

            caller.WriteVerbose("Get script data..");
            if (sourceFile != string.Empty)
            {
                manifestContent.AppendLine(EmbedResource(compilerParameters, sourceFile, tempDir, "ScriptData", "Script"));
            }

            string scriptName;

            if (sourceFile != string.Empty)
            {
                scriptName = System.IO.Path.GetFileName(sourceFile);
            }

            caller.WriteVerbose("Processing arguments..");
            ScriptBlock scriptToProcess = ScriptBlock.Create(File.ReadAllText(sourceFile));
            List <Ast>  paramBlockList  = scriptToProcess.Ast.FindAll(ast1 => ast1.GetType() == typeof(ParamBlockAst), false).ToList();

            List <string> supportedTypes = new List <string>()
            {
                "byte", "sbyte", "short", "ushort", "int", "uint", "ulong", "long", "float", "double", "decimal", "char", "switch", "bool", "boolean", "string"
            };

            if (paramBlockList.Count > 0)
            {
                ParamBlockAst paramBlock = paramBlockList[0] as ParamBlockAst;
                foreach (ParameterAst param in paramBlock.Parameters)
                {
                    string name        = param.Name.ToString().Substring(1);
                    string helpMessage = string.Empty;
                    bool   mandatory   = false;
                    string type        = "string";
                    foreach (AttributeBaseAst attributeAst in param.Attributes)
                    {
                        if (attributeAst.GetType() == typeof(AttributeAst))
                        {
                            foreach (NamedAttributeArgumentAst namedArgumentAst in ((AttributeAst)attributeAst).NamedArguments)
                            {
                                if (namedArgumentAst.ArgumentName.ToLower() == "helpmessage")
                                {
                                    helpMessage = namedArgumentAst.Argument.ToString();
                                }
                                if (namedArgumentAst.ArgumentName.ToLower() == "mandatory")
                                {
                                    mandatory = bool.Parse(namedArgumentAst.Argument.ToString().Replace("{", "").Replace("}", "").Replace("$", ""));
                                }
                            }
                        }
                        if (attributeAst.GetType() == typeof(TypeConstraintAst))
                        {
                            type = attributeAst.ToString().Replace("[", "").Replace("]", "").ToLower();
                            if (!supportedTypes.Contains(type))
                            {
                                caller.WriteWarning(string.Format("Argument '{0}' is of an unsupported type ({1}). Might not work or maybe it will. Who knows?", name, type));
                            }
                        }
                    }
                    parameters.Add(new ParameterItem(name, helpMessage, mandatory, type));
                }
            }



            caller.WriteVerbose("Get external modules..");
            if (appdata.EmbedModules != null)
            {
                foreach (PSModuleInfo module in appdata.EmbedModules)
                {
                    EmbedModule(module, compilerParameters, tempDir, manifestContent);
                }
            }

            caller.WriteVerbose("Creating manifest..");
            EmbedTextResource(compilerParameters, tempDir, manifestContent.ToString(), "Manifest");


            caller.WriteVerbose("Loading compiler..");
            Dictionary <string, string> providerOptions = new Dictionary <string, string>();

            providerOptions.Add("CompilerVersion", string.Format("v{0}", appdata.Framework.GetEnumDescription()));
            CSharpCodeProvider cSharpProvider = new CSharpCodeProvider(providerOptions);

            caller.WriteVerbose("Constructing assembly info..");
            string assemblyInfo    = Resources.SelfHostedPS.AssemblyInfo;
            string assemblyCulture = appdata.LCID == 0 ? System.Globalization.CultureInfo.InvariantCulture.Name : System.Globalization.CultureInfo.GetCultureInfo(appdata.LCID).Name;

            assemblyInfo = assemblyInfo.Replace("$COPYRIGHT$", string.Format("© {0} {1}, All rights reserved.", DateTime.Now.Year, appdata.PublisherOrganization == string.Empty ? appdata.PublisherName : appdata.PublisherOrganization));
            assemblyInfo = assemblyInfo.Replace("$DESCRIPTION$", string.Format("{0};{1};{2};{3};{4};{5}", DateTime.Now, System.Security.Principal.WindowsIdentity.GetCurrent().Name, appdata.PublisherOrganization, appdata.PublisherName, Assembly.GetExecutingAssembly().GetName().Version, (appdata.GetType() == typeof(ServiceData))));
            assemblyInfo = assemblyInfo.Replace("$VERSION$", appdata.Version.ToString());
            assemblyInfo = assemblyInfo.Replace("$SCRIPTNAME$", appdata.ApplicationName);
            assemblyInfo = assemblyInfo.Replace("$COMPANY$", appdata.PublisherOrganization == string.Empty ? appdata.PublisherName : appdata.PublisherOrganization);
            assemblyInfo = assemblyInfo.Replace("$CULTURENAME$", assemblyCulture);
            assemblyInfo = assemblyInfo.Replace("//[", "[");
            assemblyInfo = assemblyInfo.Replace("\\", "\\\\");

            caller.WriteVerbose("Collecting code..");
            List <string> codeList = new List <string>();

            codeList.Add(assemblyInfo);
            codeList.Add(Resources.SelfHostedPS.Host);
            codeList.Add(Resources.SelfHostedPS.HostRawUserInterface);
            codeList.Add(Resources.SelfHostedPS.HostUserInterface);
            codeList.Add(Resources.SelfHostedPS.Common);
            codeList.Add(Resources.SelfHostedPS.ConsoleHandler);
            codeList.Add(Resources.SelfHostedPS.Commandline);

            caller.WriteVerbose("Making program adjustments..");
            if (appdata.ReplaceProgram == string.Empty)
            {
                if ((appdata.GetType() == typeof(ServiceData)))
                {
                    codeList.Add(Resources.SelfHostedPS.IntegratedServiceInstaller);

                    string serviceProgram = Resources.SelfHostedPS.ServiceProgram;
                    if (appdata.Mode.ToString() == "STA")
                    {
                        serviceProgram = serviceProgram.Replace("[MTAThread]", "[STAThread]");
                    }
                    if (appdata.LCID != 0)
                    {
                        serviceProgram = serviceProgram.Replace("System.Globalization.CultureInfo.InvariantCulture", string.Format("System.Globalization.CultureInfo.GetCultureInfo({0})", appdata.LCID));
                    }
                    codeList.Add(serviceProgram);

                    string serviceCode = Resources.SelfHostedPS.PSService;
                    if (appdata.Mode.ToString() == "STA")
                    {
                        serviceCode = serviceCode.Replace("System.Threading.ApartmentState.MTA", "System.Threading.ApartmentState.STA");
                    }
                    serviceCode = serviceCode.Replace("$SERVICENAME$", ((ServiceData)appdata).ServiceName);
                    serviceCode = serviceCode.Replace("$DISPLAYNAME$", ((ServiceData)appdata).DisplayName);
                    serviceCode = serviceCode.Replace("$DESCRIPTION$", ((ServiceData)appdata).Description);
                    codeList.Add(serviceCode);
                }
                else
                {
                    codeList.Add(Resources.SelfHostedPS.ParameterItem);
                    codeList.Add(Resources.SelfHostedPS.AssemblyData);



                    string programCode = Resources.SelfHostedPS.Program;
                    if (appdata.LCID != 0)
                    {
                        programCode = programCode.Replace("System.Globalization.CultureInfo.InvariantCulture", string.Format("System.Globalization.CultureInfo.GetCultureInfo({0})", appdata.LCID));
                    }
                    if (appdata.Mode.ToString() == "STA")
                    {
                        programCode = programCode.Replace("[MTAThread]", "[STAThread]").Replace("System.Threading.ApartmentState.MTA", "System.Threading.ApartmentState.STA");
                    }
                    if (appdata.HideConsole == true)
                    {
                        programCode = programCode.Replace("hideCon = false", "hideCon = true");
                    }

                    if (parameters.Count > 0)
                    {
                        StringBuilder appendCode = new StringBuilder();
                        foreach (ParameterItem parameter in parameters)
                        {
                            appendCode.AppendFormat("validCmds.Add(new ParameterItem(\"{0}\", \"{1}\", {2}, \"{3}\"));\n", parameter.Name.Replace("\"", "").Replace("'", ""), parameter.HelpText.Replace("\"", "").Replace("'", ""), parameter.Mandatory.ToString().ToLower(), parameter.Type);
                        }

                        programCode = programCode.Replace("//AddValidCommands", appendCode.ToString());
                    }
                    else
                    {
                        programCode = programCode.Replace("//AddValidCommands", "");
                    }

                    codeList.Add(programCode);
                }
            }
            else
            {
                string programCode = appdata.ReplaceProgram;
                if (appdata.LCID != 0)
                {
                    programCode = programCode.Replace("System.Globalization.CultureInfo.InvariantCulture", string.Format("System.Globalization.CultureInfo.GetCultureInfo({0})", appdata.LCID));
                }
                if (appdata.Mode.ToString() == "STA")
                {
                    programCode = programCode.Replace("[MTAThread]", "[STAThread]").Replace("System.Threading.ApartmentState.MTA", "System.Threading.ApartmentState.STA");
                }
                if (appdata.HideConsole == true)
                {
                    programCode = programCode.Replace("hideCon = false", "hideCon = true");
                }
                codeList.Add(programCode);
            }

            foreach (string additionalCode in appdata.AdditionalCode)
            {
                codeList.Add(additionalCode);
            }

            caller.WriteVerbose("Compiling..");
            CompilerResults results = cSharpProvider.CompileAssemblyFromSource(compilerParameters, codeList.ToArray());

            if (results.Errors.Count > 0)
            {
                foreach (CompilerError error in results.Errors)
                {
                    if (error.IsWarning)
                    {
                        caller.WriteWarning(string.Format("({0}): {1}, at {2} line {3}", error.ErrorNumber, error.ErrorText, error.FileName, error.Line));
                    }
                    else
                    {
                        caller.WriteError(new ErrorRecord(new Exception(error.ErrorText), error.ErrorNumber, ErrorCategory.NotSpecified, error));
                    }
                }
            }



            if (!appdata.DebugBuild)
            {
                caller.WriteVerbose("Deleting temporary files..");

                foreach (string fileName in Directory.GetFiles(tempDir))
                {
                    File.Delete(fileName);
                }

                Directory.Delete(tempDir);
            }

            if (appdata.SigningInformation != null)
            {
                try
                {
                    caller.WriteVerbose("Signing file..");

                    if (appdata.SigningInformation.Certificate == null)
                    {
                        caller.WriteVerbose("No certificate specified, will try to auto-find code-signing certificate in local store..");
                    }

                    if (appdata.SigningInformation.TimestampServer == string.Empty)
                    {
                        caller.WriteVerbose("No time-stamping server specified, will try to use default..");
                    }

                    SignatureHelper.SetFileSignature(outputName, appdata.SigningInformation.Certificate, appdata.SigningInformation.TimestampServer);
                }
                catch (Exception e)
                {
                    caller.ThrowTerminatingError(new ErrorRecord(new PSSecurityException("Could not sign file", e), "200", ErrorCategory.InvalidOperation, null));
                    File.Delete(outputName);
                }
            }

            return(caller.InvokeScript(string.Format("Get-SelfHostedPS -Path \"{0}\"", outputName)));
        }