oleg-shilo / cs-script

C# scripting platform
http://www.cs-script.net
MIT License
1.63k stars 236 forks source link

cs referencing hell #384

Closed rexxitall closed 1 month ago

rexxitall commented 2 months ago

Hi Oleg :)

Thanks for this thing. At the moment i try to add scripting to revit. I am not the c# hero and the only way to enhance revit is to load a dll - Autodesk said. That you can forget cause even on a fast com that will need 3 minutes. Not a option

I managed to add one cs file to my revit code.

BTW: The roslyn engine does not work out of revit due dll restrictions

CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom; CSScript.EvaluatorConfig.DebugBuild = true; string path = System.IO.Path.GetDirectoryName(mainfile); CSScript.GlobalSettings.AddSearchDir(Path.GetFullPath(path)); //csscriptlibdir CSScript.GlobalSettings.AddSearchDir(csscriptlibdir); //csscriptlibdir

dynamic script = CSScript.Evaluator

                 .ReferenceAssembliesFromCode(code)
                 .ReferenceAssembly(Assembly.GetExecutingAssembly())
                 .ReferenceAssembly(Assembly.GetExecutingAssembly().Location)
                 .ReferenceDomainAssemblies()
                                .LoadCode(code);

well that works so far. I can adress revit entitys and do my engineering stuff on a limited base.

But i know sooner or later i will have a real monster of single code file... Last times as i do something similar with autocad i end up after a "few" years with 380 files...

What i want is to modularize my code by single files :)

main.cs vactor.cs ... whatever.cs

most prefereable by subfolders (380 files in a folder are also no gift)

main.cs .\lib\math\vector.cs .\lib\math\math.cs .\lib\util... .\lib\div\whatever.cs

Sorry can you please provide a sample for a hosted csscript ? in my case i wrote a revit extension dll which just lay out everything to cs-script which works fine. I can load the extension and execute ONE cs file which does not care about search folders and whatever

Greetings from germany Thomas

oleg-shilo commented 2 months ago

Hi Thomas,

I do not have my environment handy to check, but if I am not mistaken CodeDOM evaluator will process CS-Script directives the same way as in CLI execution. If it does then you can import all your scripts at runtime as you need without resorting to the single file approach.

You can easily test it by including any of the dependency scripts in your primary script via the directive at the top of the script file:

//css_include my_dependency_script.cs
....
rexxitall commented 2 months ago

Thank you Oleg, i was confused by the include and the wording that it would act like in other languages. Which is not the case a include includes a file AT THE PLACE of the include. Which is now what you want in every case cause using statements would get included on places where they are not allowed. Yesterday i tried also with //css_dir and //css_searchdir. For sure for peoples who use your project for a long time everything is clear. But if you are new you can assume whatever you want by the small amount of information given (especially for the hosted thing) / I was very frustrated yesterday. If i does not had a very urgend need i propably would have drop the CS-Script thing as "not working due lack of documentation" :) I riddle meanwhile over a week on cs-script. And usualöly i am a riddle master by using github for decades :D

rexxitall commented 2 months ago

Test it a few minutes ago - works like a charm :) Thanks !

oleg-shilo commented 2 months ago

BTW, the documentation is there and reasonably extensive. It also went through a vigorous review process by the users. Some of them directly updated it to make it more aligned with the average user's expectations. Just in case if you missed this wiki page:

image

When it comes to syntax help (above), you can always get it from CLI too. The very same content as on wiki:

image

Interestingly enough the functionality you needed (css_inc) was not in the original design as Roslyn does not support multi-file compilation. It's only later I discovered that the original CS-Script CLI implementation has this positive side effect when using CodeDom.

... a include includes a file AT THE PLACE of the include.

This is the case only for dynamic languages. C# is a statically compiled language. However, even in dynamic language placing the imports on at the top of the file is considered a preferred practice and one should avoid using imports in the middle of the script.

Nevertheless, of course, moving to a new tech will take some time to get comfortable with. The easiest way to deal with C# scripting is to consider your script file as a referenced assembly that is compiled on-fly. And in order to compile it you also create an on-fly C# project definition with //css_include, //css_reference and //css_nuget. Though nuget packages are only supported in CLI mode.

Good luck...

rexxitall commented 1 month ago

HI Oleg Thanks, Well i have had some luck :) It works that well that i know just riddle how to get (in my hosted application) the original source file from a CSSript error message. The error message just delivers the temp file name. The workaround would to add a special comment to each file to get the real source. But there might be a more elegant solution. Any hint ?

oleg-shilo commented 1 month ago

No, Thomas, I cannot offer anything more elegant. With CLI this problem is addressed. You can check the environment variable EntryScript and it will contain the path to your script.

But with hosted script execution this approach cannot work. You may have dozens of scripts being executed. And in some cases, there will be no static file as the script will be file will be generated from the user-specified C# code fragment.

Saying that, if your concern is debugging then you simply need to provide the debugging flag and the debugger will be able to lookup the corresponding *.cs file:

CSScript.EvaluatorConfig.PdbFormat = Microsoft.CodeAnalysis.Emit.DebugInformationFormat.Embedded;
CSScript.EvaluatorConfig.DebugBuild = true;
rexxitall commented 1 month ago

Hi, I made a form using webview2 and codemirror to have a easy way to fix small issues without VS. (There are also more reasons why i do that this way). I currently manage it like that that i added a special comment with the filename and path as first line. Now i load the temp file and scan for that comment. Then i load the real file. Works for sure. But might be a idea to add a dictionary behind the CSScript scene. So you could deliver the original filename by a api or on demand direct as error message. I do not know how much afford it is to implement it on your side. But i think it would be a nice new feature :) To be honest to deliver the temp file name is not that intuitive :D Have a great day, Thomas

oleg-shilo commented 1 month ago

Thomas, I realized that you can discover the source file if it is executed in the cached mode (default). But you need it in the hosted execution. :( Well, adding the hidden dictionary is a possibility. Can you please log an enhancement issue for that?

rexxitall commented 1 month ago

did it

oleg-shilo commented 1 month ago

Closing this and as the issue is managed via #385