public static void IncludeFilesToProjectBuild(string[] alFiles)
        {
            DirectoryInfo vafDirectoryInfo = ALFilesWriter.GetMFTargetDirectoryInfo();

            if (!vafDirectoryInfo.Exists)
            {
                return;
            }

            FileInfo projectBuildFile = new FileInfo($@"{vafDirectoryInfo.FullName}\{vafDirectoryInfo.Name}.csproj");

            if (!projectBuildFile.Exists)
            {
                return;
            }

            VAFProject = new Project($@"{projectBuildFile.FullName}");

            var    prjItems      = VAFProject.Items;
            string fileToInclude = string.Empty;

            foreach (string alFile in alFiles)
            {
                fileToInclude = $@"{alFile.Replace($"{vafDirectoryInfo.FullName}\\", "")}";
                if (prjItems.Any(prjItem => "Compile".Equals(prjItem.ItemType) && fileToInclude.Equals(prjItem.UnevaluatedInclude)))
                {
                    continue;
                }

                VAFProject.AddItem("Compile", fileToInclude);
            }

            VAFProject.Save();
        }
        private static string GenerateXmlFile(string v)
        {
            string projectName = ALFilesWriter.GetMFTargetDirectoryInfo().Name;

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
            sb.AppendLine("<application");
            sb.AppendLine("			type=\"server-application\"");
            sb.AppendLine("			xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
            sb.AppendLine("			xsi:noNamespaceSchemaLocation=\"http://www.m-files.com/schemas/appdef-server-v1.xsd\">");
            sb.AppendLine("  <guid>ee54cadd-fd56-4092-ac43-007f844558ef</guid>");
            sb.AppendLine($"  <name>{projectName}</name>");
            sb.AppendLine("  <description>VAF Vault Application</description>");
            sb.AppendLine("  <publisher></publisher>");
            sb.AppendLine("  <version>1.0.0</version>");
            sb.AppendLine("  <copyright></copyright>");
            sb.AppendLine("  <extension-objects>");
            sb.AppendLine("    <extension-object>");
            sb.AppendLine($"      <name>{projectName}</name>");
            sb.AppendLine($"      <assembly>{projectName}.dll</assembly>");
            sb.AppendLine($"      <class>{projectName}.VaultApplication</class>");
            sb.AppendLine("      <installation-method>Install</installation-method>");
            sb.AppendLine("      <uninstallation-method>Uninstall</uninstallation-method>");
            sb.AppendLine("      <initialization-method>Initialize</initialization-method>");
            sb.AppendLine("      <uninitialization-method>Uninitialize</uninitialization-method>");
            sb.AppendLine("      <start-operations-method>StartOperations</start-operations-method>");
            sb.AppendLine("    </extension-object>");
            sb.AppendLine("  </extension-objects>");
            sb.AppendLine("</application>");

            return(sb.ToString());
        }
        public bool Generate()
        {
            bool result = false;

            try {
                if (Api == null)
                {
                    return(false);
                }
                Console.WriteLine("\n+----------------------------+");
                Console.WriteLine("| AbstractionLayer Generator |");
                Console.WriteLine("+----------------------------+\n");
                Console.WriteLine($"[INFO] Generating AbstractionLayer for vault <{Api.MFilesSettings.VaultName} ({Api.MFilesSettings.VaultGUID})>...");
                // Proceed with abstraction
                Api.InitObjectTypes();
                Api.InitClassTypes();
                Api.InitPropertyDefinitions();
                Api.InitValueLists();
                Api.InitWorkflowWorkflowStates();

                // Generating AL class files
                List <GeneratorArtifacts> generatorArtifactsList = new List <GeneratorArtifacts>()
                {
                    GeneratorArtifacts.UTILITIES
                    , GeneratorArtifacts.MODELS
                    , GeneratorArtifacts.INTERFACES
                    , GeneratorArtifacts.EVENT_HANDLERS
                    , GeneratorArtifacts.VAULT_APPLICATION
                };

                ALFilesWriter alFilesWriter    = null;
                string[]      generatedALFiles = { };

                generatorArtifactsList.ForEach(generatorArtifact => {
                    alFilesWriter = FilesWriterFactory.GetFilesWriter(generatorArtifact);
                    alFilesWriter.WriteFiles(Api);
                    generatedALFiles = generatedALFiles.Union(alFilesWriter.GeneratedFiles).ToArray();
                });
                Console.WriteLine($"[INFO] Successfully generated AbstractionLayer for vault <{Api.MFilesSettings.VaultName} ({Api.MFilesSettings.VaultGUID})>...");

                DirectoryInfo mfTargetDirectoryInfo = ALFilesWriter.GetMFTargetDirectoryInfo();
                Console.WriteLine($"[INFO] Adding generated AbstractionLayer files to <{mfTargetDirectoryInfo.Name}> project build...");
                BuildUtils.IncludeFilesToProjectBuild(generatedALFiles);
                Console.WriteLine($"[INFO] Successfully added generated AbstractionLayer files to <{mfTargetDirectoryInfo.Name}> project build...\n");
                result = true;
            } catch (Exception ex) {
                Console.WriteLine($"[ERROR] Something went wrong during execution of ALGenerator. " + ex.Message);
            } finally {
                Api?.Dispose();
            }
            Console.WriteLine("[END]");
            if (!Api.MFilesSettings.SilentExit)
            {
                Console.WriteLine($"Press any key to exit...");
                Console.ReadKey();
            }
            return(result);
        }
        public void SaveToXmlFile()
        {
            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();

            xmlWriterSettings.Indent = true;
            xmlWriterSettings.NewLineOnAttributes = true;
            XmlWriter xmlWriter = null;

            try {
                if (File.Exists(MFILES_SETTINGS_XML_FILE))
                {
                    File.Delete(MFILES_SETTINGS_XML_FILE);
                }

                xmlWriter = XmlWriter.Create(MFILES_SETTINGS_XML_FILE, xmlWriterSettings);

                if (string.IsNullOrWhiteSpace(ProjectName))
                {
                    ProjectName = ALFilesWriter.GetMFTargetDirectoryInfo().Name;
                }
                if (string.IsNullOrWhiteSpace(Domain))
                {
                    Domain = "";
                }

                Console.WriteLine("[INFO] Creating/Updating M-Files settings...");
                xmlWriter.WriteStartElement("mfiles");
                xmlWriter.WriteElementString("projectName", ProjectName);
                xmlWriter.WriteElementString("serverName", Server);
                xmlWriter.WriteElementString("port", string.IsNullOrWhiteSpace(Port) ? "2266" : Port);
                xmlWriter.WriteElementString("vaultName", VaultName);
                xmlWriter.WriteElementString("vaultGUID", VaultGUID);
                xmlWriter.WriteElementString("authType", ((int)AuthType).ToString());
                xmlWriter.WriteElementString("domain", Domain);
                xmlWriter.WriteElementString("username", Username);
                xmlWriter.WriteElementString("password", SecurityUtils.Encrypt(Password));

                xmlWriter.WriteEndElement();
                File.SetAttributes(MFILES_SETTINGS_XML_FILE, FileAttributes.Hidden);
            } catch (Exception ex) {
                Console.WriteLine($"[ERROR] {ex.Message}");
            } finally {
                xmlWriter?.Flush();
            }

            Console.WriteLine("[INFO] Completed creating/updating M-Files settings...");
        }
        private string GetMFEventTypeHandlerAttributes()
        {
            string        vafDirectory = ALFilesWriter.GetMFTargetDirectoryInfo().FullName;
            List <string> parsedCustomEventHandlerAttributes = new List <string>();
            SyntaxTree    vaultAppTree = CSharpSyntaxTree.ParseText(File.ReadAllText($"{vafDirectory}\\Interfaces\\IMFEvent.cs"));

            #region get event handlers
            foreach (string cs_file in Directory.GetFiles(vafDirectory, "*.cs", SearchOption.AllDirectories))
            {
                SyntaxTree    tree        = CSharpSyntaxTree.ParseText(File.ReadAllText(cs_file));
                var           root        = (CompilationUnitSyntax)tree.GetCompilationUnitRoot();
                var           compilation = CSharpCompilation.Create("test_compile").AddSyntaxTrees(vaultAppTree, tree);
                SemanticModel model       = compilation.GetSemanticModel(tree);
                foreach (var cls in root.DescendantNodes().OfType <ClassDeclarationSyntax>().Where(o => (o.BaseList + "").Contains("OT_")))
                {
                    foreach (var method in cls.Members.OfType <MethodDeclarationSyntax>())
                    {
                        foreach (var attrl in method.AttributeLists)
                        {
                            foreach (AttributeSyntax attr in attrl.Attributes)
                            {
                                var typeInfo = model.GetTypeInfo(attr).Type;
                                if (typeInfo == null || !typeInfo.AllInterfaces.Any(o => o.Name + "" == "IMFEvent"))
                                {
                                    continue;
                                }
                                string eventHandlerName = typeInfo.Name.ToString();
                                if (!parsedCustomEventHandlerAttributes.Contains(eventHandlerName))
                                {
                                    parsedCustomEventHandlerAttributes.Add(eventHandlerName);
                                }
                            }
                        }
                    }
                }
            }
            #endregion get event handlers

            List <string> eventHandlerTypesToInsert =
                parsedCustomEventHandlerAttributes.Select(eventHandler => $"[EventHandler(MFEventHandlerType.{eventHandler})]").ToList();

            return(string.Join("\n\t\t", eventHandlerTypesToInsert));
        }
        public static void BuildProject(ILogger logger = null)
        {
            DirectoryInfo vafDirectoryInfo = ALFilesWriter.GetMFTargetDirectoryInfo();

            if (!vafDirectoryInfo.Exists)
            {
                return;
            }

            if (VAFProject == null)
            {
                VAFProject = new Project($@"{vafDirectoryInfo.FullName}\{vafDirectoryInfo.Name}.csproj");
            }
#if !DEBUG
            BuildUtils.VAFProject.SetProperty("Configuration", "Release");
#endif
            bool isBuildSuccessfull = logger != null?VAFProject.Build(logger) : VAFProject.Build();

            if (!isBuildSuccessfull)
            {
                throw new Exception($"Compile issue(s) found in VAF project...");
            }
        }
        public void ReadSettingsFile()
        {
            try {
                if (!File.Exists(MFILES_SETTINGS_XML_FILE))
                {
                    HasSettingsXmlFile = false;
                    return;
                }

                XmlDocument mfilesSettingsXmlDoc = new XmlDocument();
                mfilesSettingsXmlDoc.Load(MFILES_SETTINGS_XML_FILE);
                XmlNode mfilesSettingsNodes = mfilesSettingsXmlDoc.SelectNodes("/mfiles")[0];

                ProjectName        = mfilesSettingsNodes["projectName"].InnerText;
                ProjectName        = !string.IsNullOrWhiteSpace(ProjectName) ? ProjectName : ALFilesWriter.GetMFTargetDirectoryInfo().Name;
                Server             = mfilesSettingsNodes["serverName"].InnerText;
                Port               = mfilesSettingsNodes["port"].InnerText;
                VaultName          = mfilesSettingsNodes["vaultName"].InnerText;
                VaultGUID          = mfilesSettingsNodes["vaultGUID"].InnerText;
                AuthType           = (MFAuthType)Int32.Parse(mfilesSettingsNodes["authType"].InnerText);
                Domain             = mfilesSettingsNodes["domain"].InnerText;
                Username           = mfilesSettingsNodes["username"].InnerText;
                Password           = SecurityUtils.Decrypt(mfilesSettingsNodes["password"].InnerText);
                HasSettingsXmlFile = true;
            } catch {
                Console.WriteLine("[ERROR] Something wrong during reading of M-Files Settings file...");
            }
        }
        public bool Run()
        {
            Console.WriteLine("\n+--------------+");
            Console.WriteLine("| VAF Deployer |");
            Console.WriteLine("+--------------+\n");

            DirectoryInfo vafDirectoryInfo   = ALFilesWriter.GetMFTargetDirectoryInfo();
            string        vafProjectFullPath = vafDirectoryInfo.FullName;
            string        vafProjectName     = vafDirectoryInfo.Name;

            ALFilesWriter alFilesWriter = FilesWriterFactory.GetFilesWriter(GeneratorArtifacts.VAULT_APPLICATION);

            alFilesWriter.WriteFiles(null);
            BuildUtils.IncludeFilesToProjectBuild(alFilesWriter.GeneratedFiles);

#if DEBUG
            string appPathStr = Path.Combine(new string[] { vafProjectFullPath, "bin", "Debug" });
#else
            string appPathStr = Path.Combine(new string[] { vafProjectFullPath, "bin", "Release" });
#endif
            try {
                Console.WriteLine($"[INFO] Building VAF project...");
                BuildErrorConsoleLogger errorLogger = new BuildErrorConsoleLogger();
                BuildUtils.BuildProject(errorLogger);
                Console.WriteLine($"[INFO] Sucessfully built VAF project...");
                DirectoryInfo applicationPath = new DirectoryInfo(appPathStr);
                FileInfo      appDefFile      = new FileInfo(Path.Combine(applicationPath.FullName, "appdef.xml"));
                Version       version         = new Version("1.0.0.0");
                //Version version = typeof(VAF.VaultApplication).Assembly.GetName().Version;
                File.WriteAllText(appDefFile.FullName, GenerateXmlFile(version.ToString()));

                string vault = MFilesSettings.VaultGUID;
                if (string.IsNullOrWhiteSpace(vault))
                {
                    vault = MFilesSettings.VaultName;
                }

                Console.WriteLine($"[INFO] Creating vault application package for <{vault}>...");
                VAEBuilder vaeBuilder         = new VAEBuilder();
                string     applicationGuid    = GetApplicationGuid(appDefFile);
                FileInfo   applicationPackage = vaeBuilder.CreateApplicationPackage(applicationGuid, applicationPath);
                Console.WriteLine($"[INFO] Application package for {vault} created: " + applicationPackage);

                if (MFilesSettings.Server != null && !string.IsNullOrWhiteSpace(vault))
                {
                    ConnectAndReinstall(applicationGuid, applicationPackage);
                    Console.WriteLine($"[INFO] Completed deployment for vault <{MFilesSettings.VaultName} ({MFilesSettings.VaultGUID})>...\n");
                    return(true);
                }
                else
                {
                    Console.WriteLine("[INFO] Skipping installation:");
                }
            } catch (Exception e) {
                Console.WriteLine($"[ERROR] {e.Message}\n");
            }
            if (!NoPromptExit)
            {
                Console.WriteLine($"Press any key to exit...");
                Console.ReadKey();
            }
            return(false);
        }