#Region " Imports "
Imports System.Reflection
Imports System.Security
Imports System.Security.Permissions
#End Region
#Region " Resource Util "
Namespace ElektroKit.Core.Application.Resources.Tools
Partial Public NotInheritable Class ResourceUtil
#Region " Public Methods "
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Loads a resource in memory and executes its main entrypoint.
''' <para></para>
''' The resource must be a .NET assembly.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Execute(My.Resources.MyProgram)
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="resource">
''' The resource to execute.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="EntryPointNotFoundException">
''' Entrypoint not found in the specified resource. Are you sure it is a .NET assembly?
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Sub Execute(ByVal resource As Byte())
ResourceUtil.Execute(resource, Nothing)
End Sub
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Loads a resource in memory and executes its main entrypoint.
''' <para></para>
''' The resource must be a .NET assembly.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' Execute(My.Resources.MyProgram, {"Parameter 1", "Parameter 2", "etc..."})
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="resource">
''' The resource to execute.
''' </param>
'''
''' <param name="parameters">
''' The parameters to pass to the method executed.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="EntryPointNotFoundException">
''' Entrypoint not found in the specified resource. Are you sure it is a .NET assembly?
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Sub Execute(ByVal resource As Byte(), ByVal parameters As Object())
Dim helper As New ExecuteHelper()
helper.LoadAssembly(resource, parameters)
End Sub
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Loads a resource in memory and executes its main entrypoint.
''' <para></para>
''' The resource must be a .NET assembly.
''' <para></para>
''' If the loaded assembly attempts to force an application termination
''' by for example internaly calling <see cref="Environment.Exit"/>, then the call is catched and ignored.
''' <para></para>
''' The downside is that the loaded assembly will not be able to call (P/Invoke) unmanaged code. You are advised.
''' <para></para>
''' *** Note that this is a experimental methodology. ***
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' ExecuteSafe(My.Resources.MyProgram)
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="resource">
''' The resource to execute.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="EntryPointNotFoundException">
''' Entrypoint not found in the specified resource. Are you sure it is a .NET assembly?
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Sub ExecuteSafe(ByVal resource As Byte())
ResourceUtil.ExecuteSafe(resource, Nothing)
End Sub
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Loads a resource in memory and executes its main entry point.
''' <para></para>
''' The resource must be a .NET assembly.
''' <para></para>
''' If the loaded assembly attempts to force an application termination
''' by for example internaly calling <see cref="Environment.Exit"/>, then the call is catched and ignored.
''' <para></para>
''' The downside is that the loaded assembly will not be able to call (P/Invoke) unmanaged code. You are advised.
''' <para></para>
''' *** Note that this is a experimental methodology. ***
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <example> This is a code example.
''' <code>
''' ExecuteSafe(My.Resources.MyProgram, {"Parameter 1", "Parameter 2", "etc..."})
''' </code>
''' </example>
''' ----------------------------------------------------------------------------------------------------
''' <param name="resource">
''' The resource to execute.
''' </param>
'''
''' <param name="parameters">
''' The parameters to pass to the method executed.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="EntryPointNotFoundException">
''' Entrypoint not found in the specified resource. Are you sure it is a .NET assembly?
''' </exception>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Public Shared Sub ExecuteSafe(ByVal resource As Byte(), ByVal parameters As Object())
' This is where the main executable resides. For more info on this, see the "Remarks" section at:
' http://msdn.microsoft.com/en-us/library/system.appdomainsetup.applicationbase(v=vs.110).aspx#Anchor_1
Dim adSetup As New AppDomainSetup()
adSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
' Permissions of the AppDomain/what it can do.
Dim permission As New PermissionSet(PermissionState.None)
With permission
' All SecurityPermission flags EXCEPT UnmanagedCode, which is required by Environment.Exit() method.
.AddPermission(New SecurityPermission(SecurityPermissionFlag.AllFlags And Not SecurityPermissionFlag.UnmanagedCode))
.AddPermission(New EnvironmentPermission(PermissionState.Unrestricted))
.AddPermission(New EventLogPermission(PermissionState.Unrestricted))
.AddPermission(New FileDialogPermission(PermissionState.Unrestricted))
.AddPermission(New FileIOPermission(PermissionState.Unrestricted))
.AddPermission(New GacIdentityPermission(PermissionState.Unrestricted))
.AddPermission(New IsolatedStorageFilePermission(PermissionState.Unrestricted))
.AddPermission(New KeyContainerPermission(PermissionState.Unrestricted))
.AddPermission(New PerformanceCounterPermission(PermissionState.Unrestricted))
.AddPermission(New PrincipalPermission(PermissionState.Unrestricted))
.AddPermission(New ReflectionPermission(PermissionState.Unrestricted))
.AddPermission(New RegistryPermission(PermissionState.Unrestricted))
.AddPermission(New SiteIdentityPermission(PermissionState.Unrestricted))
.AddPermission(New StorePermission(PermissionState.Unrestricted))
.AddPermission(New TypeDescriptorPermission(PermissionState.Unrestricted))
.AddPermission(New UIPermission(PermissionState.Unrestricted))
.AddPermission(New UrlIdentityPermission(PermissionState.Unrestricted))
.AddPermission(New ZoneIdentityPermission(PermissionState.Unrestricted))
End With
' Our sandboxed AppDomain.
Dim domain As AppDomain = AppDomain.CreateDomain("SomeGenericName", Nothing, adSetup, permission, Nothing)
Try
' Create an instance of Helper in the sandboxed AppDomain.
Dim helper As ExecuteHelper = DirectCast(domain.CreateInstanceAndUnwrap(GetType(ExecuteHelper).Assembly.FullName, GetType(ExecuteHelper).FullName), ExecuteHelper)
helper.LoadAssembly(resource, parameters)
Catch ex As TargetInvocationException When (ex.InnerException.GetType() = GetType(SecurityException))
' Some kind of permissions issue occured here, possibly an attempt to call Environment.Exit() or call (P/Invoke) unmanaged code.
' Do Nothing.
Catch ex As Exception
Throw
End Try
End Sub
#End Region
End Class
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' A class that serves to execute assemblies that are stored as application resource (eg. My.Resources.MyProgram1 )
''' </summary>
''' ----------------------------------------------------------------------------------------------------
Friend NotInheritable Class ExecuteHelper : Inherits MarshalByRefObject
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Loads the assembly.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <param name="bytes">
''' The bytes of the assembly/resource to execute.
''' </param>
'''
''' <param name="parameters">
''' The parameters to pass to the method executed.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <exception cref="EntryPointNotFoundException">
''' Entrypoint not found in the specified resource. Are you sure it is a .NET assembly?
''' </exception>
''' ----------------------------------------------------------------------------------------------------
Public Sub LoadAssembly(ByVal bytes As Byte(), ByVal parameters As Object())
Dim ass As Assembly = Assembly.Load(bytes)
Dim method As MethodInfo = ass.EntryPoint
If (method IsNot Nothing) Then
Dim instance As Object = ass.CreateInstance(method.Name)
method.Invoke(instance, parameters)
If (instance IsNot Nothing) AndAlso (instance.GetType().GetInterfaces.Contains(GetType(IDisposable))) Then
DirectCast(instance, IDisposable).Dispose()
End If
instance = Nothing
method = Nothing
ass = Nothing
Else
Throw New EntryPointNotFoundException("Entrypoint not found in the specified resource. Are you sure it is a .NET assembly?")
End If
End Sub
End Class
End Namespace
#End Region