示例#1
0
        // String based DLL function executer. Path-format:"name.dll" Command-format:"namespace.class functionname(parameter1,parameter2,parameter3,parameteretc)" Do not deviate from the format! Do not use special characters!
        /// =======================================================================================================
        public static Status RunDll(Map map,
                                    string path,
                                    string command,
                                    int timeout,
                                    out List <Control> interactive_controls,
                                    AutoReport auto_report = null)
        {
            string c = command;

            interactive_controls = new List <Control>();
            Status status = Status.PASS;

            foreach (string namespace_class_function in c.Split(';'))
            {
                // Get cheker
                Checker checker = null;
                try { checker = GetChecker(auto_report, map, command); }
                catch (Exception e) { auto_report.AddOverlayedMessage(map, e.Message, Status.ABORT); }

                // Check for abort
                if (CAT.AbortAll)
                {
                    return(Status.ABORT);
                }

                // Command started
                auto_report.OverlayCommandStarted(map);

                // Check for valid function and class
                string functionwithparameters = namespace_class_function.Substring(Regex.Match(namespace_class_function, @"\s").Index + 1, namespace_class_function.Length - Regex.Match(namespace_class_function, @"\s").Index - 1);
                string namespaceclass         = namespace_class_function.Substring(0, Regex.Match(namespace_class_function, @"\s").Index);
                if (string.IsNullOrWhiteSpace(namespaceclass))
                {
                    functionwithparameters = namespace_class_function;
                }

                // Check function
                if (!Regex.IsMatch(functionwithparameters, FUNC_FORMAT + PARAM_FORMAT))
                {
                    functionwithparameters += "()";
                }                           // Auto add brackets (no parameters)

                // Retry function check
                if (!Regex.IsMatch(functionwithparameters, FUNC_FORMAT + PARAM_FORMAT))
                {
                    auto_report.AddOverlayedMessage(map, "Function '" + functionwithparameters + "' is invalid", Status.FAIL);
                    return(Status.FAIL);
                }

                // Function Name and Parameters
                string        functionname  = ExtractFunctionName(functionwithparameters);
                List <string> parameterList = ExtractParameters(functionwithparameters);

                // Default DLL
                if (string.IsNullOrWhiteSpace(namespaceclass))
                {
                    Type[] types = Assembly.GetExecutingAssembly().GetTypes();
                    foreach (Type t in types)
                    {
                        if (t.GetMethod(functionname) != null)
                        {
                            namespaceclass = "API." + t.Name;
                            auto_report.AddOverlayedMessage(map, "Applied assumption (Namespace.Class): " + namespaceclass, Status.WARN);
                        }
                    }
                    if (string.IsNullOrWhiteSpace(namespaceclass))
                    {
                        namespaceclass = DISK.RemoveExtension(path) + "." + DISK.RemoveExtension(path);
                        auto_report.AddOverlayedMessage(map, "Applied assumption (Namespace.Class): " + namespaceclass, Status.WARN);
                    }
                }

                // Class
                if (string.IsNullOrWhiteSpace(namespaceclass))
                {
                    auto_report.AddOverlayedMessage(map, "Class '" + namespaceclass + "' is invalid", Status.FAIL);
                    return(Status.FAIL);
                }

                // DLL Thread
                object returnvalue = null;
                path = DISK.AutoAddBaseDirectory(DISK.AutoAddExt(path, "dll"));
                DateTime starttime = DateTime.Now;
                Assembly assembly  = null;
                try { assembly = Assembly.LoadFile(path); if (assembly == null)
                      {
                          throw new Exception("Assembly still null");
                      }
                }
                catch (Exception e) { auto_report.AddOverlayedMessage(map, "Error loading assembly " + path + ":\r\n" + ErrorMsg(e), Status.FAIL); return(Status.FAIL); }

                Type type = null;
                try { type = assembly.GetType(namespaceclass); if (type == null)
                      {
                          throw new Exception("Type still null");
                      }
                }
                catch (Exception e) { auto_report.AddOverlayedMessage(map, "Error loading type " + namespaceclass + ":\r\n" + ErrorMsg(e), Status.FAIL); return(Status.FAIL); }

                object instance = null;
                try { instance = Activator.CreateInstance(type); if (instance == null)
                      {
                          throw new Exception("Instance still null");
                      }
                }
                catch (Exception e) { auto_report.AddOverlayedMessage(map, "Error loading instance for " + type + ":\r\n" + ErrorMsg(e), Status.FAIL); return(Status.FAIL); }

                MethodInfo newmethod = null;
                try { newmethod = type.GetMethod(functionname); if (newmethod == null)
                      {
                          throw new Exception("Method still null");
                      }
                }
                catch (Exception e) { auto_report.AddOverlayedMessage(map, "Error loading method " + functionname + " for " + type + ":\r\n" + ErrorMsg(e), Status.FAIL); return(Status.FAIL); }
                string name = newmethod.Name;

                var ts = new CancellationTokenSource();
                CancellationToken ct = ts.Token;
                bool iscomplete      = false;
                bool exception       = false;
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        if (newmethod.ReturnType == typeof(void))
                        {
                            newmethod.Invoke(instance, parameterList.Cast <object>().ToArray());
                        }
                        else
                        {
                            if (parameterList != null)
                            {
                                returnvalue = newmethod.Invoke(null, parameterList.Cast <object>().ToArray());
                            }
                            else
                            {
                                returnvalue = newmethod.Invoke(null, null);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        auto_report.AddOverlayedMessage(map, ErrorMsg(e), Status.FAIL);
                        exception = true;
                    }
                    iscomplete = true;
                }, ct);
                while (!iscomplete)
                {
                    // Timeout
                    if ((DateTime.Now - starttime).TotalSeconds > timeout)
                    {
                        ts.Cancel();
                        auto_report.AddOverlayedMessage(map, "Timeout occured (timeout = " + timeout + "s)", Status.TIMEOUT);
                        return(Status.TIMEOUT);
                    }

                    // Abort
                    if (CAT.AbortAll || CAT.AbortCurrent)
                    {
                        ts.Cancel();
                        CAT.AbortCurrent = false; // Reset to jump to next command
                        Thread.Sleep(500);        // Allow threads to cleanup using abort flags
                        auto_report.AddOverlayedMessage(map, "User aborted after " + (int)((DateTime.Now - starttime).TotalMilliseconds) + "ms", Status.ABORT);
                        return(Status.ABORT);
                    }

                    // CPU handling
                    Thread.Sleep(10);

                    // Progress Feedback
                    auto_report.UpdateCommandProgress(map);
                }


                // RETURN VALUE
                if (exception)
                {
                    status = Status.FAIL;
                }
                else if (returnvalue == null)
                {
                }
                else if (returnvalue is Control)
                {
                    interactive_controls.Add(returnvalue as Control);
                }
                else if (returnvalue is List <Control> )
                {
                    foreach (Control ctrl in (returnvalue as List <Control>))
                    {
                        interactive_controls.Add(ctrl);
                    }
                    ;
                }
                else if (!(returnvalue is Return))
                {
                    auto_report.AddOverlayedMessage(map, "This framework only supports 'Return' return type (or void)!\r\n" + returnvalue.GetType() + " is invalid", Status.FAIL);
                    status = Status.FAIL;
                }
                else
                {
                    if (((Return)returnvalue).Messages != null)
                    {
                        foreach (CATMessage message in ((Return)returnvalue).Messages)
                        {
                            auto_report.AddOverlayedMessage(map, message.Text, message.Status);
                            if (message.Status == Status.FAIL)
                            {
                                status = Status.FAIL;
                            }
                        }

                        // Add extra message checker messages
                        if (checker != null && checker.CheckType == "Messages")
                        {
                            List <Result> messageresults = Results.Check(((Return)returnvalue).Messages, checker.CheckFunction, checker.CheckParameters);
                            foreach (Result message in messageresults)
                            {
                                auto_report.AddOverlayedMessage(map, message.Message, message.Passed ? Status.PASS : Status.FAIL);
                            }
                        }
                    }

                    // Charts
                    if (((Return)returnvalue).Charts != null)
                    {
                        List <ChartData> newdata = new List <ChartData>();
                        foreach (ChartData chart in ((Return)returnvalue).Charts)
                        {
                            newdata.Add(chart);
                        }
                        auto_report.AddChartList(map, newdata);

                        // Add extra chart checker messages
                        if (checker != null && checker.CheckType == "Charts")
                        {
                            List <Result> chartresults = Results.Check(((Return)returnvalue).Charts, checker.CheckFunction, checker.CheckParameters);
                            foreach (Result chartmessage in chartresults)
                            {
                                auto_report.AddMessage(map, chartmessage.Message, chartmessage.Passed ? Status.PASS : Status.FAIL);
                            }
                        }
                    }

                    // Charts List
                    if (((Return)returnvalue).ChartsList != null)
                    {
                        foreach (List <ChartData> chartlist in ((Return)returnvalue).ChartsList)
                        {
                            auto_report.AddChartList(map, chartlist);
                        }
                    }
                }
            }

            return(status);
        }