I want to deploy a plugin to all my office colleagues at once called Librarian.
I would like to move the necessary files (.xml and contents folder) inside a button folder because we are developing an internal Pyrevit tab full of scripts and utilities and running it from inside.
# This line specifies the path to the DLL file of the Librarian add-in
__assembly__ = r'C:\ProgramData\Autodesk\ApplicationPlugins\Librarian.bundle\Contents\2024\Librarian.dll'
# This line specifies the class within the DLL that should be executed
__command_class__ = 'Librarian.LibrarianExternalApp'
# Optional metadata
__title__ = 'Librarian'
__author__ = 'spicetools'
__helpurl__ = 'https://spicetools.blogspot.com/p/librarian.html'
This file is located inside a folder called Librarian.linkbutton alongside a icon.png file.
So now I have a folder called Librarian.invokebutton that contains:
icon.png
bundle.yaml:
# This line specifies the path to the DLL file of the Librarian add-in
__assembly__ = r'C:\ProgramData\Autodesk\ApplicationPlugins\Librarian.bundle\Contents\2024\Librarian.dll'
# This line specifies the class within the DLL that should be executed
__command_class__ = 'Librarian.LibrarianExternalApp'
# Optional metadata
__title__ = 'Librarian'
__author__ = 'spicetools'
__helpurl__ = 'https://spicetools.blogspot.com/p/librarian.html'
title: Test Link Button (Custom Title)
tooltip: Test Link Button Tooltip
author: "{{author}}"
highlight: new
assembly: 'C:\ProgramData\Autodesk\ApplicationPlugins\Librarian.bundle\Contents\2024\Librarian.dll'
command_class: LibrarianExternalApp
The fact is that when I try to run it (from pyrevit) the script returns me this error:
A simple pushbutton with this script.py inside could theoretically work?
from Autodesk.Revit.UI import RevitCommandId, PostableCommand, UIApplication
from pyrevit import script
# Function to execute the Librarian command
def execute_librarian_command():
# Define the command name as found in the journal file
command_name = "CustomCtrl_%CustomCtrl_%CustomCtrl_%Add-Ins%SPICETOOLS%RUTILITIES%Librarian:Librarian.ExternalCommands.CommandToggleDockVisibility"
# Get the current Revit UIDocument and UIApplication
uidoc = __revit__.ActiveUIDocument
uiapp = __revit__.Application
# Attempt to find the command by its name
command_id = RevitCommandId.LookupCommandId(command_name)
if command_id and uiapp.CanPostCommand(command_id):
# If the command is found and can be posted, execute it
uiapp.PostCommand(command_id)
else:
# If the command cannot be found or executed, print a message
print("Command not found or not executable: " + command_name)
# Execute the function
execute_librarian_command()
IronPython Traceback:
Traceback (most recent call last):
File “P:\GESTIONE PROGETTI PARK\BIM\24 pyRevit\Parkour_dev\Parkour_dev C24.extension\Parkour_dev.tab\Families.panel\Librarian.pushbutton\script.py”, line 6, in
AttributeError: ‘NoneType’ object has no attribute ‘Id’
Script Executor Traceback:
System.MissingMemberException: ‘NoneType’ object has no attribute ‘Id’
at Microsoft.Scripting.Interpreter.ThrowInstruction.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run3[T0,T1,T2,TRet](T0 arg0, T1 arg1, T2 arg2)
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at Microsoft.Scripting.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)
at IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx)
at PyRevitLabs.PyRevit.Runtime.IronPythonEngine.Execute(ScriptRuntime& runtime)
It means this command does not have a CommandId as it is not found with the lookup function.
I checked installing the Librarian addin. The command name of what you are looking for is right but it is an external command that does not map to keyboard shortcuts, which is usually an indicator that it is not possible to call it through the PostCommand or find it with the LookupCommanId
So after some trial and error, this code seems to work fine:
bundle.yaml
title: Test Link Button (Custom Title)
tooltip: Test Link Button Tooltip
author: "{{author}}"
highlight: new
assembly: 'C:\ProgramData\Autodesk\ApplicationPlugins\Librarian.bundle\Contents\2023\Librarian.dll'
command_class: ExternalCommands.CommandToggleDockVisibility