0

Am attempting to Serialize a dynamically generated/compiled assembly to store into SQL and then subsequently extract the assembly for use. However, I am hitting an error that is driving me nuts.

"Could not load file or assembly '<random code>, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified."

When I try to De-Serialize the Assembly. Will appreciate any pointers. Partial codes:

    '--------------------------------------------------------------
    'This section SUCCESSFULLY Compile & Execute the Dynamic Code
    '  vsResult returns ok.
    '  **Note: This is partial code to create the compiler.
    '--------------------------------------------------------------
    Dim voCompileResults As System.CodeDom.Compiler.CompilerResults = voCompiler.CompileAssemblyFromSource(voCompilerParams, sb.ToString)
    Dim voAssembly As Reflection.Assembly = voCompileResults.CompiledAssembly
    Dim voInstance As Object = Activator.CreateInstance(voAssembly.GetType("libARules.clsMyRoutine"), {New libARules.Sys.clsInterProcessData(New System.Xml.XmlDocument), New libArrowOps.clsDBAccess})
    Dim vsResult As String = voInstance.GetType().InvokeMember("Run", Reflection.BindingFlags.InvokeMethod, Nothing, voInstance, Nothing)

    '----------------------------------------------------
    'Attempt to Serialize the Assembly for store/forward
    '----------------------------------------------------
    Dim voMemStream As New IO.MemoryStream
    Dim voBF As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
    voBF.AssemblyFormat = Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
    voBF.Serialize(voMemStream, voCompileResults.CompiledAssembly)

    '--------------------------------------
    'Reset the MemoryStream position to begining
    '--------------------------------------
    voMemStream.Position = 0

    '--------------------------------------
    'Attempt to De-Serialize the MemoryStream back to an assembly
    '--------------------------------------
    voBF = New Runtime.Serialization.Formatters.Binary.BinaryFormatter
    voBF.AssemblyFormat = Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
    voAssembly = voBF.Deserialize(voMemStream)
    '----- **Error Here** ---------------------------------

ERROR At this point: at the line voAssembly = voBF.Deserialize(voMemStream)

Could not load file or assembly '...<random code>..., Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

jlee88my
  • 2,935
  • 21
  • 28

1 Answers1

1

Ok, I finally figured it out after a nap ... Documenting it here for "future generations" :P

Apparently, I should not be Serializing/De-Serializing the CompiledAssembly.

    '-----------------------------------------------------
    'Instead of Generating in Memory, generate it into a temporary Assembly file (I don't need the CompiledAssembly from the compiler).
    ' Note: Again, this is partial code, with only the important parts here.
    '-----------------------------------------------------
    voCompilerParams.ReferencedAssemblies.Add("mscorlib.dll")
    voCompilerParams.GenerateInMemory = False
    voCompilerParams.OutputAssembly = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "deleteNow_" & Guid.NewGuid().ToString() & ".dll")

    Dim voCompileResults As System.CodeDom.Compiler.CompilerResults = voCompiler.CompileAssemblyFromSource(voCompilerParams, sb.ToString)

    '--------------------------------------------------------------------------
    'After the Assembly is generated, open the Assembly file and read the entire content into a byte buffer.
    'Note that this byte buffer **CAN BE STORED into an SQL BLOB field.**
    '--------------------------------------------------------------------------
    Dim voInstance As Object = Nothing
    Dim vsResult As String = ""
    Dim voAssembly As Reflection.Assembly = Nothing
    If Not voCompileResults.Errors.HasErrors Then
        '----------------------------------------------------------------
        'No compilation error, open and read the generated assembly file
        '  into a Byte array.
        '----------------------------------------------------------------
        Dim voBuffer() As Byte = Nothing
        Dim voFileStream As IO.FileStream = IO.File.OpenRead(voCompilerParams.OutputAssembly)
        If voFileStream.CanRead Then
            ReDim voBuffer(voFileStream.Length - 1)
            voFileStream.Read(voBuffer, 0, voFileStream.Length)
        End If
        voFileStream.Close()
        IO.File.Delete(voCompilerParams.OutputAssembly) 'Clean-up after ourselves.

        '----------------------------------------------------------------
        'Now, re-create the CompiledAssembly from the Byte array.
        '----------------------------------------------------------------
        If Not IsNothing(voBuffer) Then
            voAssembly = Reflection.Assembly.Load(voBuffer)
        End If
        If Not IsNothing(voAssembly) Then
            '--------------------------------------------
            'Instantiate my dynamically compiled class
            '--------------------------------------------
            voInstance = Activator.CreateInstance(voAssembly.GetType("libARules.clsMyRoutine"), {New libARules.Sys.clsInterProcessData(New System.Xml.XmlDocument), New libMyLib.clsMyClass})
            If Not IsNothing(voInstance) Then
               '------------------------------------------------
               'Run my dynamic code to proof that it is working
               '------------------------------------------------
                vsResult = voInstance.GetType().InvokeMember("Run", Reflection.BindingFlags.InvokeMethod, Nothing, voInstance, Nothing)
            End If
        End If
    End If

And whola... the vsResult is populated. This is a proof of concept that the CompiledAssembly can be stored and reused later. NOTING that the actual temporary assembly file has been deleted before the voAssembly object is recreated from voBuffer().

jlee88my
  • 2,935
  • 21
  • 28