/// <summary>
        /// 更新功能块数组列表。
        /// </summary>
        public override void UpdatePOUs()
        {
            // 当CPU为null的时候,有可能当前类还未初始化完毕;
            if (this.CPU == null)
            {
                return;
            }

            this.DeleteAll();

            IniFile iniFile     = new IniFile(this.SourceFile);
            string  projectPath = FileName.GetFilePath(this.SourceFile);

            int sectionType = 0;    // 0 不关心;2 POE;9 LIBRARY

            iniFile.LoopSections((section) =>
            {
                if (section.EndsWith("_FUNCTIONBLOCK", StringComparison.OrdinalIgnoreCase) ||
                    section.EndsWith("_FUNCTION", StringComparison.OrdinalIgnoreCase))
                {
                    sectionType = 2;
                    return(true);
                }
                if (string.Equals(section, "LIBRARY", StringComparison.OrdinalIgnoreCase))
                {
                    sectionType = 9;
                    return(true);
                }

                sectionType = 0;
                return(false);
            }, (key, value) =>
            {
                if (!string.IsNullOrEmpty(value) && key.IsPrefixIndex("FILE"))
                {
                    string file, hardwareType;
                    switch (sectionType)
                    {
                    case 2:
                        // 工程本身的功能块
                        {
                            file         = FileName.GetAbsoluteFileName(projectPath, value);
                            file         = FileName.GetNewExtFileName(file, ".POE");
                            hardwareType = ViGlobal.GetPathHardwareName(projectPath, file);
                            // 没有硬件类型名称,或者硬件类型名称匹配的情况下,才将功能块加入
                            if (string.IsNullOrEmpty(hardwareType) ||
                                string.Equals(hardwareType, this.CPU.HardwareType, StringComparison.OrdinalIgnoreCase))
                            {
                                ViPOEBlockType blockType = ViIECPOEFile.GetBlockType(file);
                                if (blockType != null)
                                {
                                    blockType.PouSource = this;
                                    this.AddChild(blockType);
                                }
                            }
                        }
                        break;

                    case 9:
                        // 工程使用的 ViGET 库工程的功能块
                        {
                            file = FileName.GetAbsoluteFileName(ViGlobal.ProjODKPath, value);
                            file = FileName.GetNewExtFileName(file, ".VAR");

                            // 不能讲把自身作为一个库文件来使用,否则会造成死循环;
                            if (this.CPU.ProjectFile != null && !this.CPU.ProjectFile.Equals(file, StringComparison.OrdinalIgnoreCase))
                            {
                                ViPouSourceCPU cpu = new ViPouSourceCPU()
                                {
                                    ProjectFile  = file,
                                    HardwareType = this.CPU.HardwareType,
                                };

                                ViCPUPouSource cpuSource = new ViCPUPouSource(cpu, ViPouAttributes.ProjectLibrary | (this.PouAttributes & ViPouAttributes.Public));
                                if (cpuSource != null)
                                {
                                    this.AddChild(cpuSource);
                                }
                            }
                        }
                        break;
                    }
                }
                return(true);
            });

            // CPU 安装的硬件库的功能块
            if (!string.IsNullOrEmpty(this.CPU.CPUName))
            {
                string globProt = ViGlobal.GetCPUENVPath(projectPath, this.CPU.CPUName) + "GLOBPROT.INC";
                string infoFile = ViGlobal.GetCPUENVPath(projectPath, this.CPU.CPUName) + this.CPU.HardwareType + ".ini";
                this.AddChild(new ViIncPouSource(globProt, infoFile, ViPouAttributes.CPULibrary | (this.PouAttributes & ViPouAttributes.Public)));
            }

            // ViGET 全局的功能块。对于安装的库工程,就不要这些信息了,否则就重复了
            if (!string.IsNullOrEmpty(this.CPU.CPUName))
            {
                ArrayList alPouSources = ViGlobal.GetPouSources(this.CPU.HardwareType);
                if (alPouSources != null)
                {
                    foreach (ViPouSource source in alPouSources)
                    {
                        this.AddChild(source);
                    }
                }
            }
        }
 /// <summary>
 /// 从功能块 Prototype 描述字符串中解析出功能块类型。
 /// </summary>
 /// <param name="decl">功能块 Prototype 描述字符串</param>
 /// <returns>解析出的功能块类型。</returns>
 public static ViPOEBlockType Parse(string decl)
 {
     return(ViIECPOEFile.GetBlockType(string.Empty, new StringReader(decl)));
 }