无法禁用已集成的Revit Updater功能的技术求助
问题描述
始终无法禁用已集成到应用中的Updater功能,推测是转换操作存在错误。仅需禁用已集成的Updater功能,以下是相关代码:
应用初始化代码
try { UtilsAssemblyLock.AssemblyLockUpdaterId assemblyLockUpdater = new UtilsAssemblyLock.AssemblyLockUpdaterId(application .ActiveAddInId); UpdaterRegistry.RegisterUpdater(assemblyLockUpdater, true); UpdaterRegistry.AddTrigger( assemblyLockUpdater.GetUpdaterId(), new ElementClassFilter(typeof(FabricationPart)), Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.FABRICATION_PART_WEIGHT))); UtilsAssemblyLock.assemblyLockedFailureId = new FailureDefinitionId(Guid.NewGuid()); FailureDefinition.CreateFailureDefinition( UtilsAssemblyLock.assemblyLockedFailureId, FailureSeverity.Error, "S.A.I.: \n" + "Cannot edit assembly without permission."); } catch (Exception ex3) { MessageBox.Show(ex3.Message); return Result.Cancelled; }
工具类代码
public class UtilsAssemblyLock { public static FailureDefinitionId assemblyLockedFailureId; public class AssemblyLockUpdaterId : IUpdater { private readonly UpdaterId assemblyLockUpdaterId; private FabricationDimensionDefinition _dimensionDefinition; public AssemblyLockUpdaterId(AddInId id) { assemblyLockUpdaterId = new UpdaterId(id, new Guid("7595F412-275B-4F65-A354-7F9CB439283B")); } public void Execute(UpdaterData data) { try { Document doc = data.GetDocument(); List<ElementId> ids = new List<ElementId>(); ids.AddRange(data.GetAddedElementIds()); ids.AddRange(data.GetModifiedElementIds()); ids.AddRange(data.GetDeletedElementIds()); foreach (ElementId id in ids) { if (doc.GetElement(id) is FabricationPart fabricationPart) { if (!data.IsChangeTriggered(id, Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.FABRICATION_PART_WEIGHT)))) { break; } if (!fabricationPart.IsValidObject) continue; #region Elements Are Assembled if (!fabricationPart.AssemblyInstanceId.IsNull()) { Console.Beep(); AssemblyPassword assemblyPasswordForm = new AssemblyPassword(); assemblyPasswordForm.ShowDialog(); if (assemblyPasswordForm.assemblyPasswordEntry() == "1234" || assemblyPasswordForm.assemblyPasswordEntry() == "abcd") { } else { FailureMessage failureMessage = new FailureMessage(assemblyLockedFailureId); failureMessage.SetFailingElement(id); doc.PostFailure(failureMessage); } } #endregion } } } catch (Exception ex) { MessageBox.Show(ex.Message); } } public UpdaterId GetUpdaterId() { UpdaterId id = assemblyLockUpdaterId; return (id); } public ChangePriority GetChangePriority() { return ChangePriority.MEPSystems; } public string GetUpdaterName() { return "Fabrication Assembly Updater"; } public string GetAdditionalInformation() { return "Fabrication Pipe Assembly updater example: checks to make sure Pipe that has been assembled " + "is not edited."; } } }
禁用命令代码
{ [Transaction(TransactionMode.Manual)] //[Journaling(JournalingMode.NoCommandData)] public class DisableAssemblyLock : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { var transaction = new Transaction(commandData.Application.ActiveUIDocument.Document, "Disable Assembly Lock"); using (transaction) { if (transaction.Start() == TransactionStatus.Started) { try { UpdaterRegistry.DisableUpdater(new AssemblyLockUpdaterId(commandData.Application.ActiveAddInId)); } catch (Exception e) { MessageBox.Show(e.Message); return Result.Failed; } finally { transaction.Commit(); } } return Result.Succeeded; } } } }
问题分析与解决方案
核心问题
- 不必要的事务包裹:UpdaterRegistry的启用/禁用操作属于应用级配置,不需要放在文档事务中,事务会干扰该操作的执行逻辑。
- 实例匹配问题:通过新建
AssemblyLockUpdaterId实例来禁用,虽然内部的UpdaterId使用了相同的Guid,但部分场景下Revit的UpdaterRegistry无法正确识别新实例与已注册实例的关联。
修正后的禁用命令代码
移除事务包裹,并直接通过固定的UpdaterId标识来禁用目标Updater:
[Transaction(TransactionMode.Manual)] public class DisableAssemblyLock : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { try { // 直接使用注册时的UpdaterId标识来定位并禁用 var targetUpdaterId = new UpdaterId( commandData.Application.ActiveAddInId, new Guid("7595F412-275B-4F65-A354-7F9CB439283B")); if (UpdaterRegistry.IsUpdaterRegistered(targetUpdaterId)) { UpdaterRegistry.DisableUpdater(targetUpdaterId); MessageBox.Show("Updater已成功禁用"); } else { MessageBox.Show("目标Updater未注册"); } } catch (Exception e) { MessageBox.Show($"禁用失败:{e.Message}"); return Result.Failed; } return Result.Succeeded; } }
额外优化建议
- 在初始化注册Updater时,可将
UpdaterId保存为静态变量,禁用时直接复用该变量,避免重复构造Guid。 - 添加
IsUpdaterRegistered检查,提前判断目标Updater状态,提升代码容错性。
内容的提问来源于stack exchange,提问作者nhilson
相关产品推荐
相关产品推荐

