Unzip Application zip file

MarcusH
Contributor III

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

MarcusH_0-1709563350998.png

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

 

1 ACCEPTED SOLUTION

sameburn
New Contributor III

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)	

 

 

View solution in original post

4 REPLIES 4

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
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.

sameburn
New Contributor III

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)	

 

 

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