Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 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
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 not shown.
Binary file not shown.
Binary file modified bin/netcore/engines/IPY2712PR/pyRevitLoader.dll
Binary file not shown.
Binary file modified bin/netcore/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 modified bin/netcore/engines/IPY342/pyRevitLabs.PyRevit.Runtime.2025.dll
Binary file not shown.
Binary file modified bin/netcore/engines/IPY342/pyRevitLabs.PyRevit.Runtime.2026.dll
Binary file not shown.
Binary file modified bin/netcore/engines/IPY342/pyRevitLoader.dll
Binary file not shown.
Binary file modified bin/netcore/engines/IPY342/pyRevitRunner.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.Common.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.CommonCLI.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.CommonWPF.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.DeffrelDB.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.Emojis.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.Json.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.Language.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.MahAppsMetro.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.NLog.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.PyRevit.Runtime.Shared.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.PyRevit.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.TargetApps.AutoCAD.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.TargetApps.Navisworks.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.TargetApps.Revit.dll
Binary file not shown.
Binary file modified bin/netcore/pyRevitLabs.UnitTests.dll
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified bin/netfx/engines/IPY2712PR/pyRevitLabs.PyRevit.Runtime.2019.dll
Binary file not shown.
Binary file modified bin/netfx/engines/IPY2712PR/pyRevitLabs.PyRevit.Runtime.2020.dll
Binary file not shown.
Binary file not shown.
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 modified bin/netfx/engines/IPY342/pyRevitLabs.PyRevit.Runtime.2017.dll
Binary file not shown.
Binary file modified bin/netfx/engines/IPY342/pyRevitLabs.PyRevit.Runtime.2018.dll
Binary file not shown.
Binary file modified bin/netfx/engines/IPY342/pyRevitLabs.PyRevit.Runtime.2019.dll
Binary file not shown.
Binary file modified bin/netfx/engines/IPY342/pyRevitLabs.PyRevit.Runtime.2020.dll
Binary file not shown.
Binary file modified bin/netfx/engines/IPY342/pyRevitLabs.PyRevit.Runtime.2021.dll
Binary file not shown.
Binary file modified bin/netfx/engines/IPY342/pyRevitLabs.PyRevit.Runtime.2022.dll
Binary file not shown.
Binary file modified bin/netfx/engines/IPY342/pyRevitLabs.PyRevit.Runtime.2023.dll
Binary file not shown.
Binary file modified bin/netfx/engines/IPY342/pyRevitLabs.PyRevit.Runtime.2024.dll
Binary file not shown.
Binary file modified bin/netfx/engines/IPY342/pyRevitLoader.dll
Binary file not shown.
Binary file modified bin/netfx/engines/IPY342/pyRevitRunner.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.Common.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.CommonCLI.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.CommonWPF.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.DeffrelDB.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.Emojis.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.Json.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.Language.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.MahAppsMetro.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.NLog.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.PyRevit.Runtime.Shared.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.PyRevit.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.TargetApps.AutoCAD.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.TargetApps.Navisworks.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.TargetApps.Revit.dll
Binary file not shown.
Binary file modified bin/netfx/pyRevitLabs.UnitTests.dll
Binary file not shown.
Binary file modified bin/pyRevitLabs.Common.dll
Binary file not shown.
Binary file modified bin/pyRevitLabs.CommonCLI.dll
Binary file not shown.
Binary file modified bin/pyRevitLabs.CommonWPF.dll
Binary file not shown.
Binary file modified bin/pyRevitLabs.Json.dll
Binary file not shown.
Binary file modified bin/pyRevitLabs.Language.dll
Binary file not shown.
Binary file modified bin/pyRevitLabs.NLog.dll
Binary file not shown.
Binary file modified bin/pyRevitLabs.PyRevit.dll
Binary file not shown.
Binary file modified bin/pyRevitLabs.TargetApps.Revit.dll
Binary file not shown.
Binary file modified bin/pyrevit-doctor.dll
Binary file not shown.
Binary file modified bin/pyrevit-doctor.exe
Binary file not shown.
1 change: 1 addition & 0 deletions bin/pyrevit-doctor.runtimeconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"version": "8.0.0"
},
"configProperties": {
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false,
"CSWINRT_USE_WINDOWS_UI_XAML_PROJECTIONS": false
}
Expand Down
Binary file modified bin/pyrevit.dll
Binary file not shown.
Binary file modified bin/pyrevit.exe
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
Binary file modified dev/libs/netcore/pyRevitLabs.Json.dll
Binary file not shown.
Binary file modified dev/libs/netcore/pyRevitLabs.MahAppsMetro.dll
Binary file not shown.
Binary file modified dev/libs/netcore/pyRevitLabs.NLog.dll
Binary file not shown.
Binary file modified dev/libs/netfx/pyRevitLabs.Json.dll
Binary file not shown.
Binary file modified dev/libs/netfx/pyRevitLabs.MahAppsMetro.dll
Binary file not shown.
Binary file modified dev/libs/netfx/pyRevitLabs.NLog.dll
Binary file not shown.
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 @@ -170,6 +170,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>
112 changes: 108 additions & 4 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 @@ -77,17 +111,87 @@ private static Result ExecuteStartupScript(UIControlledApplication uiControlledA
return result;
}

public static Result LoadSession(object outputWindow = 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,
outputWindow);

// 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