none
Travailler un fichier .zip en mémoire RRS feed

  • Question

  • Bonjour à tous, j'ai une question un peu technique.

    Dans mon projet j'ai un fichier temp.zip, créé avec la compression gzip, et qui contient un executable programmé en vb.net

    Ce que je souhaite faire c'est executer le fichier temp.exe qui se trouve dans l'archive temp.zip mais sans copier ce fichier sur le disque dur.

    Voilà le code que j'utilise :

    Imports System.Net
    Imports System.IO
    Imports System.IO.Compression
    Imports System.Reflection
    
    Public Class Form1
      Public assembly As Assembly = Assembly.GetExecutingAssembly()
    
      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Execute()
      End Sub
    
      Sub Execute()
        Dim resources As String() = assembly.GetManifestResourceNames()
        For Each resource As String In resources
          If resource.Contains("temp.zip") Then
            Try
    
              'Lecture du fichier compresse
              'Dim monFileStream As New FileStream(resource, FileMode.Open)
              Dim resourceStream As Stream = assembly.GetManifestResourceStream(resource)
              ' Données du fichier placées dans un GZipStream
              Dim monGzipStream As New GZipStream(resourceStream, CompressionMode.Decompress)
    
              ' Tableau qui va contenir la taille du fichier
              Dim tailleOctets(3) As Byte
    
              ' Positionnement dans le Stream pour récupérer la taille
              Dim position As Integer = CInt(resourceStream.Length - 4)
              resourceStream.Position = position
    
              ' Récupération de la taille du fichier
              resourceStream.Read(tailleOctets, 0, 4)
    
              ' Repositionnement en début du Stream
              resourceStream.Position = 0
    
              ' Conversion de la taille du fichier en entier
              Dim tailleFichier As Integer = BitConverter.ToInt32(tailleOctets, 0)
              ' Dimesionnement du buffer
              Dim buffer(tailleFichier + 100) As Byte
              ' Offset qui permettra de se repérer dans le Stream
              Dim monOffset As Integer = 0
    
    
              While (True)
    
                ' Les données sont décompressées et placées dans le buffer
                Dim decompressionOctets As Integer = monGzipStream.Read(buffer, monOffset, 100)
    
                ' Tant qu'il reste des données on continue
                If (decompressionOctets = 0) Then
                  Exit While
                End If
    
                ' On icrémente l'offset pour ne pas repartir de 0 à chaque fois...
                monOffset += decompressionOctets
    
              End While
              'fermeture du stream
              monGzipStream.Close()
    
              'execution du fichier
              Dim exeAssembly As Assembly = assembly.Load(buffer)
              exeAssembly.EntryPoint.Invoke(Nothing, Nothing)
              Environment.[Exit](0)
    
            Catch ex As Exception
    
              MsgBox(ex.Message)
    
            End Try
    
          End If
    
        Next
      End Sub
    End Class
    

    Lorsque j'essaye j'ai une erreur :

    Exception has been thrown by the target of an invocation

    Quelqu'un voit t-il l'erreur ?

    Merci d'avance.

    mardi 25 mai 2010 19:38

Réponses

  • Bonjour,

     

    Votre Application.ExecutablePath retourne un chemin temporaire si l’application est lancée depuis une archive. Par exemple, une application que j’ai lancé depuis une archive de ‘c:\programming’ retourne une Application.Path :

    C:\Users\i-alepet\AppData\Local\Temp\1\Rar$EX00.187\ConsoleApplication2.exe

     

    Votre application essaye d’ouvrir des fichiers qu’elle ne trouve pas, avec FileOpen. Essayez de créer un fichier log pour écrire les valeurs de vos variables, je crois que ça vous aidera découvrir l’erreur plus vite.

     

    Cordialement,

    Alex

    __________________________________________________________________________________________

    Publiez un article sur une de ces technologies : Visual Basic, C#, C++, .NET, ASP.NET, SQL Server, Silverlight, SharePoint 2010, SharePoint 2007

     

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework

     

     

    • Marqué comme réponse BreizhNet mardi 1 juin 2010 12:38
    vendredi 28 mai 2010 09:04
  • Bonjour,

    Je miserai sur un problème d'index au niveau des lignes suivants :

    Dim key As String = Cutter(2)
    Dim Str As String = enc(Cutter(1), key)
    

    Le tableau Cutter est certainement vide...

    Cordialement


    Gilles TOURREAU - MVP C# - MCP - Architecte .NET/Consultant/Formateur - http://gilles.tourreau.fr
    • Marqué comme réponse BreizhNet mardi 1 juin 2010 12:38
    vendredi 28 mai 2010 21:45
    Modérateur

Toutes les réponses

  • Bonjour,

    En fait, lorsque vous appellez la méthode Main() via EntryPoint, vous exécutez une méthode statique dans le même AppDomain que votre application. Cette méthode Main() appelle des méthodes d'initialisation (SetCompatibleTextRenderingDefault() par exemple) qui doivent être appellée qu'une seule fois (ces initialisations sont générés par le compilateur).

    Or, votre application hôte appelle cette méthode ainsi que la méthode contenu dans votre assembly dézippé.

    Pour palier à ce problème, créez une méthode statique (Shared) Sub Main() dans votre application zippé afin de court circuité les initialisations qui sont générés par le compilateur.

    Cordialement


    Gilles TOURREAU - MVP C# - MCP - Architecte .NET/Consultant/Formateur - http://gilles.tourreau.fr
    mercredi 26 mai 2010 06:59
    Modérateur
  • Le résultat est le même, je vais essayer de copier le .zip sur le disque dur et d'executer l'exe en mémoire pour voir si ça change qualquechose
    mercredi 26 mai 2010 16:08
  • Bonjour,

    Pouvez-vous supprimer votre Try/Catch, déobguez votre application (touche F5) et regardez l'exception interne (InnerException) qui est affichée ? Cette exception contient l'origine du problème...

    Cordialement


    Gilles TOURREAU - MVP C# - MCP - Architecte .NET/Consultant/Formateur - http://gilles.tourreau.fr
    mercredi 26 mai 2010 18:28
    Modérateur
  • Voici l'exception :

    System.Reflection.TargetInvocationException was unhandled
     Message="Exception has been thrown by the target of an invocation."
     Source="mscorlib"
     StackTrace:
        at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)  at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)  at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)  at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)  at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)  at ConsoleApplication1.Class1.Main() in C:\Documents and Settings\tof\Mes documents\tof\dev\ConsoleApplication1\ConsoleApplication1\Class1.vb:line 38  at System.AppDomain._nExecuteAssembly(Assembly 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.Run(ExecutionContext executionContext, ContextCallback callback, Object state)  at System.Threading.ThreadHelper.ThreadStart()
     InnerException: System.IndexOutOfRangeException
        Message="Index was outside the bounds of the array."
        Source="Embedded"
        StackTrace:
          at Console.Console.Main()
        InnerException: 

    jeudi 27 mai 2010 03:29
  • Bonjour,

    Vous avez donc une exception au niveau de Console.Console.Main(). Un IndexOutOfRangeException signifie que vous accéder à une indice d'un tableau qui se trouve en dehors des limites de ce dernier.

    Pouvez-vous poster le code Console.Main() de votre application ?

    Cordialement


    Gilles TOURREAU - MVP C# - MCP - Architecte .NET/Consultant/Formateur - http://gilles.tourreau.fr
    jeudi 27 mai 2010 06:40
    Modérateur
  • Shared Sub Main()
        Dim Cuttkey As String = "/separation/"
        FileOpen(1, Application.ExecutablePath, OpenMode.Binary, OpenAccess.Read, OpenShare.Shared)
        Dim res As String = Space(LOF(1))
        FileGet(1, res)
        FileClose(1)
        Dim Cutter() As String
        Cutter = Split(res, Cuttkey)
        Dim key As String = Cutter(2)
        Dim Str As String = enc(Cutter(1), key)
        Try
          Dim ByteArray() As Byte = Encoding.Default.GetBytes(Str)
          Class1.Execute(ByteArray, Process.GetCurrentProcess().MainModule.FileName)
        Catch ex As Exception
          Environment.Exit(0)
        End Try
        Environment.Exit(0)
      End Sub
    jeudi 27 mai 2010 12:24
  • Bonjour,

     

    Votre Application.ExecutablePath retourne un chemin temporaire si l’application est lancée depuis une archive. Par exemple, une application que j’ai lancé depuis une archive de ‘c:\programming’ retourne une Application.Path :

    C:\Users\i-alepet\AppData\Local\Temp\1\Rar$EX00.187\ConsoleApplication2.exe

     

    Votre application essaye d’ouvrir des fichiers qu’elle ne trouve pas, avec FileOpen. Essayez de créer un fichier log pour écrire les valeurs de vos variables, je crois que ça vous aidera découvrir l’erreur plus vite.

     

    Cordialement,

    Alex

    __________________________________________________________________________________________

    Publiez un article sur une de ces technologies : Visual Basic, C#, C++, .NET, ASP.NET, SQL Server, Silverlight, SharePoint 2010, SharePoint 2007

     

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework

     

     

    • Marqué comme réponse BreizhNet mardi 1 juin 2010 12:38
    vendredi 28 mai 2010 09:04
  • Bonjour,

    Je miserai sur un problème d'index au niveau des lignes suivants :

    Dim key As String = Cutter(2)
    Dim Str As String = enc(Cutter(1), key)
    

    Le tableau Cutter est certainement vide...

    Cordialement


    Gilles TOURREAU - MVP C# - MCP - Architecte .NET/Consultant/Formateur - http://gilles.tourreau.fr
    • Marqué comme réponse BreizhNet mardi 1 juin 2010 12:38
    vendredi 28 mai 2010 21:45
    Modérateur
  • Bonjour,

     

    Csharploser, avez-vous réussi à progresser ?

     

    Cordialement,

    Alex

    __________________________________________________________________________________________

    Publiez un article sur une de ces technologies : Visual Basic, C#, C++, .NET, ASP.NET, SQL Server, Silverlight, SharePoint 2010, SharePoint 2007

     

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework, Workflow Foundation

     

     

    lundi 31 mai 2010 11:59
  • Non je n'ai pas progressé mais je vais voir avec vos 2 réponses si j'arrive à m'en sortir.

    Merci encore.

    mardi 1 juin 2010 12:38