Forum Discussion

MarcusH's avatar
MarcusH
Contributor III
10 months ago

Unzip Application zip file

I am trying to save the XML files in the application zip file as separate XML files rather than a single zip. I get the zip file as a byte array and then pass that to XFZip.Unzip

The code executes without an error and without any files being saved as well. Does anyone have any suggestions or can point out where I am going wrong with the code? 

OnPrem V7.4.2

Dim xmlOptions As New XmlExtractOptions
xmlOptions.ExtractAllItems = True

Dim folderNameForExtract As String = "XMLs"
Dim extractPath As String = $"{Environment.GetEnvironmentVariable ("Temp")}\{folderNameForExtract}\"

'Execute the Metadata Extract
Using dbConnFW As DBConnInfo = BRAPi.Database.CreateFrameworkDbConnInfo(si)
    Using dbConnApp As DBConnInfo = BRAPi.Database.CreateApplicationDbConnInfo(si)
        Dim zippedBytes As Byte() = ApplicationZipFileHelper.Extract(dbConnFW, dbConnApp, Nothing, xmlOptions)

        XFZip.Unzip(zippedBytes, extractPath)

    End Using
End Using

 

  • Hi MarcusH 

    You can (also) use the System.IO.Compression namespace here to ExtractToDirectory.  If you extract your zip file from a source directory e.g rather than from bytes().  Below is some sample code that achieves the same effect.

    EDIT: just read your follow up comment. Sounds like you already know this 🙂

    	'' Imports the namespace
    	'Imports System.IO.Compression
    	
    	' Get File Path (FileShare)
    	Dim configSettings As AppServerConfigSettings = AppServerConfig.GetSettings(si)
    	Dim fullPath As String = Path.Combine(FileShareFolderHelper.GetGroupsFolderForApp(si, True, configSettings.FileShareRootFolder, si.AppToken.AppName), "Administrators")
    	
    	' The path of the zip file to decompress
    	Dim zipPath As String = String.Format("{0}\archive.zip", fullPath)
    	
    	' The path of the directory to extract the files to
    	Dim extractPath As String = String.Format("{0}\extract", fullPath)
    	If Not Directory.Exists(fullPath) Then Directory.CreateDirectory(fullPath)
    	
    	' Extracts all the files from the zip file to the directory
    	ZipFile.ExtractToDirectory(zipPath, extractPath)	

     

     

  • sameburn's avatar
    sameburn
    Contributor II

    Hi MarcusH 

    You can (also) use the System.IO.Compression namespace here to ExtractToDirectory.  If you extract your zip file from a source directory e.g rather than from bytes().  Below is some sample code that achieves the same effect.

    EDIT: just read your follow up comment. Sounds like you already know this 🙂

    	'' Imports the namespace
    	'Imports System.IO.Compression
    	
    	' Get File Path (FileShare)
    	Dim configSettings As AppServerConfigSettings = AppServerConfig.GetSettings(si)
    	Dim fullPath As String = Path.Combine(FileShareFolderHelper.GetGroupsFolderForApp(si, True, configSettings.FileShareRootFolder, si.AppToken.AppName), "Administrators")
    	
    	' The path of the zip file to decompress
    	Dim zipPath As String = String.Format("{0}\archive.zip", fullPath)
    	
    	' The path of the directory to extract the files to
    	Dim extractPath As String = String.Format("{0}\extract", fullPath)
    	If Not Directory.Exists(fullPath) Then Directory.CreateDirectory(fullPath)
    	
    	' Extracts all the files from the zip file to the directory
    	ZipFile.ExtractToDirectory(zipPath, extractPath)	

     

     

    • MarcusH's avatar
      MarcusH
      Contributor III

      Thanks Sam. The unzip works but the compression library is trying to use a folder on the web server for its temporary folder. So I have changed my approach: get the application zip file contents as a byte array, create a zip file in memory and then read the contents of that file. Seems to work and cuts out the creation of the zip file itself.

      Dim xmlOptions As New XmlExtractOptions
      xmlOptions.ExtractAllItems = True
      
      'Execute the Metadata Extract
      Using dbConnFW As DBConnInfo = BRAPi.Database.CreateFrameworkDbConnInfo(si)
          Using dbConnApp As DBConnInfo = BRAPi.Database.CreateApplicationDbConnInfo(si)
              Dim zipBytes As Byte() = ApplicationZipFileHelper.Extract(dbConnFW, dbConnApp, Nothing, xmlOptions)
      
              ' Dictionary to store file names and their contents
              Dim fileContents As New Dictionary(Of String, String)
      
              ' Decompress the zipped bytes into memory
              Using zipStream As New MemoryStream(zipBytes)
                  Using archive As New ZipArchive(zipStream, ZipArchiveMode.Read)
                      ' Iterate through each entry in the zip archive
                      For Each entry As ZipArchiveEntry In archive.Entries
                          ' Read the contents of the entry into a string
                          Using entryStream As Stream = entry.Open()
                              Using reader As New StreamReader(entryStream)
                                  Dim contents As String = reader.ReadToEnd()
      
                                  ' Add the file name and contents to the dictionary
                                  fileContents.Add(entry.FullName, contents)
                              End Using
                          End Using
                      Next
                  End Using
              End Using
              
              ' Display the contents of each file
              For Each kvp As KeyValuePair(Of String, String) In fileContents
                  ' File contents are in kvp.Value
                  BRApi.ErrorLog.LogMessage(si, "File Name: " & kvp.Key)
              Next
                  
          End Using
      End Using

       

  • MikeG's avatar
    MikeG
    Contributor III

    Hi MarcusH , Why not just extract the files one at a time?  You either do it up front or splice apart the Full Application XML.  Then you can push the metadata file to it's own folder, Dashboards to it's own folder, etc.  It may be a quicker path to completing what you're wanting to do, which is just create backups as of a point in time, right?

     

  • MarcusH's avatar
    MarcusH
    Contributor III

    Sorry Mike - in my eagerness I hit the wrong button. I am trying to save a bit of time in the zip/unzip process. The API returns a byte array which is then saved as a zip file. In order to read the zip file you need to get a byte array again so I thought I would cut out the middle step. As the XFZip.Unzip function is not documented and I can't get it to work I will probably have to use the standard compression libraries for unzipping the file ie save the application file as a zip then read and unzip.