I don’t know why Erik wants to call this FaceMelter, but here is an example of how to use the Idling event and 2014’s new SynchronizeWithCentral method to automatically Synchronize With Central at a desired interval.
For testing purposes I set it to auto-synch every 3 minutes. You would probably want an interval a bit longer 🙂
public static class myCommand
{
// store the time when the last save occurred
static DateTime lastSaveTime;
public static void idleUpdate(object sender, IdlingEventArgs e)
{
// set an initial value for the last saved time
if (lastSaveTime == DateTime.MinValue)
lastSaveTime = DateTime.Now;
// check the current time
DateTime now = DateTime.Now;
TimeSpan elapsedTime = now.Subtract(lastSaveTime);
double minutes = elapsedTime.Minutes;
UIApplication uiApp = sender as UIApplication;
// write a comment to the journal file for diagnostic purposes
uiApp.Application.WriteJournalComment("Idle check. Elapsed time = " + minutes,true);
// don't do anything if less than 3 minutes since last auto-save
if (minutes < 3)
return;
Document doc = uiApp.ActiveUIDocument.Document;
if (!doc.IsWorkshared)
return;
TransactWithCentralOptions transact = new TransactWithCentralOptions();
SynchronizeWithCentralOptions synch = new SynchronizeWithCentralOptions();
synch.Comment = "Autosaved by the API at " + DateTime.Now;
RelinquishOptions relinquishOptions = new RelinquishOptions(true);
relinquishOptions.CheckedOutElements = true;
synch.SetRelinquishOptions(relinquishOptions);
uiApp.Application.WriteJournalComment("AutoSave To Central", true);
doc.SynchronizeWithCentral(transact, synch);
// update the last saved time
lastSaveTime = DateTime.Now;
}
}
class rtcApplication : IExternalApplication
{
public static FailureDefinitionId failureDefinitionId = new FailureDefinitionId(new Guid("E7BC1F65-781D-48E8-AF37-1136B62913F5"));
public Autodesk.Revit.UI.Result OnStartup(UIControlledApplication application)
{
// register the idling event when Revit starts
application.Idling += new EventHandler<IdlingEventArgs>(myCommand.idleUpdate);
return Result.Succeeded;
}
public Result OnShutdown(UIControlledApplication application)
{ return Result.Succeeded; }
}
Hi Harry
Great tool.
I built the macro without errors but I don’t think it is working. I didn’t detect any auto synchronization with central.
What am I possibly doing wrong here?
Did the Idling event get registered? Maybe try starting with a simpler example that posts a Task Dialog showing the current time every 10 seconds.
No, I didn’t find any signs of it in the journal file.
Please post your code
/*
* Created by SharpDevelop.
* User: vvlasov
* Date: 7/15/2013
* Time: 2:19 PM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.UI.Events;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.ApplicationServices;
namespace AutoSynch2014
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.DB.Macros.AddInId(“B6DC71CA-7865-4C20-B6F0-72038004A2F4”)]
public partial class ThisApplication
{
private void Module_Startup(object sender, EventArgs e)
{
}
private void Module_Shutdown(object sender, EventArgs e)
{
}
#region Revit Macros generated code
private void InternalStartup()
{
this.Startup += new System.EventHandler(Module_Startup);
this.Shutdown += new System.EventHandler(Module_Shutdown);
}
#endregion
public static class myCommand
{
// store the time when the last save occurred
static DateTime lastSaveTime;
public static void idleUpdate(object sender, IdlingEventArgs e)
{
// set an initial value for the last saved time
if (lastSaveTime == DateTime.MinValue)
lastSaveTime = DateTime.Now;
// check the current time
DateTime now = DateTime.Now;
TimeSpan elapsedTime = now.Subtract(lastSaveTime);
double minutes = elapsedTime.Minutes;
UIApplication uiApp = sender as UIApplication;
// write a comment to the journal file for diagnostic purposes
uiApp.Application.WriteJournalComment(“Idle check. Elapsed time = ” + minutes,true);
// don’t do anything if less than 3 minutes since last auto-save
if (minutes < 1)
return;
Document doc = uiApp.ActiveUIDocument.Document;
if (!doc.IsWorkshared)
return;
TransactWithCentralOptions transact = new TransactWithCentralOptions();
SynchronizeWithCentralOptions synch = new SynchronizeWithCentralOptions();
synch.Comment = "Autosaved by the API at " + DateTime.Now;
RelinquishOptions relinquishOptions = new RelinquishOptions(true);
relinquishOptions.CheckedOutElements = true;
synch.SetRelinquishOptions(relinquishOptions);
uiApp.Application.WriteJournalComment("AutoSave To Central", true);
doc.SynchronizeWithCentral(transact, synch);
// update the last saved time
lastSaveTime = DateTime.Now;
}
}
class rtcApplication : IExternalApplication
{
public static FailureDefinitionId failureDefinitionId = new FailureDefinitionId(new Guid("E7BC1F65-781D-48E8-AF37-1136B62913F5"));
public Autodesk.Revit.UI.Result OnStartup(UIControlledApplication application)
{
// register the idling event when Revit starts
application.Idling += new EventHandler(myCommand.idleUpdate);
return Result.Succeeded;
}
public Result OnShutdown(UIControlledApplication application)
{ return Result.Succeeded; }
}
public void AutoSynch2014()
{
}
public void PrintSheetsFromLink()
{
}
}
}
I receive a warning for the public static void idleUpdate(object sender, IdlingEventArgs e) line stating idlingeventargs is inaccessible due to its protection level
Try replacing Idlingeventargs with Autodesk.Revit.UI.Events.IdlingEventArgs if you don’t have a using statement for Autodesk.Revit.UI.Events. More info at https://boostyourbim.wordpress.com/2012/12/23/using-statements/
Hi, as I can load this app on my Revit 2013. Thanks
How to force Revit 2013/2014 to reload linked model while SYNC to central? Is there simple way to do it or need any Macro? ANy help will be appriciated
2014 has a new method RevitLinkType.Load() which you can try calling during the Application.DocumentSynchronizingWithCentral Event
It seems this would be easy to modify this to autosave the local instead. That would avoid the face melting.
What and how do I get this to work. how do load the provided info
Hi Kenneth – If you are new to the Revit API and creating external applications, my video course at http://bit.ly/revitapi is a great way to get started
does this work with later versions 2018-2020?
I think so. Don’t forget to include the needed namespaces such as:
using Autodesk.Revit.UI.Events;
which is needed for IdlingEventArgs
Are any of the comments being written to the journal file? To do this “right”, I would not use a macro – create a project in Visual Studio and compile a DLL with this External Application. I only used a macro for demonstration purposes on this blog.
no comments written to the journal file.
could you please point me to either your lectures, posts or other resources on how to compile a DLL to make this work? I’m relatively new to programming in C# but would love to learn it! Thanks in advanced!
Start with the Udemy lecture “Create an External Command”
Also relevant are “Debugging external commands in Visual Studio” and “Events”
in this sample you supposed last time saved is when Revit starts am I right?
how can I check if the user synced or saved and how can I get last time that the document is synced or saved by the user to make it my start point ?
There are events like DocumentSaved, DocumentSavedAs, DocumentSynchronizedWithCentral that you could subscribe to and use as your start point
Thanks for your reply,
I’ve already tried to do that but some thing goes wrong.
what I want to do is to make an add-in that shows an alert for the user if he didn’t sync for 60 min and if he didn’t sync this alert shows repeatedly every 1 min till he sync I’ve tried a lot but didn’t get what I want.
Can I send you the source code and can you please help me with this?