LIBERAR SUB-PROGRAMA INSTANCIADO DO PRINCIPAL

LRICX 05/06/2013 20:23:26
#424414
Caros colegas,

Estou com dificuldades de liberar totalmente programas executáveis instanciados pelo programa principal através do Assembly e CreateInstance. As rotinas funcionam perfeitamente, entretanto, depois de encerrado o sub-programa que foi chamado pelo programa principal, para que eu possa atualizar a versão deste, ou seja, substituir o programa chamado, cujo usuários estejam utilizando o Sistema (executável Principal), é necessário que o programa principal seja encerrado também, ou seja, todos devem sair do sistema para a devida atualização do sub-programa. Existe alguma maneira de ser liberado totalmente o programa chamado da memória depois que foi encerrado para que possa ser feito a atualização deste programa sem ter que encerrar o sistema totalmente? Abaixo está descrito a chamada dos sub-programas. Esta chamada está em uma class library:

Dim extAssembly As System.Reflection.Assembly = System.Reflection.Assembly.UnsafeLoadFrom(Pub.pathsistema & [Ô]\[Ô] & Programa & [Ô].exe[Ô])

Dim FormType As Type = extAssembly.GetType(Programa & [Ô].[Ô] & Formulario, True)

Dim extForm As Object = Activator.CreateInstance(FormType, Nothing, Nothing, Param, Nothing, Nothing)

extForm.Show()


Se puder me ajudar nesta dúvida, fico extremamente agradecido. Aguardo breve retorno. Muito obrigado.

Atenciosamente

Luiz Ricardo
LLAIA 06/06/2013 09:52:48
#424419
Essa chamada pela Class Library é de um método static/shared ou está em um objeto? Se estiver em um objeto, acho que o mesmo está mantendo esses sub-programas referenciados não permitindo que vc faça a substituição na atualização. Veja se consegue dá um Dispose() nesse objeto hipotético.
OCELOT 06/06/2013 10:02:34
#424421
O .Net não permite que assemblies sejam [Ô]descarregados[Ô] da memória sem que o AppDomain seja finalizado, quando você carrega um assembly da forma como fez ele é carregado no AppDomain padrão do seu programa então só quando o seu programa for finalizado é que ele vai ser descarregado e não tem o que fazer.

é possível criar um AppDomain secundário, porém é mais complicado trabalhar com isso, tem algumas limitações do que pode ser feito e ainda assim é necessário finalizar esse AppDomain manualmente, então você precisaria saber quando ele não é mais necessário para poder fazer isso.

Outra coisa é que não recomendo fazer desta forma com executáveis, o melhor seria você usar DLLs para estes sub programas, fica basicamente a mesma coisa que já está no seu código, só que na DLL não é gerado algumas partes de código que são específicas para EXEs
LRICX 06/06/2013 11:49:07
#424424
Bom dia a todos!

A estrutura está montada da seguinte forma:

Codigo no Programa Principal abaixo:

Imports MAIN

Public Class FormPrincipal

Dim Instancia As New ClasseInstanciar

Private Sub FormPrincipal_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

Pub.pathsistema = Application.StartupPath

etc...

End Sub

Private Sub EventoMenu_Click(ByVal sender As Object, ByVal e As System.EventArgs) [ô]Click do Menu Dinâmico

If CType(sender, MenuItem).Name <> Nothing Then

Pub.Programa = CType(sender, MenuItem).Name

If Instancia.Instanciar(Pub.Programa, Pub.Param) = False Then
Me.Close()
Exit Sub
End If
End If

etc...

End Sub


Codigo no Programa Chamado:

Imports MAIN

Public Class FormChamado

Dim BancoDados As New ClasseBancoDados(Pub.conexao)

etc...

Private Sub FimProgramaChamado

Me.Close

End Sub


Código da Class Library chamado de MAIN ( única DLL que contém várias Classes como: ClasseInstanciar, Pub (contém variáveis shared apenas), ClasseBancoDados, ClasseMenu, ControleFormulario, etc...):

ClasseInstanciar contém o seguinte código:

Imports System.Reflection
Imports System.Windows.Forms

Public Function Instanciar(ByVal Programa As String, Optional ByVal Param() As Object = Nothing) As Boolean

Dim extAssembly As System.Reflection.Assembly = System.Reflection.Assembly.UnsafeLoadFrom(Pub.pathsistema & [Ô]\[Ô] & Programa & [Ô].exe[Ô])

Try

Dim FormType As Type = extAssembly.GetType(Programa & [Ô].[Ô] & Formulario, True)

Dim extForm As Object = Activator.CreateInstance(FormType, Nothing, Nothing, Param, Nothing, Nothing)

extForm.Show()

Catch ex As Exception

MessageBox.Show([Ô]Ocorreu um erro durante a chamada do programa: [Ô] & ex.Message, _
[Ô]Executa Rotina[Ô], MessageBoxButtons.OK, MessageBoxIcon.Error)

Return False

End Try

Return True

End Function

End Class

Obs: Na DLL MAIN cada classe no projeto foi criado separado (Adicionar/Novo Item/Classe)

Leandro, shared estão designados para as variáveis criadas na classe PUB na DLL. Postei melhor os códigos de acordo com o projeto.

OCELOT, estava com receio sobre AppDomain. Já li a respeito disso, porém é um tanto complicado, mas se for esta a solução, você poderia postar um exemplo de como utilizar isto?

Obrigado a todos!!

Que Deus abençoe!!!

Atc,

Luiz Ricardo
Faça seu login para responder