Hi
Thanks for your reply! Your methodology suggestion did actually put me on the right path and I managed to make the tool working!
The problem was that my revLinkType parameter was not pointing to the right thing so the script didn't know what to reload. I fixed the issue by pairing the ModelPath and the RevitLinkType through the Zip and Tuple.Create methods. I think it might be a bit of an overkill but I'm not much of an expert right now so I'm just glad it works. Any suggestion/comment is more than welcome
I'm copying here my final working script so that everyone with the same issue can have a look and it will maybe help someone:
namespace BatchReloadRVTLinks { [Transaction(TransactionMode.Manual)] public class Command : IExternalCommand { public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { // Get application and document objects UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Autodesk.Revit.ApplicationServices.Application app = uiapp.Application; Autodesk.Revit.DB.Document doc = uidoc.Document; // NO TRANSACTION NEEDS TO BE OPENED try { using (Transaction tx = new Transaction(doc)) { // Collect files linked in current project FilteredElementCollector collector = new FilteredElementCollector(doc); ICollection<Element> linkInstances = collector.OfClass(typeof(RevitLinkType)).ToElements(); // Convert ICollection into a list of RevitLinkTypes List<RevitLinkType> revLinkType = new List<RevitLinkType>(); foreach (RevitLinkType i in linkInstances) { revLinkType.Add(i); } // Put names of linked files into a list of strings List<string> linkNames = new List<string>(); foreach (Element i in linkInstances) { linkNames.Add(i.Name.Split(' ')[0]); } // Prompt user with files selection dialog Start: OpenFileDialog openFileDialog1 = new OpenFileDialog(); openFileDialog1.InitialDirectory = (@"P:\"); openFileDialog1.Filter = "RVT|*.rvt"; openFileDialog1.Multiselect = true; openFileDialog1.RestoreDirectory = true; // If you select the files and hit OK (in the file browser) if (openFileDialog1.ShowDialog() == DialogResult.OK) { // Show which files (path + version) has been selected before linking them StringBuilder userSelectionWVersion = new StringBuilder(); foreach (string fp in openFileDialog1.FileNames) { userSelectionWVersion.AppendLine( fp.ToString() + " which was created with " + BasicFileInfo.Extract(fp).SavedInVersion.ToString().ToUpper()); } // Recap the user with his selection + Revit version of the file DialogResult linkCorrect = MessageBox.Show( userSelectionWVersion.ToString(), "You selected the files:", MessageBoxButtons.OKCancel); // Put paths of files selected by user into a list if (linkCorrect == DialogResult.OK) { List<string> userSelectionNames = new List<string>(); foreach (string fp in openFileDialog1.FileNames) { userSelectionNames.Add(fp.ToString()); } // Check which of the files that the user selected have the same name of the files linked in the project IEnumerable<string> elementsToReload = userSelectionNames.Where(a => linkNames.Exists(b => a.Contains(b))); // Show which files need to be reloaded StringBuilder intersection = new StringBuilder(); foreach (string fp in elementsToReload) { intersection.AppendLine(fp.ToString()); } DialogResult temp = MessageBox.Show(intersection.ToString(), "The following files need to be roloaded"); // Initialize + populate list of ModelPaths > path from where to reload List<ModelPath> modPaths = new List<ModelPath>(); foreach (string fp in elementsToReload) { FileInfo filePath = new FileInfo(fp); ModelPath linkpath = ModelPathUtils.ConvertUserVisiblePathToModelPath(filePath.ToString()); modPaths.Add(linkpath); } // Zip together file (as RevitLinkType) and the corresponding path to be reloaded from > Reload foreach(var ab in revLinkType.Zip(modPaths, Tuple.Create)) { ab.Item1.LoadFrom(ab.Item2, new WorksetConfiguration()); } } return Result.Succeeded; } catch (Exception ex) { // If something went wrong return Result.Failed DialogResult genericException = MessageBox.Show(ex.Message, "Oops there was problem!"); return Result.Failed; } } } }
Any comment is highly appreciated as it will help me get better in the future!
Also, find attached the test file I was using in case you guys want to give it a try.
PS do you know if there is a class/method to get the status of a linked file? (as it appears in the Manage Links window inside of Revit where it says Status = Not Loaded). This would help me optimise the script so I could reload only the files with the Not Loaded Status and avoid useless calculations for the files that are already correctly loaded.
Thanks again for the advice.
Ciao,
Andrea