Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagec#
titleSample gmslAPI Upgrade Program (beta)
linenumberstrue
collapsetrue
using System.Collections.Generic;
using System.Linq;
using gmslLibrary.Services;
using gmslLibrary.Model;
using gmslLibrary.Enums;
using GM = gmslAPI;

namespace gmUpgrade
{
    public static class Program
    {
        const string taskArg = "TaskInfo=";
        const string startupArg = "startup=";

        [System.STAThread] // faster using STA
        static void Main(string[] args)
        {

            string cmlStartup = System.Array.Find(args, str => str.StartsWith(startupArg));
            string startupPath = null;
            if (cmlStartup == null)
            {
                // default startup file path
                startupPath = gmslAPI.Common.DefaultStartUpFile;
            }
            else
            {
                // parse startup path from the command line, and remove it from the list of arguments
                int i = 0;
                foreach (string arg in args)
                {
                    if (arg.StartsWith(startupArg))
                    {
                        args[i] = "";
                        startupPath = arg.Split('=')[1];
                    }
                    i++;
                }
            }

            // When started by gmStudio, TaskInfo argument is passed on the command line.
            // The TaskInfo XML file is generated by gmStudio.  It contains details about 
            // the upgrade task and the upgrade environment.
            // For debugging or direct operation, load upgrade tasks here.
            // Note: you can redirect the output of this to the log file for 
            // debugging (> log) in project properties, but doing so will block 
            // gmStudio from running the EXE running when VS is open. 
            string cmlTask = System.Array.Find(args, str => str.StartsWith(taskArg));
            List<string> taskList = new List<string>();
            if (cmlTask == null)
            {
                // batch
                taskList.Add(taskArg + @"C:\gmSpec\Util\APITest\proj\log\APITest-APITest-exe-csh.TRAN.Xml");
            }
            else
            {
                // parse taskarg item from the command line
                int i = 0;
                foreach (string arg in args)
                {
                    if (arg.StartsWith(taskArg))
                    {
                        args[i] = "";
                        taskList.Add(arg);
                    }
                    i++;
                }
            }
            if (taskList.Count == 0)
            {
                System.Console.Write("USAGE: " + args[0] + " " + taskArg + " TaskInfoFilePath");
                System.Environment.Exit(1);
            }

            RunAllTranslations(taskList, startupPath, args);
            System.Environment.Exit(0);
        }

        static void RunAllTranslations(List<string> taskList, string startupPath, string[] args)
        {
            GM.Common.LoadLicense(logInfo: true);

            string taskInfoPath = "";
            foreach (string arg in taskList)
            {
                if (arg.StartsWith(taskArg))
                {
                    taskInfoPath = arg.Split('=')[1];
                    if (!System.IO.File.Exists(taskInfoPath))
                    {
                        System.Console.WriteLine("ERROR: TaskInfo File Not Found:" + taskInfoPath);
                        System.Environment.Exit(999);
                    }
                    else
                    {
                        repair(taskInfoPath);
                        GM.gmStudioTask task = GM.Common.Load(taskInfoPath);
                        RunUpgrade(task, startupPath, args);
                    }
                }
            }
        }
        private static void RunUpgrade(gmslAPI.gmStudioTask task, string startupPath, string[] args)
        {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            // Go to Upgrade project working folder so relative file references are correct
            System.IO.Directory.SetCurrentDirectory(task.WorkFolder);

            System.Console.WriteLine("Loaded task:" + task.JobId);

            string projectStartup = @"C:\Program Files (x86)\GreatMigrations\gmStudio\support\tools\gmBasic.xml";
            if (!System.IO.File.Exists(projectStartup)) projectStartup = null;

            gmBasic.StartUp(projectStartup, null, args);

            // Detailed translation rules are stored in a ScriptRules.xml
            // This format can be used by both XML-based and API-based upgrade tasks
            // The ScriptRules class makes these rules available to API calls.
            GM.ScriptRules rules = new GM.ScriptRules(@"..\usr\ScriptRules.xml");

            rules.AddRules(task, "BasicRules");

            rules.logEnable = true;
            log(rules.logEnable, rules.AllRulesReport());

            log(rules.logEnable, "Startup(ms):" + sw.ElapsedMilliseconds);
            Execute.Storage(action: "Create", identifier: task.JobId);

            if (rules.OptionRules != 0)
            {
                Execute.gmPL(commands: rules.OptionRules);
                log(rules.logEnable, "Options(ms):" + sw.ElapsedMilliseconds);
            }

            bool useWPF = Select.SubSystem == Dialects.wpf;

            log(rules.logEnable, "GUI: " + (useWPF ? "WPF" : "WinForms"));

            Execute.Load(project: task.SrcPath, sourcecode: "on");
            AddCommentOnErrorHandlers();

            Execute.Compile(resx: task.ResxFolder, commands: rules.CompileRules);
            //Execute.Compile(project: task.SrcPath, resx: task.ResxFolder, commands: rules.CompileRules);
            log(rules.logEnable, "Compile(ms):" + sw.ElapsedMilliseconds);

            if (rules.PreAnalyseRules != 0)
            {
                Execute.gmPL(commands: rules.PreAnalyseRules);
                log(rules.logEnable, "PreAnalyse(ms):" + sw.ElapsedMilliseconds);
            }

            Execute.Analyse();
            log(rules.logEnable, "Analyze(ms):" + sw.ElapsedMilliseconds);

            if (rules.PostAnalyseRules != 0)
            {
                Execute.gmPL(commands: rules.PostAnalyseRules);
                log(rules.logEnable, "PostAnalyse(ms):" + sw.ElapsedMilliseconds);
            }

            Execute.Output(status: "New", filename: task.BndPath);

            Execute.Author(commands: rules.AuthorRules);
            log(rules.logEnable, "Author(ms):" + sw.ElapsedMilliseconds);
            Execute.Output(status: "Close");

            if (rules.PostAuthorRules != 0)
            {
                Execute.gmPL(commands: rules.PostAuthorRules);
                log(rules.logEnable, "PostAuthor(ms):" + sw.ElapsedMilliseconds);
            }

            Execute.Storage(action: "Close");
            gmBasic.Terminate();
            log(rules.logEnable, "Total(ms):" + sw.ElapsedMilliseconds);
        }
        private static void log(bool doLog, string msg)
        {
            if (doLog) System.Console.WriteLine(msg);
        }
        private static void repair(string taskInfoPath)
        {
            string data = System.IO.File.ReadAllText(taskInfoPath);
            data = data.Replace("UsrCm nt=", "UsrCmnt= ");
            data = data.Replace("UsrDes c=", "UsrDesc= ");
            System.IO.File.WriteAllText(taskInfoPath, data);
        }

        private static void AddCommentOnErrorHandlers()
        {
            int[] levels = new int[19];
            int iRoot;
            tInfoFile formFile;
            Text textStream;
            int nRecord;
            int curRecord;
            int length = 0;
            int rai = 0;
            string record;

            for (iRoot = Store.FindFirstChild(levels, 0); iRoot != 0; iRoot = Store.FindNextChild(levels))
            {
                if (Store.GetObjectType(iRoot) != ObjectType.FormFile) continue;
                string name = Symbol.FullName(iRoot, 0);
                FileSystem.LogMessage("name=" + name);

                formFile = new tInfoFile(iRoot);
                if (formFile.textBase == 0) continue;
                FileSystem.LogMessage("formFile.textBase=" + formFile.textBase);

                textStream = new Text(formFile.textBase);
                FileSystem.LogMessage("textStream=" + textStream);

                // sample code changes lines ending with ":" to lines ending with ": 'TEST"
                nRecord = textStream.Maximum();
                curRecord = 0;
                while (curRecord < nRecord)
                {
                    curRecord = curRecord + 1;
                    textStream.Position(curRecord);
                    record = textStream.Access(ref length, ref rai);

                    if (length < 2) continue;
                    string last = Character.Substr(record, length - 1, 1);
                    if (last == ":")
                    {
                        // Inserts a record after the current record and sets Position to new record
                        textStream.Insert(record + " ' TEST");
                        // reset position to original record
                        textStream.Position(curRecord);
                        // delete original record
                        textStream.Delete();
                        continue;
                    }
                }
                textStream.Close();
            }
        }
    }
}

...