I know nobody is checking the code I check into the RevitPythonShell code
repository, because nobody bothered to ask me about the new killer feature i
sneaked in. For a project at work that I used the RevitPythonShell for, the
need arose to deploy a bunch of scripts on a customers computer. Now, RPS
itself has a simple installer that you can execute and go next, next, next,
finish and voilĂ , you have RPS installed on your computer. But... any scripts
you write need to be copied to the customers computer, then RPS has to be
installed and configured to pick up the script. Oh, and don't forget to install
cpython and any modules you make use of.
Have you tried writing instructions for such a manual installation procedure? I
have. It is not fun at all! I have also tried to get people to execute these
instructions. It just doesn't fly.
This is where the new feature of RPS comes in: In the Ribbon, there is now an
additional button called "Deploy RpsAddin" that is located under the button for
starting the shell, just above the one for customizing RPS.
Deploying an RPS script as a standalone addin involves choosing an xml file
that acts as a manifest or package description of the addin you are about to
create. Basically, you describe which python scripts to assign to which
buttons and it creates a new dll for you that includes all these scripts and
can be used as an addin in Revit. You just need to write an addin manifest and
place it in the right position.
The source comes with an example addin called HelloWorld. That really is all it
does: a Button that prints "Hello, World!" to the screen. But I include the xml
deployment file and also an InnoSetup script to get you started on deploying
your own addins.
When you want to include a cpython library, you will need to make sure that
this is also in the search path of the addin's bundled interpreter. So, the
addin includes a bunch of files, dlls, a version of IronPython (2.7) and also
the new RpsRuntime dll that handles the parts of RPS that get used by both the
standard RPS version and deployed addins.
You can include cpython modules in your setup program, copying them for
instance into your installation directory and then go from there. There is an
equivalent of the
RevitPythonShell2013.xml file that gets deployed with
your addin to the
%AppData% folder that you can use for setting up stuff.
The structure of the deployment xml file looks like this: (I will call it RpsAddin xml file from now on)
<?xml version=" 1.0" encoding=" utf-8" ?>
<RpsAddin>
<RibbonPanel text=" Hello World">
<!-- the script is always searched relative to the location of the RpsAddin xml file -->
< PushButton text="Hello World! " src="helloworld.py "/>
</RibbonPanel>
</RpsAddin>
You can add as many RibbonPanel tags as you would like. Each PushButton is then
placed on that panel and assigned to the script. The path to the script is
relative to the RpsAddin xml file. The DLL that gets created is placed in a
folder "Output_YOUR_RPSADDIN_NAME" relative to the RpsAddin xml. The name of
your addin is taken from the name you call the RpsAddin xml file. In this case,
the file is called "HelloWorld.xml", so the Addin will be called "HelloWorld",
a folder "Output_HelloWorld" is created with the dll "HelloWorld.dll",
"RpsRuntime.dll" and a bunch of IronPython dlls.
You can then use an
InnoSetup file to create an installer for this. The
HelloWorld example comes with this file:
[Files]
Source: Output_HelloWorld\RpsRuntime.dll; DestDir: {app};
Source: Output_HelloWorld\IronPython.dll; DestDir: {app};
Source: Output_HelloWorld\IronPython.Modules.dll; DestDir: {app};
Source: Output_HelloWorld\Microsoft.Scripting.Metadata.dll; DestDir: {app};
Source: Output_HelloWorld\Microsoft.Dynamic.dll; DestDir: {app};
Source: Output_HelloWorld\Microsoft.Scripting.dll; DestDir: {app};
; this is the main dll with the script embedded
Source: Output_HelloWorld\HelloWorld.dll; DestDir: {app};
; add a similar line, if your addin requires a configuration file (search paths or predefined variables)
;Source: HelloWorld.xml; DestDir: {userappdata}\HelloWorld; Flags: onlyifdoesntexist;
[code]
{ install revit manifest file }
procedure CurStepChanged(CurStep: TSetupStep);
var
AddInFilePath: String;
AddInFileContents: String;
begin
if CurStep = ssPostInstall then
begin
{ GET LOCATION OF USER AppData (Roaming) }
AddInFilePath := ExpandConstant('{userappdata}\Autodesk\Revit\Addins\2013\HelloWorld.addin');
{ CREATE NEW ADDIN FILE }
AddInFileContents := '<?xml version="1.0" encoding="utf-8" standalone="no"?>' + #13#10;
AddInFileContents := AddInFileContents + '<RevitAddIns>' + #13#10;
AddInFileContents := AddInFileContents + ' <AddIn Type="Application">' + #13#10;
AddInFileContents := AddInFileContents + ' <Name>HelloWorld</Name>' + #13#10;
AddInFileContents := AddInFileContents + ' <Assembly>' + ExpandConstant('{app}') + '\HelloWorld.dll</Assembly>' + #13#10;
{ NOTE: create your own GUID here!!! }
AddInFileContents := AddInFileContents + ' <AddInId>276D41F2-CCC4-4B55-AF2A-47D30227F289</AddInId>' + #13#10;
AddInFileContents := AddInFileContents + ' <FullClassName>HelloWorld</FullClassName>' + #13#10;
{ NOTE: you should register your own VendorId with Autodesk }
AddInFileContents := AddInFileContents + ' <VendorId>RIPS</VendorId>' + #13#10;
AddInFileContents := AddInFileContents + ' </AddIn>' + #13#10;
AddInFileContents := AddInFileContents + '</RevitAddIns>' + #13#10;
SaveStringToFile(AddInFilePath, AddInFileContents, False);
end;
end;
{ uninstall revit addin manifest }
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
AddInFilePath: String;
begin
if CurUninstallStep = usPostUninstall then
begin
AddInFilePath := ExpandConstant('{userappdata}\Autodesk\Revit\Addins\2013\HelloWorld.addin');
if FileExists(AddInFilePath) then
begin
DeleteFile(AddInFilePath);
end;
end;
end;
[Setup]
AppName=HelloWorld
AppVerName=HelloWorld
RestartIfNeededByRun=false
DefaultDirName={pf32}\HelloWorld
OutputBaseFilename=Setup_HelloWorld
ShowLanguageDialog=auto
FlatComponentsList=false
UninstallFilesDir={app}\Uninstall
UninstallDisplayName=HelloWorld
AppVersion=2012.0
VersionInfoVersion=2012.0
VersionInfoDescription=HelloWorld
VersionInfoTextVersion=HelloWorld
I included some Pascal code for installing an addin manifest to the
%APPDATA%
folder. This is generally something like
C:\Users\username\AppData\Roaming\ADDIN_NAME. Running this setup will
produce a file called
Setup_Helloworld.exe that can then be given to your
friends to try out your new cool HelloWorld Revit Addin, coded in the sweet
python language we all love so much!