private static void InitializeDocumentManager(DynamoRevitCommandData commandData)
 {
     if (DocumentManager.Instance.CurrentUIApplication == null)
     {
         DocumentManager.Instance.CurrentUIApplication = commandData.Application;
     }
 }
 private static void HandleDebug(DynamoRevitCommandData commandData)
 {
     if (commandData.JournalData != null && commandData.JournalData.ContainsKey("debug"))
     {
         if (Boolean.Parse(commandData.JournalData["debug"]))
         {
             Debugger.Launch();
         }
     }
 }
        private static RevitDynamoModel InitializeCoreModel(DynamoRevitCommandData commandData)
        {
            // Temporary fix to pre-load DLLs that were also referenced in Revit folder.
            // To do: Need to align with Revit when provided a chance.
            PreloadDynamoCoreDlls();
            var corePath           = DynamoRevitApp.DynamoCorePath;
            var dynamoRevitExePath = Assembly.GetExecutingAssembly().Location;
            var dynamoRevitRoot    = Path.GetDirectoryName(dynamoRevitExePath);// ...\Revit_xxxx\ folder

            // get Dynamo Revit Version
            var dynRevitVersion = Assembly.GetExecutingAssembly().GetName().Version;

            var umConfig           = UpdateManagerConfiguration.GetSettings(new DynamoRevitLookUp());
            var revitUpdateManager = new DynUpdateManager(umConfig);

            revitUpdateManager.HostVersion = dynRevitVersion; // update RevitUpdateManager with the current DynamoRevit Version
            revitUpdateManager.HostName    = "Dynamo Revit";
            if (revitUpdateManager.Configuration is IDisableUpdateConfig)
            {
                (revitUpdateManager.Configuration as IDisableUpdateConfig).DisableUpdates = true;
            }

            Debug.Assert(umConfig.DynamoLookUp != null);

            var userDataFolder = Path.Combine(Environment.GetFolderPath(
                                                  Environment.SpecialFolder.ApplicationData),
                                              "Dynamo", "Dynamo Revit");
            var commonDataFolder = Path.Combine(Environment.GetFolderPath(
                                                    Environment.SpecialFolder.CommonApplicationData),
                                                "Autodesk", "RVT " + commandData.Application.Application.VersionNumber, "Dynamo");

            bool isAutomationMode = CheckJournalForKey(extCommandData, JournalKeys.AutomationModeKey);

            // when Dynamo runs on top of Revit we must load the same version of ASM as revit
            // so tell Dynamo core we've loaded that version.
            var loadedLibGVersion = PreloadAsmFromRevit();


            return(RevitDynamoModel.Start(
                       new RevitDynamoModel.RevitStartConfiguration()
            {
                DynamoCorePath = corePath,
                DynamoHostPath = dynamoRevitRoot,
                GeometryFactoryPath = GetGeometryFactoryPath(corePath, loadedLibGVersion),
                PathResolver = new RevitPathResolver(userDataFolder, commonDataFolder),
                Context = GetRevitContext(commandData),
                SchedulerThread = new RevitSchedulerThread(commandData.Application),
                StartInTestMode = isAutomationMode,
                AuthProvider = new RevitOxygenProvider(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher)),
                ExternalCommandData = commandData,
                UpdateManager = revitUpdateManager,
                ProcessMode = isAutomationMode ? TaskProcessMode.Synchronous : TaskProcessMode.Asynchronous
            }));
        }
        public static string GetRevitContext(DynamoRevitCommandData commandData)
        {
            var    r       = new Regex(@"\b(Autodesk |Structure |MEP |Architecture )\b");
            string context = r.Replace(commandData.Application.Application.VersionName, "");

            //they changed the application version name conventions for vasari
            //it no longer has a version year so we can't compare it to other versions
            if (context == "Vasari")
            {
                context = "Vasari 2014";
            }

            return(context);
        }
        private static bool CheckJournalForKey(DynamoRevitCommandData commandData, string key, bool defaultReturn = false)
        {
            var result = defaultReturn;

            if (commandData.JournalData == null)
            {
                return(result);
            }

            if (commandData.JournalData.ContainsKey(key))
            {
                bool.TryParse(commandData.JournalData[key], out result);
            }

            return(result);
        }
        private static void InitializeCore(DynamoRevitCommandData commandData)
        {
            if (initializedCore)
            {
                return;
            }

            // Change the locale that LibG depends on.
            StringBuilder sb          = new StringBuilder("LANGUAGE=");
            var           revitLocale = System.Globalization.CultureInfo.CurrentUICulture.ToString();

            sb.Append(revitLocale.Replace("-", "_"));
            _putenv(sb.ToString());

            InitializeAssemblies();
            InitializeDocumentManager(commandData);

            initializedCore = true;
        }
        private static void TryOpenAndExecuteWorkspaceInCommandData(DynamoRevitCommandData commandData)
        {
            if (commandData.JournalData == null)
            {
                return;
            }

            if (commandData.JournalData.ContainsKey(JournalKeys.DynPathKey))
            {
                bool isAutomationMode = CheckJournalForKey(commandData, JournalKeys.AutomationModeKey);
                bool forceManualRun   = CheckJournalForKey(commandData, JournalKeys.ForceManualRunKey);

                bool useExistingWorkspace = false;
                if (CheckJournalForKey(commandData, JournalKeys.DynPathCheckExisting))
                {
                    WorkspaceModel currentWorkspace = revitDynamoModel.CurrentWorkspace;
                    if (currentWorkspace.FileName.Equals(commandData.JournalData[JournalKeys.DynPathKey],
                                                         StringComparison.OrdinalIgnoreCase))
                    {
                        useExistingWorkspace = true;
                    }
                }

                if (!useExistingWorkspace) //if use existing is false, open the specified workspace
                {
                    if (ModelState == RevitDynamoModelState.StartedUIless)
                    {
                        revitDynamoModel.OpenFileFromPath(commandData.JournalData[JournalKeys.DynPathKey], forceManualRun);
                    }
                    else
                    {
                        dynamoViewModel.OpenIfSavedCommand.Execute(new Dynamo.Models.DynamoModel.OpenFileCommand(commandData.JournalData[JournalKeys.DynPathKey], forceManualRun));
                        dynamoViewModel.ShowStartPage = false;
                    }
                }

                //If we have information about the nodes and their values we want to push those values after the file is opened.
                if (commandData.JournalData.ContainsKey(JournalKeys.ModelNodesInfo))
                {
                    try
                    {
                        var allNodesInfo = JsonConvert.DeserializeObject <List <Dictionary <string, string> > >(commandData.JournalData[JournalKeys.ModelNodesInfo]);
                        if (allNodesInfo != null)
                        {
                            foreach (var nodeInfo in allNodesInfo)
                            {
                                if (nodeInfo.ContainsKey(JournalNodeKeys.Id) &&
                                    nodeInfo.ContainsKey(JournalNodeKeys.Name) &&
                                    nodeInfo.ContainsKey(JournalNodeKeys.Value))
                                {
                                    var modelCommand = new DynamoModel.UpdateModelValueCommand(nodeInfo[JournalNodeKeys.Id],
                                                                                               nodeInfo[JournalNodeKeys.Name],
                                                                                               nodeInfo[JournalNodeKeys.Value]);
                                    modelCommand.Execute(revitDynamoModel);
                                }
                            }
                        }
                    }
                    catch
                    {
                        Console.WriteLine("Exception while trying to update nodes with new values");
                    }
                }

                //If we are in automation mode the model will run anyway (on the main thread
                //without the idle loop) regardless of the DynPathExecuteKey.
                if (!isAutomationMode && commandData.JournalData.ContainsKey(JournalKeys.DynPathExecuteKey))
                {
                    bool executePath = false;
                    bool.TryParse(commandData.JournalData[JournalKeys.DynPathExecuteKey], out executePath);
                    if (executePath)
                    {
                        HomeWorkspaceModel modelToRun = revitDynamoModel.CurrentWorkspace as HomeWorkspaceModel;
                        if (modelToRun != null)
                        {
                            modelToRun.Run();
                            return;
                        }
                    }
                }
            }
        }
        public bool ExecuteCommand(DynamoRevitCommandData commandData)
        {
            var startupTimer = Stopwatch.StartNew();

            if (ModelState == RevitDynamoModelState.StartedUIless)
            {
                if (CheckJournalForKey(commandData, JournalKeys.ShowUiKey, true) ||
                    CheckJournalForKey(commandData, JournalKeys.ModelShutDownKey))
                {
                    //When we move from UIless to UI we prefer to start with a fresh revitDynamoModel
                    //in order to benefit from a startup sequence similar to Dynamo Revit UI launch.
                    //Also there might be other situations which demand a new revitDynamoModel.
                    //In order to be able to address them we process ModelShutDownKey.
                    //An example of this situation is when you have a revitDynamoModel already started and you switch
                    //the document in Revit. Since revitDynamoModel is well connected to the previous document we need to
                    //shut it down and start a new one in order to able to run a graph in the new document.
                    revitDynamoModel.ShutDown(false);
                    ModelState = RevitDynamoModelState.NotStarted;
                }
                else
                {
                    TryOpenAndExecuteWorkspaceInCommandData(commandData);
                    return(true);
                }
            }

            if (ModelState == RevitDynamoModelState.StartedUI)
            {
                TryOpenAndExecuteWorkspaceInCommandData(commandData);
                return(true);
            }

            HandleDebug(commandData);

            InitializeCore(commandData);
            //subscribe to the assembly load
            AppDomain.CurrentDomain.AssemblyLoad += AssemblyLoad;

            try
            {
                extCommandData = commandData;

                UpdateSystemPathForProcess();

                // create core data models
                revitDynamoModel = InitializeCoreModel(extCommandData);
                revitDynamoModel.UpdateManager.RegisterExternalApplicationProcessId(Process.GetCurrentProcess().Id);
                revitDynamoModel.Logger.Log("SYSTEM", string.Format("Environment Path:{0}", Environment.GetEnvironmentVariable("PATH")));

                // handle initialization steps after RevitDynamoModel is created.
                revitDynamoModel.HandlePostInitialization();
                ModelState = RevitDynamoModelState.StartedUIless;

                // show the window
                if (CheckJournalForKey(extCommandData, JournalKeys.ShowUiKey, true))
                {
                    dynamoViewModel = InitializeCoreViewModel(revitDynamoModel);

                    // Let the host (e.g. Revit) control the rendering mode
                    var save = RenderOptions.ProcessRenderMode;
                    InitializeCoreView().Show();
                    RenderOptions.ProcessRenderMode = save;
                    revitDynamoModel.Logger.Log(Dynamo.Applications.Properties.Resources.WPFRenderMode + RenderOptions.ProcessRenderMode.ToString());

                    ModelState = RevitDynamoModelState.StartedUI;
                    // Disable the Dynamo button to prevent a re-run
                    DynamoRevitApp.DynamoButtonEnabled = false;
                }

                //foreach preloaded exception send a notification to the Dynamo Logger
                //these are messages we want the user to notice.
                preLoadExceptions.ForEach(x => revitDynamoModel.Logger.LogNotification
                                              (revitDynamoModel.GetType().ToString(),
                                              x.GetType().ToString(),
                                              DynamoApplications.Properties.Resources.MismatchedAssemblyVersionShortMessage,
                                              x.Message));

                TryOpenAndExecuteWorkspaceInCommandData(extCommandData);

                //unsubscribe to the assembly load
                AppDomain.CurrentDomain.AssemblyLoad -= AssemblyLoad;
                Analytics.TrackStartupTime("DynamoRevit", startupTimer.Elapsed, ModelState.ToString());
            }
            catch (Exception ex)
            {
                // notify instrumentation
                Analytics.TrackException(ex, true);

                MessageBox.Show(ex.ToString());

                DynamoRevitApp.DynamoButtonEnabled = true;

                //If for some reason Dynamo has crashed while startup make sure the Dynamo Model is properly shutdown.
                if (revitDynamoModel != null)
                {
                    revitDynamoModel.ShutDown(false);
                    revitDynamoModel = null;
                }

                return(Result.Failed);
            }

            return(Result.Succeeded);
        }