Powershell: Binary Modules vs Script Modules - c#

I'm writing a Build Process (wrapping msbuild in my module) for 350+ projects (VS 2010). This module now includes lots of Functions. Although, it is working efficently, but , I've started considering writing a Dll instead of script based module. Also because I may use Win-Forms (C#) in these dlls.
I'm Googling for the performance and other issues for both approach, but not getting sufficient info.
If anyone have experience related to this, kindly give some advice that which approach is better for PS Modules: Binary(.dll) or Script(.psm1)
Regards

Starting with PowerShell 2.0, there is no difference in implementing a cmdlet as script or binary. In fact, whatever is available to a binary cmdlet is available to a script cmdlet with respect to cmdlet arguments and other features. You can read more about Advanced Functions to understand this.
To me, it all boils down to the choice of language. If you are comfortable with .NET and C#, you may want to implement a binary cmdlet. Otherwise, just go for a script module which will serve the same purpose.

Related

Call Python from .NET

I have some code written in Python which can not be transferred to a .NET language. I need to call one of these functions from my .NET WinForms application.
Now, I do it by starting the Python script as a separate process and pass parameters to it as command line arguments. It works, but I don't really like this solution. I'd like to improve it to a better one.
Is there any better way to call a function of a .py script from a .NET application? What is the best way to do it?
Note: IronPython is NOT an option for this Python script
This might be a lot more work than launching the Python process, but here's an alternate solution.
You can embed Python into another program. The API is for C and Interop from .NET will probably be a major pain. If you're into a bit of a safer way to handle the native Python API, you can look into Boost.Python, which, among its less advertised features, has support for embedding.
With these tools, you can write a C++ managed DLL that uses Boost.Python to load the Python interpreter and execute any Python script. Thus, you can execute any Python code directly in the hosting process, eliminating the use of an external process and any form of IPC.
Edit: AFAIK, all you have to add to your installation procedure is the deployment of the Python DLL and Boost.Python DLL.
Besides the COM option, you could make your Python script instantiate a xmlrpc server -
it is quite transparent and you never have to deal with "xml" on your own code.
Then, on .net side, you simply connect to your python app via xmlrpc - if there is no suitable way to do that in C#, just write a client function in IronPython.
The SimpleXMLRPCServer example on Python documentation is enough for that:
http://docs.python.org/library/simplexmlrpcserver.html
I think you need to re-evaluate Carlos' answer.
See the section Implementing COM Objects with Python in Mark Hammond's book Python Programming on Win32.
You should be able to create a COM object, then have .Net interact with it.
From the book the following will create a COM server with a single method.
# SimpleCOMServer.py - A sample COM server - almost as small as they come!
#
# We expose a single method in a Python COM object.
class PythonUtilities:
_public_methods_ = [ 'SplitString' ]
_reg_progid_ = "PythonDemos.Utilities"
# NEVER copy the following ID
# Use "print pythoncom.CreateGuid()" to make a new one.
_reg_clsid_ = "{41E24E95-D45A-11D2-852C-204C4F4F5020}"
def SplitString(self, val, item=None):
import string
if item != None: item = str(item)
return string.split(str(val), item)
# Add code so that when this script is run by
# Python.exe, it self-registers.
if __name__=='__main__':
print "Registering COM server..."
import win32com.server.register
win32com.server.register.UseCommandLine(PythonUtilities)
The book goes on to say ".. you can do this by executing the code as a normal Python script. The easiest way to do this is to open the source file in PythonWin and use the Run command from the File menu. "
I think you need the ActivePython distribution from Activestate to do it.
See this question Consuming Python COM Server from .NET
It works, but I don't really like this solution, I'd like to improve it to a better one.
No, AFAIK there isn't a better solution, especially if IronPython is a no-no for you. So you could still keep this as a temporary workaround while waiting for the script to be migrated to .NET or until you find that someone already wrote a library on .NET that provides you with similar functionality.
Create a COM .dll from a .py script and use Interop in your .NET code.
Have a look here: http://docs.python.org/faq/windows.html
PythonNet should help with this one. It enables you to call python code from C#.
A cleaner way is to expose the python script via a Flask REST API and consume that from your .NET Application. Don't forget to put proper authentication in place.

Calling python code(.py files) from C#

I have some python code that does a certain task. I need to call this code from C# without converting the python file as an .exe, since the whole application is built on C#.
How can I do this?
If your python code can be executed via IronPython then this is definitely the way to go - it offers the best interop and means that you will be able to use .Net objects in your scripts.
There are many ways to invoke IronPython scripts from C# ranging from compiling the script up as an executable to executing a single script file or event dynamically executing expressions as they are typed in by the user - check the documentation and post another question if you are still haivng problems.
If your script is a CPython script and can't be adapted to work with IronPython then your options are more limited. I believe that some CPython / C# interop exists, but I couldn't find it after a quick Google search. The best thing I can think of would be to just invoke the script directly using python.exe and the Process class.
Have a look at IronPython.
Based on your answer and comments, I believe that the best thing you can do is to embed IronPython in your application. As always, there is a relevant SO question about this. As Kragen said, it is important not to rely on a CPython module.
Process.Start is what you're after. It allows you to call another program, passing it arguments.

What's a good way to write batch scripts in C#?

I would like to write simple scripts in C#. Stuff I would normally use .bat or 4NT .btm files for. Copying files, parsing text, asking user input, and so on. Fairly simple but doing this stuff right in a batch file is really hard (no exceptions for example).
I'm familiar with command line "scripting" wrappers like AxScript so that gets me part of the way there. What I'm missing is the easy file-manipulation framework. I want to be able to do cd(".."), copy(srcFile, destFile) type functionality.
Tools I have tried:
NANT, which we use in our build process. Not a good scripting tool. Insanely verbose XML syntax and to add a simple function you must write an extension assembly. Can't do it inline.
PowerShell. Looks great, but I just haven't been able to switch over to this as my primary shell. Too many differences from 4NT. Whatever I do needs to run from an ordinary command prompt and not require a special shell to run it through. Can PowerShell be used as a script executor?
Perl/Python/Ruby. Really hate learning an entirely new language and framework just to do batch file operations. Haven't been able to dedicate the time I need to do this. Plus, we're a 99% .NET shop for our toolchain and I really want to leverage our existing experience and codebase.
Are there frameworks out there that are trying to solve this problem of "make a batch file in C#" that you have used?
I want the power of C#/.NET with the immediate-mode type functionality of a typical cmd.exe shell language. Am I alone in wanting something like this?
I would try to get over the PowerShell anxiety because it is the shell of the future. All of the software coming out of Microsoft is using it as their management interface and especially version 2.0 is ridiculously useful.
I'm a C# developer most of the time but PowerShell has solved that whole "WindowsApplication42" problem of temp projects just piling up. PowerShell gives you full access to the .NET framework in a command line shell so even if you don't know how to do something in PowerShell, you most likely know how to do it in .NET.
IronPython and IronRuby do let you leverage all of your .NET "experience and codebase" (they don't answer your objection to learning new languages, however).
If you have any bash nerds, you can always try cygwin.
Also remember that Python was originally intended as a "glue" langauge. If you used the aforementioned IronPython, it's pretty easy to tie together pre-written C# classes.
If you are bind to MS, PowerShell is surely the way to go. But I don't like it much.
I personally use MSBuild script more, and would like to see Mono C# Shell one day comes to Windows.
I think CS-Script might be the ideal solution for you.

Creating an interactive shell for .NET apps and embed scripting languages like python/iron python into it

I was learning python using the tutorial that comes with the standard python installation. One of the benefits that the author states about python is "maybe you’ve written a program that could use an extension language, and you don’t want to design and implement a whole new language for your application" - My question is how would i go about designing a program (using c#) that can be extended using Python interactively(for this to be possible, i would imagine that i would need to create some sort of a "shell" or "interactive" mode for the .net program) ?
Are there any pointers on how to design .NET programs that have an interactive shell. I would then like to use python script in the shell to "extend" or interact with the program.
EDIT: This question partly stems from the demo give by Miguel de Icaza during PDC 2008 where he showed the interactive csharp command prompt, C# 4.0 i think also has this "compiler as a service" feature. I looked at that and thought how cool would it be to design a windows or web program in .NET that had a interactive shell.. and a scripting language like python could be used to extend the features provided by the program.
Also, i started thinking about this kind of functionality after reading one of Steve Yegge's essays where he talks about systems that live forever.
This sounds like a great use of IronPython.
It's fairly easy to set up a simple scripting host from C# to allow calls into IronPython scripts, as well as allowing IronPython to call into your C# code. There are samples and examples on the CodePlex site that show how to do this very thing.
Another good site for examples and samples is ironpython.info
And here is a page dedicated to an example answering your very question, albeit in a generic DLR-centric way -- this would allow you to host IronPython, IronRuby, or whatever DLR languages you want to support.
I've used these examples in the past to create an IronPython environment inside a private installation of ScrewTurn Wiki - it allowed me to create very expressive Wiki templates and proved to be very useful in general.
I was looking solution for the same problem, and found IronTextBox: http://www.codeproject.com/KB/edit/irontextbox2.aspx
It needs a little tuning for current versions, but seems to be everything I needed. First made it compile, and then added variables I wanted to access from shell to the scope.
Python as an extension language is called "Embedding Python".
you can call a python module from c++ by bascially calling the python intepreter and have it execute the python source. This is called embedding.
It works from C and C++, and will probably work just as well from C#.
And no, you do not need any kind of "shell". While Python can be interactive, that's not a requirement at all.
Here is a link to a blog post about adding IronRuby to script a C# application.
http://blog.jimmy.schementi.com/2008/11/adding-scripting-to-c-silverlight-app.html
The principles would also work well for using IronPython.
If your goal is to avoid learning a new language you can use CSScript.Net and embedded scripts written in C# or VB into you application. With CSScript you get full access to the CLR. Three different models of script execution are supported so that you can execute script that refers to objects in your current app domain, execute using remoting, or execute as a shell.
Currently I am using CCScript as "glue" code for configuring application objects somewhat similar to using Boo.
This link tasks you to a code project article that provides a good overview.
I don't know what you mean with
"extend" or interact with the program
so I can't answer your question. Can you give an example?
There is an open source interactive C# shell in mono: http://www.mono-project.com/CsharpRepl
When you like python, .Net and language extension, you will probably like Boo over Iron python. Boo comes with an open source interactive shell too.
I disagree with
"you don’t want to design and
implement a whole new language for
your application"
It's not as hard as it used to be to create a simple DSL. It won't take you days to implement, just hours. It might be an interesting option.

Running scripts inside C#

I want to run javascript/Python/Ruby inside my application.
I have an application that creates process automatically based on user's definition. The process is generated in C#. I want to enable advanced users to inject script in predefined locations. Those scripts should be run from the C# process.
For example, the created process will have some activities and in the middle the script should be run and then the process continues as before.
Is there a mechanism to run those scripts from C#?
Basically, you have two problems: how to define point of injections in your generated code, and how to run python / ruby / whatev scripts from there.
Depending on how you generate the process, one possible solution would be to add a function to each possible point of injection. The function would check, whether the user has associated any scripts with given points, and if so, runs the script by invoking IronPython / IronRuby (with optionally given parameters).
Disadvantages include: limited accessibility from the scripts to the created process (basically, only variables passed as parameters could be accessed); as well as implementation limits (IronPython's current version omits several basic system functions).
Look into IronPython and IronRuby -- these will allow you to easily interoperate with C#.
You can compile C# code from within a C# application using the CSharpCodeProvider class.
If the compile succeeds you can run the resulting assembly as returned via the CompiledAssembly property of the CompilerResults class.
Awesome C# scripting language - Script.Net
.NET has a scripting language including runtime engine in PowerShell which can be embedded in any .NET application.
You can compile C# code "on the fly" into an in-memory assembly. I think this is possible with IronPython and IronRuby as well. Look at the CodeDomProvider.CreateProvider method.
If you need to run scripts a lot, or if your process runs for a long time, you might want to load these assemblies into another AppDomain. And unload the AppDomain after you're done with the script. Otherwise you are unable to remove them from memory. This has some consequenses on the other classes in your project, because you have to marshall all calls.
Have you thought about Visual Studio for Applications? I haven't heard much about it since .NET 1.1, but it might be worth a look.
http://msdn.microsoft.com/en-us/library/ms974548.aspx
I've done exactly this just recently - allowed run-time addition of C# scripting.
It's not hard at all, and this article:
http://www.divil.co.uk/net/articles/plugins/scripting.asp
is a very useful summary of the details.
One of Microsoft's solutions to JavaScript in C# is ClearScript,
which uses V8, Chrom browser's JavaScript engine. Check its short FAQtorial for code samples.
It has excellent two-way integration - iterator/enumerator, output parameters, optional parameters, parameter arrays, delegate, task/promise/async/await, bigint, and more.
Apart from that, I think the most distinguishing feature is that it does not depend on Rosyln or Dynamic Language Runtime. This can be good or bad - good because there may be a lot less dependencies (depending on your project's target), bad because you need to bundle the native, platform-dependent V8 dll.
If that is ok, you get to enjoy cutting edge JavaScript / ECMAScript. Everything you get on Chrome, or 98% ES6 as of 2022 Feb, plus several extensions. Speed is as fast as Chrome, obviously, so you get the best of both Google and Microsoft.

Categories

Resources