예제 #1
0
        internal static Hashtable GetModuleManifestProperties(string psDataFilePath, string[] keys)
        {
            string dataFileContents = ScriptAnalysis.ReadScript(psDataFilePath);

            ParseError[] parseErrors;
            var          ast = (new Parser()).Parse(psDataFilePath, dataFileContents, null, out parseErrors, ParseMode.ModuleAnalysis);

            if (parseErrors.Length > 0)
            {
                var pe = new ParseException(parseErrors);
                throw PSTraceSource.NewInvalidOperationException(
                          pe,
                          ParserStrings.CannotLoadPowerShellDataFile,
                          psDataFilePath,
                          pe.Message);
            }

            string unused1;
            string unused2;
            var    pipeline = ast.GetSimplePipeline(false, out unused1, out unused2);

            if (pipeline != null)
            {
                var hashtableAst = pipeline.GetPureExpression() as HashtableAst;
                if (hashtableAst != null)
                {
                    var result = new Hashtable(StringComparer.OrdinalIgnoreCase);
                    foreach (var pair in hashtableAst.KeyValuePairs)
                    {
                        var key = pair.Item1 as StringConstantExpressionAst;
                        if (key != null && keys.Contains(key.Value, StringComparer.OrdinalIgnoreCase))
                        {
                            try
                            {
                                var val = pair.Item2.SafeGetValue();
                                result[key.Value] = val;
                            }
                            catch
                            {
                                throw PSTraceSource.NewInvalidOperationException(
                                          ParserStrings.InvalidPowerShellDataFile,
                                          psDataFilePath);
                            }
                        }
                    }

                    return(result);
                }
            }

            throw PSTraceSource.NewInvalidOperationException(
                      ParserStrings.InvalidPowerShellDataFile,
                      psDataFilePath);
        }
예제 #2
0
        private static ConcurrentDictionary <string, CommandTypes> AnalyzeScriptModule(string modulePath, ExecutionContext context, DateTime lastWriteTime)
        {
            var scriptAnalysis = ScriptAnalysis.Analyze(modulePath, context);

            if (scriptAnalysis == null)
            {
                return(null);
            }

            List <WildcardPattern> scriptAnalysisPatterns = new List <WildcardPattern>();

            foreach (string discoveredCommandFilter in scriptAnalysis.DiscoveredCommandFilters)
            {
                scriptAnalysisPatterns.Add(new WildcardPattern(discoveredCommandFilter));
            }

            var result = new ConcurrentDictionary <string, CommandTypes>(3,
                                                                         scriptAnalysis.DiscoveredExports.Count + scriptAnalysis.DiscoveredAliases.Count,
                                                                         StringComparer.OrdinalIgnoreCase);

            // Add any directly discovered exports
            foreach (var command in scriptAnalysis.DiscoveredExports)
            {
                if (SessionStateUtilities.MatchesAnyWildcardPattern(command, scriptAnalysisPatterns, true))
                {
                    if (command.IndexOfAny(InvalidCommandNameCharacters) < 0)
                    {
                        result[command] = CommandTypes.Function;
                    }
                }
            }

            // Add the discovered aliases
            foreach (var pair in scriptAnalysis.DiscoveredAliases)
            {
                var commandName = pair.Key;
                // These are already filtered
                if (commandName.IndexOfAny(InvalidCommandNameCharacters) < 0)
                {
                    result.AddOrUpdate(commandName, CommandTypes.Alias,
                                       (_, existingCommandType) => existingCommandType | CommandTypes.Alias);
                }
            }

            // Add any files in PsScriptRoot if it added itself to the path
            if (scriptAnalysis.AddsSelfToPath)
            {
                string baseDirectory = Path.GetDirectoryName(modulePath);

                try
                {
                    foreach (string item in Directory.GetFiles(baseDirectory, "*.ps1"))
                    {
                        var command = Path.GetFileNameWithoutExtension(item);
                        result.AddOrUpdate(command, CommandTypes.ExternalScript,
                                           (_, existingCommandType) => existingCommandType | CommandTypes.ExternalScript);
                    }
                }
                catch (UnauthorizedAccessException)
                {
                    // Consume this exception here
                }
            }

            var exportedClasses = new ConcurrentDictionary <string, TypeAttributes>( /*concurrency*/
                1, scriptAnalysis.DiscoveredClasses.Count, StringComparer.OrdinalIgnoreCase);

            foreach (var exportedClass in scriptAnalysis.DiscoveredClasses)
            {
                exportedClasses[exportedClass.Name] = exportedClass.TypeAttributes;
            }

            var moduleCacheEntry = new ModuleCacheEntry
            {
                ModulePath    = modulePath,
                LastWriteTime = lastWriteTime,
                Commands      = result,
                TypesAnalyzed = true,
                Types         = exportedClasses
            };

            s_cacheData.Entries[modulePath] = moduleCacheEntry;

            return(result);
        }
예제 #3
0
        internal static ScriptAnalysis Analyze(string path, ExecutionContext context)
        {
            ModuleIntrinsics.Tracer.WriteLine("Analyzing path: {0}", path);

            try
            {
                if (Utils.PathIsUnc(path) && (context.CurrentCommandProcessor.CommandRuntime != null))
                {
                    ProgressRecord analysisProgress = new ProgressRecord(0,
                                                                         Modules.ScriptAnalysisPreparing,
                                                                         string.Format(CultureInfo.InvariantCulture, Modules.ScriptAnalysisModule, path));
                    analysisProgress.RecordType = ProgressRecordType.Processing;

                    // Write the progress using a static source ID so that all
                    // analysis messages get single-threaded in the progress pane (rather than nesting).
                    context.CurrentCommandProcessor.CommandRuntime.WriteProgress(typeof(ScriptAnalysis).FullName.GetHashCode(), analysisProgress);
                }
            }
            catch (InvalidOperationException)
            {
                // This may be called when we are not allowed to write progress,
                // So eat the invalid operation
            }

            string scriptContent = ReadScript(path);

            ParseError[] errors;
            var          moduleAst = (new Parser()).Parse(path, scriptContent, null, out errors, ParseMode.ModuleAnalysis);

            // Don't bother analyzing if there are syntax errors (we don't do semantic analysis which would
            // detect other errors that we also might choose to ignore, but it's slower.)
            if (errors.Length > 0)
            {
                return(null);
            }

            ExportVisitor exportVisitor = new ExportVisitor(forCompletion: false);

            moduleAst.Visit(exportVisitor);

            var result = new ScriptAnalysis
            {
                DiscoveredClasses        = exportVisitor.DiscoveredClasses,
                DiscoveredExports        = exportVisitor.DiscoveredExports,
                DiscoveredAliases        = new Dictionary <string, string>(),
                DiscoveredModules        = exportVisitor.DiscoveredModules,
                DiscoveredCommandFilters = exportVisitor.DiscoveredCommandFilters,
                AddsSelfToPath           = exportVisitor.AddsSelfToPath
            };

            if (result.DiscoveredCommandFilters.Count == 0)
            {
                result.DiscoveredCommandFilters.Add("*");
            }
            else
            {
                // Post-process aliases, as they are not exported by default
                List <WildcardPattern> patterns = new List <WildcardPattern>();
                foreach (string discoveredCommandFilter in result.DiscoveredCommandFilters)
                {
                    patterns.Add(WildcardPattern.Get(discoveredCommandFilter, WildcardOptions.IgnoreCase));
                }

                foreach (var pair in exportVisitor.DiscoveredAliases)
                {
                    string discoveredAlias = pair.Key;
                    if (SessionStateUtilities.MatchesAnyWildcardPattern(discoveredAlias, patterns, defaultValue: false))
                    {
                        result.DiscoveredAliases[discoveredAlias] = pair.Value;
                    }
                }
            }

            return(result);
        }
예제 #4
0
        internal static ScriptAnalysis Analyze(string path, ExecutionContext context)
        {
            ModuleIntrinsics.Tracer.WriteLine("Analyzing path: {0}", path);

            try
            {
                if (Utils.PathIsUnc(path) && (context.CurrentCommandProcessor.CommandRuntime != null))
                {
                    ProgressRecord analysisProgress = new ProgressRecord(0,
                        Modules.ScriptAnalysisPreparing,
                        String.Format(CultureInfo.InvariantCulture, Modules.ScriptAnalysisModule, path));
                    analysisProgress.RecordType = ProgressRecordType.Processing;

                    // Write the progress using a static source ID so that all
                    // analysis messages get single-threaded in the progress pane (rather than nesting).
                    context.CurrentCommandProcessor.CommandRuntime.WriteProgress(typeof(ScriptAnalysis).FullName.GetHashCode(), analysisProgress);
                }
            }
            catch (InvalidOperationException)
            {
                // This may be called when we are not allowed to write progress,
                // So eat the invalid operation
            }

            string scriptContent = ReadScript(path);

            ParseError[] errors;
            var moduleAst = (new Parser()).Parse(path, scriptContent, null, out errors, ParseMode.ModuleAnalysis);

            // Don't bother analyzing if there are syntax errors (we don't do semantic analysis which would
            // detect other errors that we also might choose to ignore, but it's slower.)
            if (errors.Length > 0)
                return null;

            ExportVisitor exportVisitor = new ExportVisitor(forCompletion: false);
            moduleAst.Visit(exportVisitor);

            var result = new ScriptAnalysis
            {
                DiscoveredClasses = exportVisitor.DiscoveredClasses,
                DiscoveredExports = exportVisitor.DiscoveredExports,
                DiscoveredAliases = new Dictionary<string, string>(),
                DiscoveredModules = exportVisitor.DiscoveredModules,
                DiscoveredCommandFilters = exportVisitor.DiscoveredCommandFilters,
                AddsSelfToPath = exportVisitor.AddsSelfToPath
            };

            if (result.DiscoveredCommandFilters.Count == 0)
            {
                result.DiscoveredCommandFilters.Add("*");
            }
            else
            {
                // Post-process aliases, as they are not exported by default
                List<WildcardPattern> patterns = new List<WildcardPattern>();
                foreach (string discoveredCommandFilter in result.DiscoveredCommandFilters)
                {
                    patterns.Add(WildcardPattern.Get(discoveredCommandFilter, WildcardOptions.IgnoreCase));
                }

                foreach (var pair in exportVisitor.DiscoveredAliases)
                {
                    string discoveredAlias = pair.Key;
                    if (SessionStateUtilities.MatchesAnyWildcardPattern(discoveredAlias, patterns, defaultValue: false))
                    {
                        result.DiscoveredAliases[discoveredAlias] = pair.Value;
                    }
                }
            }

            return result;
        }