Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
226 commits
Select commit Hold shift + click to select a range
0ecc3de
feat: add pyRevitAssemblyBuilder project to the Loader solution
romangolev Apr 10, 2025
723821c
feat: make assembly put dlls in a correct folder, scanning all availa…
romangolev Apr 11, 2025
355f92e
feat: implement recursive UI builder
romangolev Apr 11, 2025
847c246
fix: UIManagerServite to handle stacked pulldowns correctly
romangolev Apr 14, 2025
fc104aa
feat: update build dlls
romangolev Apr 14, 2025
f659f49
feat: replace DI architecture with plain intantiating of services. re…
romangolev Apr 16, 2025
c916a4a
feat: implement pyRevitExtensionParser csproject
romangolev Apr 18, 2025
aa4fc9d
feat: update dlls
romangolev Apr 18, 2025
aea0787
feat: change unique id to mimic pythonic one, add logic to CommandTyp…
romangolev Apr 18, 2025
41a5955
feat: change assembly generation module to Roslyn
romangolev Apr 20, 2025
2fc4643
feat: mvp c# loader
romangolev Apr 21, 2025
81efe9a
fix: move enums to parser, simplify code by removing wraps
romangolev Apr 23, 2025
3886911
undate binaries
romangolev Apr 23, 2025
038fd01
Switch for .net core Desktop connector API
jmcouffin Apr 11, 2025
e93db34
fix: is_schedule
leyarx Apr 11, 2025
ae30736
Update pyrevit-hosts.json 2026.0.1
jmcouffin Apr 14, 2025
bb06cdc
Update Directory.Build.targets
jmcouffin Apr 14, 2025
987570d
upd
nodatasheet Feb 8, 2024
4ead9b0
add Associated to Others to select_family_parameters
nodatasheet Apr 12, 2025
b6dda98
cleanup
nodatasheet Apr 12, 2025
2972ffc
Update __init__.py
jmcouffin Apr 14, 2025
0ba9785
Adding exitscript option to SelectFromList from pyrevit.forms
iorhanV Apr 10, 2025
52b9424
Update __init__.py - exitscritp handeled in show method
jmcouffin Apr 14, 2025
7f5eadb
Bump golang.org/x/crypto
dependabot[bot] Apr 14, 2025
3fb7b20
fixes commit f81f483
jmcouffin Apr 16, 2025
db6510d
Update __init__.py
jmcouffin Apr 16, 2025
736cfed
Update go.mod mongodb driver
jmcouffin Apr 16, 2025
6ccc8c1
Update go.mod
jmcouffin Apr 16, 2025
8ae818e
missing comma in the docs for CommandSwitchWindow
jonatanjacobsson Apr 17, 2025
4e98317
feat: add pyRevitAssemblyBuilder project to the Loader solution
romangolev Apr 10, 2025
80f6ccf
feat: make assembly put dlls in a correct folder, scanning all availa…
romangolev Apr 11, 2025
1d6da91
feat: implement recursive UI builder
romangolev Apr 11, 2025
fa8fc2b
fix: UIManagerServite to handle stacked pulldowns correctly
romangolev Apr 14, 2025
ba7d564
feat: update build dlls
romangolev Apr 14, 2025
6964633
feat: replace DI architecture with plain intantiating of services. re…
romangolev Apr 16, 2025
46bdaa9
feat: implement pyRevitExtensionParser csproject
romangolev Apr 18, 2025
0546001
feat: update dlls
romangolev Apr 18, 2025
cffdb8a
feat: change unique id to mimic pythonic one, add logic to CommandTyp…
romangolev Apr 18, 2025
b686515
feat: change assembly generation module to Roslyn
romangolev Apr 20, 2025
33b3d75
feat: mvp c# loader
romangolev Apr 21, 2025
18ecf76
fix: move enums to parser, simplify code by removing wraps
romangolev Apr 23, 2025
e8e445a
undate binaries
romangolev Apr 23, 2025
4acf0a9
feat: add a switcher in settings to be able to toglle between python …
romangolev Apr 24, 2025
84ee64b
update dlls
romangolev Apr 24, 2025
1c90cac
merge conflict
romangolev Apr 24, 2025
1b92a55
fix: remove unused dlls
romangolev Apr 25, 2025
f408e57
feat: get back ILPack method for generating assemblies, make a switch…
romangolev Apr 25, 2025
869ed85
update dlls
romangolev Apr 25, 2025
27ca06d
feat: implement availability class generator
romangolev May 3, 2025
2f9b799
fix: improve parsing logic, move command collector to ParsedExtension…
romangolev May 3, 2025
88f0223
upd dlls
romangolev May 3, 2025
b202aa1
feat: parse bundle.yaml and reorder UI Components
romangolev May 6, 2025
525f2f6
fix: use Display name insted of truncated Name for ParsedComponents
romangolev May 7, 2025
3e8596d
feat: add testing bench for parser; add support for slideout
romangolev May 14, 2025
3ca0f22
fix: make sure UI is generated correctly and buttons are executed
romangolev May 15, 2025
faaa8e6
add 2 swichable parameters to settings
romangolev Jun 12, 2025
f785799
fix: clean-up and use config files only
romangolev Jun 16, 2025
aef99de
feat: add support for PanelButtons
romangolev Jun 24, 2025
1f65b01
update dlls
romangolev Jun 24, 2025
1a6ff56
feat: parse title and name with ExtensionParser
romangolev Jul 5, 2025
b46c55b
chore: make a parser for extensions, move config to ExtensionParser
romangolev Jul 6, 2025
b999f2f
fix: read parsed data from script.py correctly
romangolev Jul 8, 2025
ad13740
chore: support parsing for some other configs, split config in 2 files
romangolev Jul 8, 2025
185b0e2
chore: refactor ExtensionParser and implement the logic for loading c…
romangolev Jul 13, 2025
8e5e1f1
feat: improve bundle parser and make it read localized versions of to…
romangolev Sep 28, 2025
35a3633
fix: make all pushbuttons show tooltip
romangolev Sep 28, 2025
8057962
chore: add tests for pulldown component, implement fixes for tooltip …
romangolev Sep 28, 2025
d0168ce
chore: make tests work and make sure they read testing bundle
romangolev Sep 28, 2025
283b4e6
update wip dlls
romangolev Sep 28, 2025
3544d22
chore: refactor tests; tests are now using test bundle
romangolev Oct 8, 2025
917d222
fix: adapt test to check the parser
romangolev Oct 9, 2025
073ac77
feat: enrich test bundle
romangolev Oct 9, 2025
511a8f5
feat: implement icons testing and add test to check the parser
romangolev Oct 9, 2025
f00d80e
fix: make sure the yaml props override defaults from bundle correctly
romangolev Oct 10, 2025
f87944a
feat: implement support for images in UIManager
romangolev Oct 10, 2025
00a5d96
fix: sanitize name to match the command parser logic
romangolev Oct 29, 2025
317d884
feat: parse dark icons
romangolev Oct 29, 2025
8ae47e2
feat: link the image determined with the parser
romangolev Oct 29, 2025
c01af21
fix: correctly detect current Revit theme
romangolev Nov 4, 2025
a5068ae
fix: netfx silent execution bug eliminated
romangolev Nov 5, 2025
d0101c1
chore: adjust props and targets for the pipeline
romangolev Nov 5, 2025
7abde0f
fix: mind the quotes while parsing bundles
romangolev Nov 5, 2025
9968c49
fix: adjust correctly sizes for pulldown images
romangolev Nov 5, 2025
f9416e3
feat: add context feature for the button
romangolev Nov 5, 2025
30b0c75
feat: add a method that writes to the pyRevit output window
romangolev Nov 5, 2025
b071d73
refactor: restore the loading order and call new loader pythonic way
romangolev Nov 5, 2025
0559d77
chore: rebuild dlls
romangolev Nov 5, 2025
708f0a7
feat: add startup script parser
romangolev Nov 10, 2025
de410a3
fix: remedy warnings
romangolev Nov 10, 2025
87f0f48
feat: implement hashing method for dll creation
romangolev Nov 11, 2025
3668d5b
chore: add description for the section of the loading settings
romangolev Nov 13, 2025
d970046
fix: handle nullable cases for the type generator
romangolev Nov 13, 2025
0882b38
fix: add a random seed in order for c# dlls differ from python
romangolev Nov 14, 2025
10bf5cc
feat: add support for lib folders and extensions
romangolev Nov 14, 2025
fbe8a93
fix: make a new line symbol to be parsed for title
romangolev Nov 14, 2025
4c7c940
feat: add support for dividers
romangolev Nov 14, 2025
ddae5b8
feat: add support for urlbutton
romangolev Nov 14, 2025
a28928a
fix: make hashing mechanism distinguish different types of buidls
romangolev Nov 14, 2025
fa401e4
feat: add highlight option to the parser
romangolev Nov 15, 2025
d3de63d
fix: process slideouts by >>> pattern
romangolev Nov 15, 2025
9a66391
feat: implement background support
romangolev Nov 15, 2025
06aa085
feat: add support for start-up scripts
romangolev Nov 15, 2025
1713883
feat: add support for invoke buttons and parse binaries
romangolev Nov 15, 2025
79aa50c
fix: ensure that icons are propagated to child components for pulldowns
romangolev Nov 15, 2025
42c498b
feat: add support for custom overriding title from layout panel
romangolev Nov 15, 2025
a4b45c9
feat: add support for c# scripts and modules support
romangolev Nov 16, 2025
d4c0cb6
feat: add support for linkbutton
romangolev Nov 16, 2025
3708082
refactor: code optimization
romangolev Nov 16, 2025
94e97b8
refactor: improve logging
romangolev Nov 16, 2025
6e52f48
chore: upd dlls
romangolev Nov 16, 2025
e26fa8d
fix: about script name
jmcouffin Nov 17, 2025
78b2916
feat: enhance session management with build strategy support and impr…
jmcouffin Nov 17, 2025
8b5b8e6
chore: update binary files for pyRevit and related libraries
jmcouffin Nov 17, 2025
2fe5ddc
fix: use pythonic logger wrapper in loader to make logging consistent
romangolev Nov 20, 2025
555e427
feat: add support for dyn scripts, add support for engine settings in…
romangolev Nov 20, 2025
13aa78c
fix: correctly bridge logger to the c# loader
romangolev Nov 20, 2025
ce6e846
fix: preserve case and strip quotes for engine path settings in bundl…
romangolev Nov 23, 2025
aa56784
fix: multiple fixes for loader
romangolev Nov 23, 2025
d469267
style: fix the warnings
romangolev Nov 23, 2025
d18412c
fix: parse newline correctly for UI and make divider to be applied co…
romangolev Nov 23, 2025
a9ad8c7
chore: refactor tests
romangolev Nov 23, 2025
8b0c5c2
refactor: small refactor and in-line docs
romangolev Nov 23, 2025
8cc3695
chore: update dlls
romangolev Nov 23, 2025
6d2d33a
feat: add pyRevitAssemblyBuilder project to the Loader solution
romangolev Apr 10, 2025
acf9ca6
feat: make assembly put dlls in a correct folder, scanning all availa…
romangolev Apr 11, 2025
e7a1652
feat: implement recursive UI builder
romangolev Apr 11, 2025
3ac8e84
fix: UIManagerServite to handle stacked pulldowns correctly
romangolev Apr 14, 2025
6a11c3c
feat: update build dlls
romangolev Apr 14, 2025
cbb0dd1
feat: replace DI architecture with plain intantiating of services. re…
romangolev Apr 16, 2025
9dcac91
feat: implement pyRevitExtensionParser csproject
romangolev Apr 18, 2025
84293a9
feat: update dlls
romangolev Apr 18, 2025
524760a
feat: change unique id to mimic pythonic one, add logic to CommandTyp…
romangolev Apr 18, 2025
117d1e5
feat: change assembly generation module to Roslyn
romangolev Apr 20, 2025
0db108d
feat: mvp c# loader
romangolev Apr 21, 2025
32b6e59
fix: move enums to parser, simplify code by removing wraps
romangolev Apr 23, 2025
80a3275
undate binaries
romangolev Apr 23, 2025
efecce3
upd
nodatasheet Feb 8, 2024
2a29139
cleanup
nodatasheet Apr 12, 2025
6811bdd
Adding exitscript option to SelectFromList from pyrevit.forms
iorhanV Apr 10, 2025
1afb551
Update __init__.py - exitscritp handeled in show method
jmcouffin Apr 14, 2025
6978597
fixes commit f81f483
jmcouffin Apr 16, 2025
b597854
Update __init__.py
jmcouffin Apr 16, 2025
6d01e12
Update go.mod
jmcouffin Apr 16, 2025
3a23ee1
feat: add a switcher in settings to be able to toglle between python …
romangolev Apr 24, 2025
4e5c613
update dlls
romangolev Apr 24, 2025
c181f00
feat: add pyRevitAssemblyBuilder project to the Loader solution
romangolev Apr 10, 2025
16eadda
feat: make assembly put dlls in a correct folder, scanning all availa…
romangolev Apr 11, 2025
74064e9
feat: implement recursive UI builder
romangolev Apr 11, 2025
fdc7639
fix: UIManagerServite to handle stacked pulldowns correctly
romangolev Apr 14, 2025
4411154
feat: replace DI architecture with plain intantiating of services. re…
romangolev Apr 16, 2025
380c6be
feat: implement pyRevitExtensionParser csproject
romangolev Apr 18, 2025
1d6b0b1
feat: change unique id to mimic pythonic one, add logic to CommandTyp…
romangolev Apr 18, 2025
04f932a
feat: change assembly generation module to Roslyn
romangolev Apr 20, 2025
9c45ccf
feat: mvp c# loader
romangolev Apr 21, 2025
fb32407
fix: move enums to parser, simplify code by removing wraps
romangolev Apr 23, 2025
8ee95b1
fix: remove unused dlls
romangolev Apr 25, 2025
f4201ef
feat: get back ILPack method for generating assemblies, make a switch…
romangolev Apr 25, 2025
e88d970
update dlls
romangolev Apr 25, 2025
21f390e
feat: implement availability class generator
romangolev May 3, 2025
9d52ec3
fix: improve parsing logic, move command collector to ParsedExtension…
romangolev May 3, 2025
817862f
upd dlls
romangolev May 3, 2025
85f2ca8
feat: parse bundle.yaml and reorder UI Components
romangolev May 6, 2025
9e4e011
fix: use Display name insted of truncated Name for ParsedComponents
romangolev May 7, 2025
98aca03
feat: add testing bench for parser; add support for slideout
romangolev May 14, 2025
4bb534d
fix: make sure UI is generated correctly and buttons are executed
romangolev May 15, 2025
e9f968e
add 2 swichable parameters to settings
romangolev Jun 12, 2025
ba3b87f
fix: clean-up and use config files only
romangolev Jun 16, 2025
d53bb79
feat: add support for PanelButtons
romangolev Jun 24, 2025
aa7760f
update dlls
romangolev Jun 24, 2025
8052c17
feat: parse title and name with ExtensionParser
romangolev Jul 5, 2025
1cf9ea8
chore: make a parser for extensions, move config to ExtensionParser
romangolev Jul 6, 2025
356db9f
fix: read parsed data from script.py correctly
romangolev Jul 8, 2025
38d8931
chore: support parsing for some other configs, split config in 2 files
romangolev Jul 8, 2025
8ef477e
chore: refactor ExtensionParser and implement the logic for loading c…
romangolev Jul 13, 2025
76f8aaa
feat: improve bundle parser and make it read localized versions of to…
romangolev Sep 28, 2025
adaab3d
fix: make all pushbuttons show tooltip
romangolev Sep 28, 2025
5f43a93
chore: add tests for pulldown component, implement fixes for tooltip …
romangolev Sep 28, 2025
993d3c8
chore: make tests work and make sure they read testing bundle
romangolev Sep 28, 2025
ab894a5
update wip dlls
romangolev Sep 28, 2025
dc7b6ad
chore: refactor tests; tests are now using test bundle
romangolev Oct 8, 2025
422499b
fix: adapt test to check the parser
romangolev Oct 9, 2025
8733537
feat: enrich test bundle
romangolev Oct 9, 2025
3e58f03
feat: implement icons testing and add test to check the parser
romangolev Oct 9, 2025
2cb20af
fix: make sure the yaml props override defaults from bundle correctly
romangolev Oct 10, 2025
9512628
feat: implement support for images in UIManager
romangolev Oct 10, 2025
d75efb3
fix: sanitize name to match the command parser logic
romangolev Oct 29, 2025
dc619dd
feat: parse dark icons
romangolev Oct 29, 2025
8ec1af5
feat: link the image determined with the parser
romangolev Oct 29, 2025
1f356f5
fix: correctly detect current Revit theme
romangolev Nov 4, 2025
2b08baa
fix: netfx silent execution bug eliminated
romangolev Nov 5, 2025
4b470fc
chore: adjust props and targets for the pipeline
romangolev Nov 5, 2025
d1c0c1f
fix: mind the quotes while parsing bundles
romangolev Nov 5, 2025
2d8f2b0
fix: adjust correctly sizes for pulldown images
romangolev Nov 5, 2025
2b928e4
feat: add context feature for the button
romangolev Nov 5, 2025
93ca394
feat: add a method that writes to the pyRevit output window
romangolev Nov 5, 2025
56c1e81
refactor: restore the loading order and call new loader pythonic way
romangolev Nov 5, 2025
3bf321b
chore: rebuild dlls
romangolev Nov 5, 2025
1f87056
feat: add startup script parser
romangolev Nov 10, 2025
aed046a
fix: remedy warnings
romangolev Nov 10, 2025
f9db957
feat: implement hashing method for dll creation
romangolev Nov 11, 2025
fb68dc5
chore: add description for the section of the loading settings
romangolev Nov 13, 2025
57903f6
fix: handle nullable cases for the type generator
romangolev Nov 13, 2025
e50cc76
fix: add a random seed in order for c# dlls differ from python
romangolev Nov 14, 2025
3e2b4e2
feat: add support for lib folders and extensions
romangolev Nov 14, 2025
df9c3a6
fix: make a new line symbol to be parsed for title
romangolev Nov 14, 2025
ca65de4
feat: add support for dividers
romangolev Nov 14, 2025
d31dab3
feat: add support for urlbutton
romangolev Nov 14, 2025
13a930a
fix: make hashing mechanism distinguish different types of buidls
romangolev Nov 14, 2025
a80f173
feat: add highlight option to the parser
romangolev Nov 15, 2025
95f779c
fix: process slideouts by >>> pattern
romangolev Nov 15, 2025
4abd568
feat: implement background support
romangolev Nov 15, 2025
5ddb267
feat: add support for start-up scripts
romangolev Nov 15, 2025
cbdb606
feat: add support for invoke buttons and parse binaries
romangolev Nov 15, 2025
faa76de
fix: ensure that icons are propagated to child components for pulldowns
romangolev Nov 15, 2025
ea52196
feat: add support for custom overriding title from layout panel
romangolev Nov 15, 2025
c612301
feat: add support for c# scripts and modules support
romangolev Nov 16, 2025
4a97a83
feat: add support for linkbutton
romangolev Nov 16, 2025
be7d2a1
refactor: code optimization
romangolev Nov 16, 2025
e01bfdb
refactor: improve logging
romangolev Nov 16, 2025
68788a4
chore: upd dlls
romangolev Nov 16, 2025
ad8e74f
fix: about script name
jmcouffin Nov 17, 2025
d4f3f32
feat: enhance session management with build strategy support and impr…
jmcouffin Nov 17, 2025
f17dbe4
chore: update binary files for pyRevit and related libraries
jmcouffin Nov 17, 2025
2d91df9
Merge branch 'develop-2023-11-23' into develop
romangolev Nov 24, 2025
bc7c247
fix: resolve merge properly
romangolev Nov 24, 2025
dd8a60d
chore: dlls
romangolev Nov 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
Binary file modified bin/netcore/engines/IPY2712PR/pyRevitLabs.Microsoft.Dynamic.dll
Binary file not shown.
Binary file modified bin/netcore/engines/IPY2712PR/pyRevitLoader.dll
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified bin/netcore/engines/IPY342/pyRevitLoader.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.Common.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.CommonWPF.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.PyRevit.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.TargetApps.Revit.dll
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified bin/netfx/engines/IPY2712PR/pyRevitLoader.dll
Binary file not shown.
Binary file modified bin/netfx/engines/IPY2712PR/pyRevitRunner.dll
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added bin/netfx/engines/IPY342/System.ValueTuple.dll
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified bin/netfx/engines/IPY342/pyRevitLoader.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.Common.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.CommonWPF.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.PyRevit.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.TargetApps.Revit.dll
Binary file not shown.
2 changes: 0 additions & 2 deletions dev/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputType>Library</OutputType>
<!-- <TargetFramework>net48</TargetFramework>-->
<!-- <TargetFrameworks>net48;net8.0-windows</TargetFrameworks>-->
<PlatformTarget>x64</PlatformTarget>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
Expand Down
10 changes: 8 additions & 2 deletions dev/pyRevitLabs.PyRevit.Runtime/ScriptCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,16 @@ public Result Execute(ExternalCommandData commandData, ref string message, Eleme

// 3: ----------------------------------------------------------------------------------------------------
#region Execute and log results

// Executing the script and logging the results
// Get script executor and Execute the script
var env = new EnvDictionary();
int result = ScriptExecutor.ExecuteScript(
int result = -1;

// Initialize ScriptExecutor before executing scripts
ScriptExecutor.Initialize();

// Execute the script
result = ScriptExecutor.ExecuteScript(
ScriptData,
ScriptRuntimeConfigs,
new ScriptExecutorConfigs {
Expand Down
6 changes: 6 additions & 0 deletions dev/pyRevitLabs/pyRevitLabs.PyRevit/PyRevitConsts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ public static class PyRevitConsts {
public const string BundleScriptGrasshopperXPostfix = ".ghx";
public const string BundleScriptRevitFamilyPostfix = ".rfa";

// loader settings
public const string ConfigsNewLoaderKey = "new_loader";
public const bool ConfigsNewLoaderDefault = false;
public const string ConfigsUseRoslynKey = "use_roslyn_loader";
public const bool ConfigsUseRoslynDefault = false;

// theme
public static SolidColorBrush PyRevitAccentBrush = new SolidColorBrush(Color.FromArgb(0xFF, 0xf3, 0x9c, 0x12));
public static SolidColorBrush PyRevitBackgroundBrush = new SolidColorBrush(Color.FromArgb(0xFF, 0x2c, 0x3e, 0x50));
Expand Down
4 changes: 2 additions & 2 deletions dev/pyRevitLoader/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PropertyGroup Condition="'$(MSBuildProjectName)' != 'pyRevitAssemblyBuilder'">
<UseRevit>true</UseRevit>
<UseWpf>true</UseWpf>
<UseWindowsForms>true</UseWindowsForms>
<UseAssemblyBuilder Condition="'$(MSBuildProjectName)' != 'pyRevitLoader.2712PR' AND '$(MSBuildProjectName)' != 'pyRevitLoader.342'">true</UseAssemblyBuilder>
<TargetFrameworks>net48;net8.0-windows</TargetFrameworks>

<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>

Expand Down
58 changes: 49 additions & 9 deletions dev/pyRevitLoader/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<None Remove="obj\**" />
</ItemGroup>

<ItemGroup Condition="$(UseRunner)=='' OR $(UseRunner)==False">
<ItemGroup Condition="$(UseLoader)==True">
<Compile Include="..\Source\PyRevitLoaderApplication.cs" Link="Source\PyRevitLoaderApplication.cs"/>
<Compile Include="..\Source\ScriptExecutor.cs" Link="Source\ScriptExecutor.cs"/>
</ItemGroup>
Expand All @@ -17,7 +17,7 @@
<Compile Include="..\Source\ScriptExecutor.cs" Link="Source\ScriptExecutor.cs"/>
</ItemGroup>

<ItemGroup Condition="$(IronPythonVersion.Contains('PR'))">
<ItemGroup Condition="'$(UseIronPython)' != 'false' AND $(IronPythonVersion.Contains('PR'))">
<Reference Include="IronPython" HintPath="$(PyRevitEnginesDir)\$(IronPythonVersion)\pyRevitLabs.IronPython.dll"/>
<Reference Include="IronPython.Modules" HintPath="$(PyRevitEnginesDir)\$(IronPythonVersion)\pyRevitLabs.IronPython.Modules.dll"/>
<Reference Include="IronPython.SQLite" HintPath="$(PyRevitEnginesDir)\$(IronPythonVersion)\pyRevitLabs.IronPython.SQLite.dll"/>
Expand All @@ -26,27 +26,67 @@
<Reference Include="Microsoft.Scripting" HintPath="$(PyRevitEnginesDir)\$(IronPythonVersion)\pyRevitLabs.Microsoft.Scripting.dll"/>
</ItemGroup>

<ItemGroup Condition="!$(IronPythonVersion.Contains('PR'))">
<ItemGroup Condition="'$(UseIronPython)' != 'false' AND !$(IronPythonVersion.Contains('PR'))">
<PackageReference Include="IronPython" Version="$(Version)"/>
</ItemGroup>

<ItemGroup>
<Reference Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" Include="Microsoft.CSharp"/>
</ItemGroup>

<ItemGroup>

<ItemGroup Condition="'$(UseAssemblyBuilder)' == 'true'">
<ProjectReference Include="..\pyRevitAssemblyBuilder\pyRevitAssemblyBuilder.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(UseExtensionParser)' == 'true'">
<ProjectReference Include="..\pyRevitExtensionParser\pyRevitExtensionParser.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(UseIronPython)' != 'false'">
<EmbeddedResource Include="$(IronPythonStdLibDir)\$(IronPythonStdLib)"/>
</ItemGroup>


<ItemGroup Condition="'$(UseRoslyn)' == 'true'">
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.13.0" />
</ItemGroup>

<ItemGroup Condition="'$(UseILPack)' == 'true'">
<PackageReference Include="Lokad.ILPack" Version="0.3.0" ExcludeAssets="runtime" />
</ItemGroup>

<Target Name="Deploy" AfterTargets="AfterBuild">
<ItemGroup>
<AllFilesToCopy Include="$(TargetDir)\**\*.dll"
Exclude="$(TargetDir)\**\Xceed.Wpf.AvalonDock.dll" />
Exclude="$(TargetDir)\**\Xceed.Wpf.AvalonDock.dll;
$(TargetDir)\**\Microsoft.CodeAnalysis.dll;
$(TargetDir)\**\Microsoft.CodeAnalysis.CSharp.dll;
$(TargetDir)\**\Microsoft.CodeAnalysis.CSharp.resources.dll;
$(TargetDir)\**\Microsoft.CodeAnalysis.resources.dll;
$(TargetDir)\**\System.*.dll"
Condition="'$(IsTestProject)' != 'true'"/>
</ItemGroup>

<!-- Default deployment to single version -->
<Copy SourceFiles="@(AllFilesToCopy)"
DestinationFolder="$(PyRevitEnginesDir)\$(IronPythonVersion)"
Condition="'$(DeployToAllVersions)' != 'true'" />
<Message Importance="high"
Text="$(MSBuildProjectName) -> Copy to $([System.IO.Path]::GetFullPath('$(PyRevitEnginesDir)\$(IronPythonVersion)'))"
Condition="'$(DeployToAllVersions)' != 'true'" />

<!-- Multi-version deployment for shared components -->
<Copy SourceFiles="@(AllFilesToCopy)"
DestinationFolder="$(PyRevitEnginesDir)\IPY342"
Condition="'$(DeployToAllVersions)' == 'true'" />
<Message Importance="high"
Text="$(MSBuildProjectName) -> Copy to $([System.IO.Path]::GetFullPath('$(PyRevitEnginesDir)\IPY342'))"
Condition="'$(DeployToAllVersions)' == 'true'" />
<Copy SourceFiles="@(AllFilesToCopy)"
DestinationFolder="$(PyRevitEnginesDir)\$(IronPythonVersion)" />
DestinationFolder="$(PyRevitEnginesDir)\IPY2712PR"
Condition="'$(DeployToAllVersions)' == 'true'" />
<Message Importance="high"
Text="$(MSBuildProjectName) -> Copy to $([System.IO.Path]::GetFullPath('$(PyRevitEnginesDir)\$(IronPythonVersion)'))" />
Text="$(MSBuildProjectName) -> Copy to $([System.IO.Path]::GetFullPath('$(PyRevitEnginesDir)\IPY2712PR'))"
Condition="'$(DeployToAllVersions)' == 'true'" />
</Target>

</Project>
148 changes: 139 additions & 9 deletions dev/pyRevitLoader/Source/PyRevitLoaderApplication.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using System;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
using pyRevitAssemblyBuilder.AssemblyMaker;
using pyRevitAssemblyBuilder.SessionManager;
using pyRevitExtensionParser;

/* Note:
* It is necessary that this code object do not have any references to IronPython.
Expand All @@ -17,18 +21,38 @@ namespace PyRevitLoader
class PyRevitLoaderApplication : IExternalApplication
{
public static string LoaderPath => Path.GetDirectoryName(typeof(PyRevitLoaderApplication).Assembly.Location);

// Store the UIControlledApplication for later use
private static UIControlledApplication _uiControlledApplication;

// Hook into Revit to allow starting a command.
Result IExternalApplication.OnStartup(UIControlledApplication application)
{
// Store the UIControlledApplication for later use
_uiControlledApplication = application;

LoadAssembliesInFolder(LoaderPath);
// We need to also looad dlls from two folders up
var commonFolder = Path.GetDirectoryName(Path.GetDirectoryName(LoaderPath));
LoadAssembliesInFolder(commonFolder);

try
{
return ExecuteStartupScript(application);
// we need a UIApplication object to assign as `__revit__` in python...
var versionNumber = application.ControlledApplication.VersionNumber;
var fieldName = int.Parse(versionNumber) >= 2017 ? "m_uiapplication" : "m_application";
var fi = application.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);

var uiApplication = (UIApplication)fi.GetValue(application);

var executor = new ScriptExecutor(uiApplication);
var result = ExecuteStartupScript(application);
if (result == Result.Failed)
{
TaskDialog.Show("Error Loading pyRevit", executor.Message);
}

return result;
}
catch (Exception ex)
{
Expand All @@ -47,13 +71,23 @@ private static void LoadAssembliesInFolder(string folder)
{
Assembly.LoadFrom(engineDll);
}
catch
catch (Exception ex)
{
// Log assembly load failures - some assemblies may fail to load and that's acceptable
Trace.WriteLine($"Failed to load assembly '{engineDll}': {ex.Message}");
}
}
}

private static Result ExecuteStartupScript(UIControlledApplication uiControlledApplication)
{
// Always execute Python startup script
// The Python script will determine whether to use C# or Python session management
// based on the configuration
return ExecuteStartUpPython(uiControlledApplication);
}

public static Result ExecuteStartUpPython(UIControlledApplication uiControlledApplication)
{
// we need a UIApplication object to assign as `__revit__` in python...
var versionNumber = uiControlledApplication.ControlledApplication.VersionNumber;
Expand All @@ -66,28 +100,124 @@ private static Result ExecuteStartupScript(UIControlledApplication uiControlledA
var startupScript = GetStartupScriptPath();
if (startupScript != null)
{
var executor = new ScriptExecutor(uiApplication); // uiControlledApplication);
result = executor.ExecuteScript(startupScript);
if (result == Result.Failed)
var versionNumber = uiControlledApplication.ControlledApplication.VersionNumber;
var fieldName = int.Parse(versionNumber) >= 2017 ? "m_uiapplication" : "m_application";
var fi = uiControlledApplication.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);
var uiApplication = (UIApplication)fi.GetValue(uiControlledApplication);

// Instantiate all services
var typeGenerator = new CommandTypeGenerator();
var assemblyBuilder = new AssemblyBuilderService(typeGenerator, versionNumber);
var extensionManager = new ExtensionManagerService();
var hookManager = new HookManager();
var uiManager = new UIManagerService(uiApplication);

var sessionManager = new SessionManagerService(
assemblyBuilder,
extensionManager,
hookManager,
uiManager
);

sessionManager.LoadSession();

// execute light version of StartupScript python script
Result result = Result.Succeeded;
var startupScript = GetStartupScriptPath(true);
if (startupScript != null)
{
TaskDialog.Show("Error Loading pyRevit", executor.Message);
var executor = new ScriptExecutor(uiApplication); // uiControlledApplication);
result = executor.ExecuteScript(startupScript);
if (result == Result.Failed)
{
TaskDialog.Show("Error Loading pyRevit", executor.Message);
}
}
}

return result;
}

public static Result LoadSession(object pythonLogger = null, string buildStrategy = null)
{
try
{
// Use the stored UIControlledApplication
if (_uiControlledApplication == null)
{
throw new InvalidOperationException("UIControlledApplication not available. LoadSession can only be called after OnStartup.");
}

var uiControlledApplication = _uiControlledApplication;
// we need a UIApplication object to assign as `__revit__` in python...
var versionNumber = uiControlledApplication.ControlledApplication.VersionNumber;
var fieldName = int.Parse(versionNumber) >= 2017 ? "m_uiapplication" : "m_application";
var fi = uiControlledApplication.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);

var uiApplication = (UIApplication)fi.GetValue(uiControlledApplication);

// Get the current Revit version
var revitVersion = uiControlledApplication.ControlledApplication.VersionNumber;

// Determine build strategy: use provided parameter, or read from config, or default to ILPack
var assemblyBuildStrategyType = typeof(pyRevitAssemblyBuilder.AssemblyMaker.AssemblyBuildStrategy);
object strategyValue;

if (!string.IsNullOrEmpty(buildStrategy))
{
// Use provided build strategy from Python
strategyValue = Enum.Parse(assemblyBuildStrategyType, buildStrategy);
}
else
{
// Fallback: read from config
try
{
var config = PyRevitConfig.Load();
var strategyName = config.NewLoaderRoslyn ? "Roslyn" : "ILPack";
strategyValue = Enum.Parse(assemblyBuildStrategyType, strategyName);
}
catch
{
// Final fallback: default to ILPack
strategyValue = Enum.Parse(assemblyBuildStrategyType, "ILPack");
}
}

// Create services using factory
var strategyEnum = (pyRevitAssemblyBuilder.AssemblyMaker.AssemblyBuildStrategy)strategyValue;
var sessionManager = pyRevitAssemblyBuilder.SessionManager.ServiceFactory.CreateSessionManagerService(
revitVersion,
strategyEnum,
uiApplication,
pythonLogger);

// Load the session using the C# SessionManagerService
sessionManager.LoadSession();

return Result.Succeeded;
}
catch (Exception ex)
{
// Log detailed error information before showing dialog
Trace.WriteLine($"Error Loading C# Session: {ex}");
Trace.WriteLine($"Stack Trace: {ex.StackTrace}");

// Show user-friendly error dialog
TaskDialog.Show("Error Loading C# Session",
$"An error occurred while loading the C# session:\n\n{ex.Message}\n\nCheck the output window for details.");
return Result.Failed;
}
}
private static string GetStartupScriptPath()
{
var loaderDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var dllDir = Path.GetDirectoryName(loaderDir);
return Path.Combine(dllDir, string.Format("{0}.py", Assembly.GetExecutingAssembly().GetName().Name));
}

Result IExternalApplication.OnShutdown(UIControlledApplication application)
{
// FIXME: deallocate the python shell...
return Result.Succeeded;
}
}
}
}
Loading