Beispiel #1
0
    /// <summary>
    ///
    /// </summary>
    private void UpdateDelgatesAndAtribs(MethodInfo method)
    {
        //Create the delgate, Taken from: http://stackoverflow.com/a/16364220
        Delegate thisDelegate = method.CreateDelegate(Expression.GetDelegateType(
                                                          (from parameter in method.GetParameters() select parameter.ParameterType)
                                                          .Concat(new[] { method.ReturnType })
                                                          .ToArray()));

        delegates.Add(thisDelegate);

        //Create the function attribute
        QuantSAExcelFunctionAttribute quantsaAttribute = method.GetCustomAttribute <QuantSAExcelFunctionAttribute>();

        functionAttributes.Add(quantsaAttribute.CreateExcelFunctionAttribute());

        // Create the function argument attributes
        List <object> thisArgumentAttributes = new List <object>();

        foreach (ParameterInfo param in method.GetParameters())
        {
            var argAttrib = param.GetCustomAttribute <ExcelArgumentAttribute>();
            if (argAttrib != null)
            {
                argAttrib.Name = param.Name;
            }
            thisArgumentAttributes.Add(argAttrib);
        }
        functionArgumentAttributes.Add(thisArgumentAttributes);
    }
Beispiel #2
0
    /// <summary>
    /// Registers the single manual function.
    /// </summary>
    private void AddSingleManualFunction(MethodInfo method, bool?isHidden)
    {
        //Create the function attribute
        QuantSAExcelFunctionAttribute quantsaAttribute = method.GetCustomAttribute <QuantSAExcelFunctionAttribute>();

        if (isHidden != null)
        {
            quantsaAttribute.IsHidden = isHidden.Value;
        }
        functionAttributes.Add(quantsaAttribute.CreateExcelFunctionAttribute());

        // Create the function argument attributes
        List <object> thisArgumentAttributes = new List <object>();

        foreach (ParameterInfo param in method.GetParameters())
        {
            var argAttrib = param.GetCustomAttribute <ExcelArgumentAttribute>();
            if (argAttrib != null)
            {
                argAttrib.Name = param.Name;
            }
            thisArgumentAttributes.Add(argAttrib);
        }
        functionArgumentAttributes.Add(thisArgumentAttributes);
    }
Beispiel #3
0
    /// <summary>
    /// Expose a plugin from a dll filename, if the dll is a valid plugin.
    /// </summary>
    private void ExposePlugin(string filename)
    {
        Assembly DLL = Assembly.LoadFile(filename);

        string[] names = DLL.GetManifestResourceNames();
        //ResourceSet set = new ResourceSet(names[0]);

        string shortName = null;

        foreach (Type type in DLL.GetExportedTypes())
        {
            if (typeof(IQuantSAPlugin).IsAssignableFrom(type)) // This class is a QuantSA plugin
            {
                IQuantSAPlugin plugin = Activator.CreateInstance(type) as IQuantSAPlugin;
                shortName = plugin.GetShortName();
                MyAddIn.plugins.Add(plugin);
            }
        }
        if (shortName == null)
        {
            throw new Exception(Path.GetFileName(filename) + " is in the Plugins directory but is not a valid plugin.");
        }

        foreach (Type type in DLL.GetExportedTypes())
        {
            foreach (MemberInfo member in type.GetMembers())
            {
                QuantSAExcelFunctionAttribute attribute = member.GetCustomAttribute <QuantSAExcelFunctionAttribute>();
                if (attribute != null) // We have found an excel exposed function.
                {
                    if (!attribute.Category.Equals(shortName))
                    {
                        throw new Exception(attribute.Name + " in plugin " + shortName + " is not in the excel category " + shortName);
                    }
                    string[] parts = attribute.Name.Split('.');
                    if (!(parts.Length == 2 && parts[0].Equals(shortName)))
                    {
                        throw new Exception(attribute.Name + " in plugin " + shortName + "does not following the naming convention: " + shortName + ".FunctionName");
                    }

                    // TODO: Check that the category and naming are all acceptable
                    UpdateDelgatesAndAtribs((MethodInfo)member);
                }
                if (member.MemberType.Equals(MemberTypes.Method))
                {
                    if (((MethodInfo)member).ReturnType.Equals(typeof(System.Drawing.Bitmap)))
                    {
                        Bitmap image = ((MethodInfo)member).Invoke(null, null) as Bitmap;
                        assemblyImageResources.Add(member.Name.Substring(4), image);
                    }
                }
            }
        }
    }
Beispiel #4
0
    /// <summary>
    /// Updates the functions from assembly.
    /// </summary>
    /// <param name="assembly">The assembly.</param>
    /// <param name="quantSAFunctions">The quant sa functions.</param>
    private static void UpdateFunctionsFromAssembly(Assembly assembly, Dictionary <string, MemberInfo> quantSAFunctions)
    {
        Type[] types = null;
        try
        {
            types = assembly.GetTypes();
        }
        catch (ReflectionTypeLoadException ex)
        {
            //TODO: This is for troubleshooting when the assembly does not load.  Should be written to some more general log.
            StringBuilder sb = new StringBuilder();
            foreach (Exception exSub in ex.LoaderExceptions)
            {
                sb.AppendLine(exSub.Message);
                FileNotFoundException exFileNotFound = exSub as FileNotFoundException;
                if (exFileNotFound != null)
                {
                    if (!string.IsNullOrEmpty(exFileNotFound.FusionLog))
                    {
                        sb.AppendLine("Fusion Log:");
                        sb.AppendLine(exFileNotFound.FusionLog);
                    }
                }
                sb.AppendLine();
            }
            string errorMessage = sb.ToString();
            Console.WriteLine(errorMessage);
        }
        foreach (Type type in types)
        {
            if (!type.IsPublic)
            {
                continue;
            }

            MemberInfo[] members = type.GetMembers();

            foreach (MemberInfo member in members)
            {
                QuantSAExcelFunctionAttribute attribute = member.GetCustomAttribute <QuantSAExcelFunctionAttribute>();
                if (attribute != null)
                {
                    if (attribute.HasGeneratedVersion) // if there is generated version then that will be used to constuct the delgate and this one will be used to get the help.
                    {
                        quantSAFunctions["_" + attribute.Name] = member;
                    }
                    else
                    {
                        quantSAFunctions[attribute.Name] = member;
                    }
                }
            }
        }
    }
Beispiel #5
0
        /// <summary>
        /// Use reflection on Excel.dll to find all the members that have
        /// the <see cref="QuantSAExcelFunctionAttribute"/> attribute.
        /// </summary>
        /// <remarks>
        /// This method is very simular to <see cref="GetFuncsWithGenVersion"/> in the AddIn</remarks>
        /// <returns></returns>
        public static Dictionary <string, MethodInfo> GetFuncsWithGenVersion(string filename)
        {
            Dictionary <string, MethodInfo> quantSAFunctions = new Dictionary <string, MethodInfo>();
            Assembly excelAssemby = Assembly.LoadFile(filename);

            Type[] types = null;
            try
            {
                types = excelAssemby.GetTypes();
            }
            catch (ReflectionTypeLoadException ex)
            {
                StringBuilder sb = new StringBuilder();
                foreach (Exception exSub in ex.LoaderExceptions)
                {
                    sb.AppendLine(exSub.Message);
                    FileNotFoundException exFileNotFound = exSub as FileNotFoundException;
                    if (exFileNotFound != null)
                    {
                        if (!string.IsNullOrEmpty(exFileNotFound.FusionLog))
                        {
                            sb.AppendLine("Fusion Log:");
                            sb.AppendLine(exFileNotFound.FusionLog);
                        }
                    }
                    sb.AppendLine();
                }
                string errorMessage = sb.ToString();
                Console.WriteLine(errorMessage);
            }
            foreach (Type type in types)
            {
                if (!type.IsPublic)
                {
                    continue;
                }

                MemberInfo[] members = type.GetMembers();
                foreach (MemberInfo member in members)
                {
                    QuantSAExcelFunctionAttribute attribute = member.GetCustomAttribute <QuantSAExcelFunctionAttribute>();
                    if (attribute != null)
                    {
                        if (attribute.HasGeneratedVersion) // if there is generated version then that will be used to constuct the delgate and this one will be used to get the help.
                        {
                            quantSAFunctions[attribute.Name] = (MethodInfo)member;
                        }
                    }
                }
            }
            return(quantSAFunctions);
        }
Beispiel #6
0
    /// <summary>
    /// Hides or shows Excel function based on the contents of functions_user.csv
    /// </summary>
    public void ExposeUserSelectedFunctions()
    {
        Dictionary <string, bool>       funcsAndVisibility = GetFunctionVisibility(FunctionsFilenameUser);
        Dictionary <string, MemberInfo> functions          = GetQuantSAFunctions();

        delegates                  = new List <Delegate>();
        functionAttributes         = new List <object>();
        functionArgumentAttributes = new List <List <object> >();

        foreach (KeyValuePair <string, MemberInfo> entry in functions)
        {
            MethodInfo method = ((MethodInfo)entry.Value);
            QuantSAExcelFunctionAttribute quantsaAttribute = method.GetCustomAttribute <QuantSAExcelFunctionAttribute>();
            // If the function appears in the user function list use the isHidden value from there.  Otherwise use the default behaviour.
            bool?isHidden = null;
            if (funcsAndVisibility.ContainsKey(quantsaAttribute.Name))
            {
                isHidden = !funcsAndVisibility[quantsaAttribute.Name];
            }

            if (!quantsaAttribute.HasGeneratedVersion) // Make delegates for all but the methods that have generated versions of themselves
            {
                //Create the delgate, Taken from: http://stackoverflow.com/a/16364220
                Delegate thisDelegate = method.CreateDelegate(Expression.GetDelegateType(
                                                                  (from parameter in method.GetParameters() select parameter.ParameterType)
                                                                  .Concat(new[] { method.ReturnType })
                                                                  .ToArray()));
                delegates.Add(thisDelegate);

                if (quantsaAttribute.IsGeneratedVersion)
                {
                    MethodInfo manualMethod = (MethodInfo)functions["_" + entry.Key];
                    AddSingleAutoFunction(method, manualMethod, isHidden);
                }
                else
                {
                    AddSingleManualFunction(method, isHidden);
                }
            }
        }
    }
Beispiel #7
0
        /// <summary>
        /// Generates the code for all the methods that have attribute value
        /// QuantSAExcelFunctionAttribute.HasGeneratedVersion=true
        /// </summary>
        /// <param name="functions">The selected functions.</param>
        private static void GenerateMethodCode(Dictionary <string, MethodInfo> functions)
        {
            foreach (KeyValuePair <string, MethodInfo> entry in functions)
            {
                QuantSAExcelFunctionAttribute quantsaAttribute = entry.Value.GetCustomAttribute <QuantSAExcelFunctionAttribute>();
                string        categoryName   = entry.Value.DeclaringType.Name;
                string        xlName         = quantsaAttribute.Name;
                string        fName          = entry.Value.Name;
                String        returnTypeName = entry.Value.ReturnType.Name;
                Type          returnType     = entry.Value.ReturnType;
                List <Type>   argTypes       = new List <Type>();
                List <string> argNames       = new List <string>();
                List <string> defaultValues  = new List <string>();
                foreach (ParameterInfo paramInfo in entry.Value.GetParameters())
                {
                    argTypes.Add(paramInfo.ParameterType);
                    argNames.Add(paramInfo.Name);
                    QuantSAExcelArgumentAttribute argAttrib = paramInfo.GetCustomAttribute <QuantSAExcelArgumentAttribute>();
                    if (argAttrib == null)
                    {
                        defaultValues.Add(null);
                    }
                    else
                    {
                        defaultValues.Add(argAttrib.Default);
                    }
                }
                var    listOfNameSpaces = new List <string>();
                string generatedMethod  = GetGeneratedMethodCode(categoryName, xlName, fName,
                                                                 argNames, argTypes, defaultValues, returnType, listOfNameSpaces);

                if (!categoriesAndGeneratedMethods.ContainsKey(categoryName))
                {
                    categoriesAndGeneratedMethods[categoryName] = new List <string>();
                    categoriesAndUsings[categoryName]           = new List <string>();
                }
                categoriesAndGeneratedMethods[categoryName].Add(generatedMethod);
                categoriesAndUsings[categoryName].AddRange(listOfNameSpaces);
            }
        }
Beispiel #8
0
    /// <summary>
    /// Registers a single function that is exposed by a manually and automatically written method.
    /// see http://www.quantsa.org/home_expose_to_excel.html
    /// </summary>
    /// <param name="method">The generated method.</param>
    /// <param name="manualMethod">The manual method.</param>
    /// <param name="isHidden">Is this function hidden.</param>
    private void AddSingleAutoFunction(MethodInfo method, MethodInfo manualMethod, bool?isHidden)
    {
        //Create the function attribute
        QuantSAExcelFunctionAttribute quantsaAttribute = manualMethod.GetCustomAttribute <QuantSAExcelFunctionAttribute>();

        if (isHidden != null)
        {
            quantsaAttribute.IsHidden = isHidden.Value;
        }
        functionAttributes.Add(quantsaAttribute.CreateExcelFunctionAttribute());

        // Create the function argument attributes
        List <object> thisArgumentAttributes = new List <object>();

        if (manualMethod.GetParameters().Length < method.GetParameters().Length)
        {
            ExcelArgumentAttribute argAttrib = new ExcelArgumentAttribute();
            argAttrib.Name        = "objectName";
            argAttrib.Description = "The name of the object to be created.";
            //Note that the above 2 strings are the same as those added in GenerateDocs, if they are changed here they should be changed there too.
            thisArgumentAttributes.Add(argAttrib);
        }
        foreach (ParameterInfo param in manualMethod.GetParameters())
        {
            var argAttrib = param.GetCustomAttribute <ExcelArgumentAttribute>();
            if (argAttrib != null)
            {
                argAttrib.Name = param.Name;
            }
            if (ExcelUtilities.InputTypeShouldHaveHelpLink(param.ParameterType))
            {
                string typeName = param.ParameterType.IsArray ? param.ParameterType.GetElementType().Name : param.ParameterType.Name;
                argAttrib.Description += "(" + typeName + ")";
            }
            thisArgumentAttributes.Add(argAttrib);
        }
        functionArgumentAttributes.Add(thisArgumentAttributes);
    }
        /// <summary>
        /// Updates the content collection for a single dll.
        /// </summary>
        /// <param name="dllName">Name of the DLL.</param>
        private void UpdateContentCollection1dll(string dllName)
        {
            Assembly DLL = Assembly.LoadFile(dllName);

            foreach (Type type in DLL.GetExportedTypes())
            {
                foreach (MemberInfo member in type.GetMembers())
                {
                    QuantSAExcelFunctionAttribute attribute = member.GetCustomAttribute <QuantSAExcelFunctionAttribute>();
                    if (attribute != null && attribute.IsGeneratedVersion)
                    {
                        MethodInfo method   = (MethodInfo)member;
                        string     name     = attribute.Name.Split('.')[1];
                        int        argCount = method.GetParameters().Count();
                        generatedMethodArgCount[name] = argCount;
                    }
                    if (attribute != null && !attribute.IsGeneratedVersion) // We have found an excel exposed function and it is not the generated version.
                    {
                        FileContents contents = new FileContents();
                        // Check consistency of contents
                        string[] categoryParts = attribute.Category.Split('.');
                        string[] nameParts     = attribute.Name.Split('.');
                        if (attribute.Description.Length < 5)
                        {
                            errorInfo.Add(type.Name + "," + attribute.Name + ",,Does not have a description.");
                        }
                        if (!nameParts[0].Equals("QSA"))
                        {
                            errorInfo.Add(type.Name + "," + attribute.Name + ",,Name does not start with 'QSA'.");
                        }
                        if (!("XL" + categoryParts[1]).Equals(type.Name))
                        {
                            errorInfo.Add(type.Name + "," + attribute.Name + ",,Category does not match file.");
                        }
                        if (attribute.HelpTopic == null)
                        {
                            errorInfo.Add(type.Name + "," + attribute.Name + ",,Does not have a help topic.");
                        }
                        else if (!attribute.HelpTopic.Equals(helpURL + nameParts[1] + ".html"))
                        {
                            errorInfo.Add(type.Name + "," + attribute.Name + ",,Help topic should be," + helpURL + nameParts[1] + ".html");
                        }
                        if (attribute.ExampleSheet == null)
                        {
                            errorInfo.Add(type.Name + "," + attribute.Name + ",,Example sheet has not been set.");
                            contents.exampleSheet = "Not available";
                        }
                        else
                        {
                            contents.exampleSheet = attribute.ExampleSheet;
                        }

                        // Add details
                        contents.name        = attribute.Name.Split('.')[1];
                        contents.category    = attribute.Category.Split('.')[1];
                        contents.Description = attribute.Description;

                        MethodInfo method = (MethodInfo)member;
                        foreach (ParameterInfo param in method.GetParameters())
                        {
                            var argAttrib = param.GetCustomAttribute <ExcelArgumentAttribute>();
                            if (argAttrib != null)
                            {
                                contents.argNames.Add(param.Name);
                                if (InputTypeShouldHaveHelpLink(param.ParameterType))
                                {
                                    string name = param.ParameterType.IsArray ? param.ParameterType.GetElementType().Name : param.ParameterType.Name;
                                    argAttrib.Description += "(" + name + ")";
                                }
                                contents.argDescriptions.Add(argAttrib.Description);

                                if (argAttrib.Description.Length < 5)
                                {
                                    errorInfo.Add(type.Name + "," + attribute.Name + "," + param.Name + ",No argument description");
                                }
                            }
                            else
                            {
                                errorInfo.Add(type.Name + "," + attribute.Name + "," + param.Name + ",Argument does not have ExcelArgumentAttribute");
                            }
                        }
                        contentCollection.AddFile(contents);
                    }
                }
            }
        }