Closed sgrodnik closed 1 year ago
You can create own program interface to communicate between C# and Python code. I think it is better solution for you.
concept code
public interface ICanReload
{
void Reload();
}
public interface IReloadableCommand
{
Result Execute(UIApplication uiApplication, ICanReload canReload);
}
public class MyCommand : IExternalCommand, IReloadableCommand
{
public Result Execute(ExternalCommandData commandData, out string message, ElementSet elements)
{
// some staff
message = null!;
return Result.Succeeded;
}
public Result Execute(UIApplication uiApplication, ICanReload canReload)
{
// some staff
canReload.Reload()
return Result.Succeeded;
}
}
import clr
clr.AddReference("MyLibrary.dll")
from pyrevit.loader import sessionmgr
from pyrevit.loader import sessioninfo
from MyLibrary import ICanReload,IReloadableCommand, MyCommand
class ReloadSession(ICanReload):
def Reload(self):
sessionmgr.load_session()
def execute():
command = MyCommand()
command.Execute(__revit__, ReloadSession())
I will close this issue as the original poster did not reply @dosymep thanks for taking the time to reply
I will close this issue as the original poster did not reply @dosymep thanks for taking the time to reply
Im afraid I do not know what to do with the provided code sample. It exceeds my coding skills. I will figure it out in the future.
I had exactly the same question. The concept code didn't work for this case, because you'll have to change the source python code of pyRevit in order to make it work. What I came up with is executing pyRevitLoader.py
script by invoking ExecuteScript
method of ScriptExecutor
class of pyRevitLoader.dll
. Basically pyRevit does every singly time it loads itself and whenever Reload button is clicked. Here is the snippet of the code I used:
// Get the pyRevitLoader assembly
Assembly asm = ExtensionManager.GetPyRevitLoaderAssembly(uiapp);
// Get the ScriptExecutor type
Type sampleType = asm.GetTypes().FirstOrDefault(t => t.Name == "ScriptExecutor");
// Create an instance of the ScriptExecutor type
object ScriptExecutorInstance = Activator.CreateInstance(sampleType, uiapp, false);
MethodInfo executeScriptMethod = sampleType.GetMethod("ExecuteScript", BindingFlags.Public | BindingFlags.Instance);
// Get directory of the pyRevitLoader script
var loaderDir = Directory.GetParent(Path.GetDirectoryName(asm.Location)).FullName;
var startupScript = Path.Combine(loaderDir, "pyRevitLoader.py");
// Prepare parameters for ExecuteScript method
var parameters = new object[] { startupScript, null, null, null };
// Invoke ExecuteScript method
var result = (Result)executeScriptMethod.Invoke(ScriptExecutorInstance, parameters);
// This method scans all loaded assemblies loaded in Revit session and finds PyRevitLoaderApplication
public static Assembly GetPyRevitLoaderAssembly(UIApplication uiapp)
{
ExternalApplicationArray loaded = uiapp.LoadedApplications;
Assembly assm = null;
foreach (IExternalApplication item in loaded)
{
Type type = item.GetType();
if (type.Name == "PyRevitLoaderApplication")
assm = type.Assembly;
}
return assm;
}
Hello eirannejad! I want to write a C# tool to automate pyRevit button creation/editing. I can process folders and scripts and bundle files in my C# code, but I still have to invoke pyRevit's native Reload command from separate Python code (
sessionmgr.load_session()
).I need a way to reload my pyRevit ribbon from my C# code. Smth like this:
I've noticed some similar staff in your restApi (didn't have enough time to understand it). Can it help me? Or maybe CLI has such a capacity? Or can I use some your dll to invoke its Reload member (if it exists)?