Click here to Skip to main content
15,887,135 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
HI,

I have created one AppDomain and would like load and run one dll with in it along with some Io permission set. I could create the create the instance but have been failing to load the Assembly. I could not recognize the mistake that I am doing however the following error message while loading the assembly. Could you please help/correct me on this:

Error Message:

"
Additional information: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
"

stack Trace:

at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark& stackMark)
at System.Security.CodeAccessPermission.Demand()
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at AppDomainSample.AppDomainSample.ThrirdPartyDomainLoader.LoadAssembly(String dllPath)
at AppDomainSample.AppDomainSample.ThrirdPartyDomainLoader.LoadAssembly(String dllPath)
at AppDomainSample.AppDomainSample.Main() in D:\DotNetTraining0504\AppDomainSample\AppDomainSample\AppDomainSample.cs:line 34
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()


What I have tried:

using System;
using System.Reflection;
using System.Configuration;

namespace AppDomainSample
{
    public class AppDomainSample 
    {
        public static void Main()
        {
            var generateFilesPluginPath = ConfigurationManager.AppSettings["GenerateFilesPlugin"];
            var generateFilesPluginPathName = ConfigurationManager.AppSettings["GenerateFilesPluginName"];

            var appDomainSetup = new AppDomainSetup
            {
                ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase
            };


            var permissionSet = AppDomainPermissionSets.GetFileIOPermissionset();

            var generateFilesAppDomain = AppDomain.CreateDomain(
                generateFilesPluginPathName,
                null,
                appDomainSetup,
                permissionSet);

            var thrirdPartyDomainLoader =
                (ThrirdPartyDomainLoader)
                generateFilesAppDomain.CreateInstanceAndUnwrap(
                    typeof(ThrirdPartyDomainLoader).Assembly.FullName,
                    typeof(ThrirdPartyDomainLoader).FullName);

            thrirdPartyDomainLoader.LoadAssembly(@"D:\EpamDotNetTraining0504\AppDomainSample\GenerateFilesPlugin\bin\Debug\GenerateFilesPlugin.dll");

            thrirdPartyDomainLoader.MethodInvoker(
                ApplicationBase(generateFilesPluginPath),
                "GenerateFilesPlugin.GenerateFiles",
                "CreateFile",
                 @"D:\",
                "temp.text");

            AppDomain.Unload(generateFilesAppDomain);

            Console.ReadLine();
        }

        public class ThrirdPartyDomainLoader : MarshalByRefObject
        {
            private Assembly _assembly;

            public void LoadAssembly(string dllPath)
            {
               var  _assembly = Assembly.LoadFrom(dllPath);
            }

            public void MethodInvoker(string dllpath, string className, string methodName, params object[] parameters)
            {
                var assm = Assembly.LoadFile(dllpath);

                var type1 = assm.GetType(className);

                var genericInstance = Activator.CreateInstance(type1);

                var method = type1.GetMethod(methodName);

                object obje = null;
                try
                {
                    obje = method.Invoke(genericInstance, new object[] { 1, 2 });
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }

                Console.WriteLine(obje);
            }
        }

        public static string ApplicationBase(string path)
        {
            var appDomainSetup = new AppDomainSetup { ApplicationBase = path };

            return appDomainSetup.ApplicationBase;
        }
    }
}



Permission sets applied for the AppDomain
public static class AppDomainPermissionSets
{
    public static PermissionSet GetFileIOPermissionset()
    {
        var permissionSet = new PermissionSet(PermissionState.None);
        permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));

        permissionSet.AddPermission(
            new FileIOPermission(
                FileIOPermissionAccess.Write,
                ConfigurationManager.AppSettings["GenerateFilesPluginRestrictedPath"]));

        return permissionSet;
    }

}


Logic in 3rd party Dll:

using System;
using System.IO;

namespace GenerateFilesPlugin
{
    public class GenerateFiles
    {
        public bool CreateFile(string path, string file)
        {
            if (path == null || file == null)
            {
                Console.WriteLine("Invalid Input");

                return false;
            }

            try
            {
                File.Create(Path.Combine(path, file));

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            return false;
        }
    }
}
Posted
Updated 21-May-17 2:43am
v2

1 solution

It seems the user running the site under IIS has no permissions to do that (to load external assemblies)...
Try one of these:
1. Switch usr (it is good for testing, but maybe improper for real environment)
2. Set trust level to full: Set a Trust Level (IIS 7)[^]
 
Share this answer
 
v2
Comments
Naga Sindhura 21-May-17 8:17am    
Hi Kornfeld Eliyahu Peterб

Yes you are true, I don't have local admin permissions and even switching user is also not possible. However, I have added the following lines in my app.config but I could see the similar error message like earlier.
<system.web>
<trust level="Full"/>
Kornfeld Eliyahu Peter 21-May-17 8:25am    
Check event log - you not have the permission to override trust level...
(also read this - just for fun :-)... https://msdn.microsoft.com/en-us/library/ms998326.aspx)
Naga Sindhura 21-May-17 8:35am    
Sure thanks, I will look into it. I have tried to load the dll in AppDomainSample -> Main() method using the following code and is working without any issues, but I could not load it through thrirdPartyDomainLoader instance. Do you think, still is this an issue with permission issue or wrong code.

var assm =
Assembly.LoadFile(
@"D:\DotNetTraining0504\AppDomainSample\GenerateFilesPlugin\bin\Debug\GenerateFilesPlugin.dll")
.GetType("GenerateFilesPlugin.GenerateFiles");
Kornfeld Eliyahu Peter 21-May-17 8:54am    
It may be the way you are creating your new application domain...
Try the most simple form: AppDomain.CreateDomain('name-for-new-domain);
Also CreateInstanceAndUnwrap seems to be wrong...
Try this: CreateInstanceAndUnwrap(Assembly.GetAssembly(typeof(ThrirdPartyDomainLoader)).FullName, typeof(ThrirdPartyDomainLoader).ToString()) as ThrirdPartyDomainLoader
(It based on code I wrote in one of my tips and proved to be working :-))
Naga Sindhura 21-May-17 9:17am    
I have changed my code from var generateFilesAppDomain = AppDomain.CreateDomain(
generateFilesPluginPathName,null,appDomainSetup,permissionSet); to generateFilesAppDomain = AppDomain.CreateDomain(generateFilesPluginPathName), however, I need to restrict the domain execution with some sort of permission like not access with C drive or some sort of sensitive paths. How could I do that one? any suggestions.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900