[IronPython] PythonEngine in separate AppDomain?
michael_sweeney at agilent.com
michael_sweeney at agilent.com
Tue May 22 21:37:15 CEST 2007
Hi All,
I have been using the PythonEngine to host IronPython in my application, it works great. I have a need to host the PythonEngine in a separate AppDomain and then provide an API back to the default app domain. I am running into the black-hole of Security issues. I get the following FileIOPermission inner-exception during the PythonEngine creation:
at System.Runtime.CompilerServices.RuntimeHelpers._RunClassConstructor(IntPtr type)
at System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(RuntimeTypeHandle type)
at IronPython.Hosting.PythonEngine.Initialize(EngineOptions engineOptions) in C:\tfs\Fusion\Main\Source\IronPython\IronPython\Hosting\PythonEngine.cs:line 175
at IronPython.Hosting.PythonEngine..ctor(EngineOptions engineOptions) in C:\tfs\Fusion\Main\Source\IronPython\IronPython\Hosting\PythonEngine.cs:line 141
at ConsoleApplication1.PythonInstance..ctor() in C:\temp\ConsoleApplication1\Program.cs:line 27
It appears that the PythonEngine is trying to create an assembly file in the OutputGenerator.cs file. I would like to know the magic to give the separate AppDomain the ability to write files.
I have also gone as far as configuring the separate AppDomain with special security permissions, with no impact... that code is also below...
I have trimmed down the application into the following test code:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython.Runtime.Operations;
using IronPython.Modules;
namespace ConsoleApplication1
{
[Serializable]
public class PythonInstance
{
// IronPython Modules
private static PythonEngine _python;
public PythonInstance()
{
// Create Python Engine
EngineOptions options = new EngineOptions();
options.ExceptionDetail = true;
options.ClrDebuggingEnabled = true;
PythonInstance._python = new PythonEngine(options);
}
public void AddPythonPath(string path)
{
PythonInstance._python.AddToPath(path);
}
}
class Program
{
static void Main(string[] args)
{
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationName = Assembly.GetEntryAssembly().FullName;
setup.ApplicationBase = Path.GetDirectoryName(typeof(Program).Assembly.Location);
AppDomain domain = AppDomain.CreateDomain("PythonDomain", null, setup);
// Create Test Engine in remote domain
object obj = domain.CreateInstanceAndUnwrap("ConsoleApplication1",
"ConsoleApplication1.PythonInstance");
PythonInstance python = obj as PythonInstance;
python.AddPythonPath(@"C:\temp");
}
}
}
Code to give the app domain special permissions:
private void SetAppDomainPolicy(AppDomain appDomain)
{
// Create an AppDomain policy level.
PolicyLevel pLevel = PolicyLevel.CreateAppDomainLevel();
// The root code group of the policy level combines all
// permissions of its children.
PermissionSet ps = new PermissionSet(PermissionState.Unrestricted);
ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.AllFlags));
UnionCodeGroup rootCodeGroup =
new UnionCodeGroup(new AllMembershipCondition(),
new PolicyStatement(ps, PolicyStatementAttribute.Nothing));
NamedPermissionSet localIntranet = FindNamedPermissionSet("LocalIntranet");
// The following code limits all code on this machine to local intranet permissions
// when running in this application domain.
UnionCodeGroup virtualIntranet =
new UnionCodeGroup(new ZoneMembershipCondition(SecurityZone.MyComputer),
new PolicyStatement(localIntranet, PolicyStatementAttribute.Nothing));
virtualIntranet.Name = "Virtual Intranet";
// Add the code groups to the policy level.
rootCodeGroup.AddChild(virtualIntranet);
pLevel.RootCodeGroup = rootCodeGroup;
appDomain.SetAppDomainPolicy(pLevel);
}
private NamedPermissionSet FindNamedPermissionSet(string name)
{
IEnumerator policyEnumerator = SecurityManager.PolicyHierarchy();
while (policyEnumerator.MoveNext())
{
PolicyLevel currentLevel = (PolicyLevel)policyEnumerator.Current;
if (currentLevel.Label == "Machine")
{
IList namedPermissions = currentLevel.NamedPermissionSets;
IEnumerator namedPermission = namedPermissions.GetEnumerator();
while (namedPermission.MoveNext())
{
if (((NamedPermissionSet)namedPermission.Current).Name == name)
{
return ((NamedPermissionSet)namedPermission.Current);
}
}
}
}
return null;
}
Thanks in advance...
Mike
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20070522/ad880470/attachment.html>
More information about the Ironpython-users
mailing list