Community
Vault Forum
Welcome to Autodesk’s Vault Forums. Share your knowledge, ask questions, and explore popular Vault topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

GetFiles using .NET

12 REPLIES 12
Reply
Message 1 of 13
Rob.O
4136 Views, 12 Replies

GetFiles using .NET

Hi All,

 

I am working on a VB.NET project that will log in to a Vault DB, get all of the latest files/folders from the DB and download them to the local working folder.
I started with the VaultMirror sample from the SDK, but am running into problems.  I want the code to be very simple... not really a mirror function, so I have stripped a lot out.  I want the code to create the folders and download the files to the working folder of the local drive overwritting all folders/files that are already contained there.
I am able to login to the DB using the code below with no problems (that I can see):
<CommandMethod("VaultGetStandards")> _
    Public Sub VaultGetStandards()
        RunCommand("serverName")
    End Sub

    Public Sub RunCommand(ByVal serverName As String)

        Dim login As New UserPasswordCredentials(serverName, Vault, Username, Password, True)

        Using serviceManager As New WebServiceManager(login)
            Try
                'Dim root As Folder = serviceManager.DocumentService.GetFolderRoot()
                root = serviceManager.DocumentService.GetFolderRoot()

            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                MsgBox(ex.ToString(), "Error")
                Return
            End Try
        End Using

        Execute()

    End Sub

 

I am then using the FullMirrorVaultFolder function from the SDK sample to add the folders/files to the working folder:
Private Sub FullMirrorVaultFolder(ByVal folder As Folder, ByVal localFolder As String)
        If folder.Cloaked Then
            Return
        End If

        If Not Directory.Exists(localFolder) Then
            Directory.CreateDirectory(localFolder)
        End If

        Dim files As ADSK.File() = m_serviceManager.DocumentService.GetLatestFilesByFolderId(folder.Id, True)
        If files IsNot Nothing Then
            For Each file As ADSK.File In files
                If file.Cloaked Then
                    Continue For
                End If

                Dim filePath As String = Path.Combine(localFolder, file.Name)
                If System.IO.File.Exists(filePath) Then
                    If file.CreateDate <> System.IO.File.GetCreationTime(filePath) Then
                        DownloadFile(file, filePath)
                    End If
                Else
                    DownloadFile(file, filePath)
                End If
            Next
        End If

        Dim subFolders As Folder() = m_serviceManager.DocumentService.GetFoldersByParentId(folder.Id, False)
        If subFolders IsNot Nothing Then
            For Each subFolder As Folder In subFolders
                FullMirrorVaultFolder(subFolder, Path.Combine(localFolder, subFolder.Name))
            Next
        End If
    End Sub

 Everything seems to work well until the line:

Dim files As ADSK.File() = m_serviceManager.DocumentService.GetLatestFilesByFolderId(folder.Id, True)

 The code crashes on the above line.

 

I am atempting to run/debug the code through AutoCAD with a command method, so when the code crashes AutoCAD fatal errors.

 

Can someone tell me what I might be doing wrong?

 

Thanks in advance!

 

 

12 REPLIES 12
Message 2 of 13
Redmond.D
in reply to: Rob.O

It would be helpful if there was more information than "it crashes"

Try putting a try/catch block around the offending code so you can see the full Exception.



Doug Redmond
Software Engineer
Autodesk, Inc.

Message 3 of 13
Rob.O
in reply to: Redmond.D

Hi Doug!

 

Thanks for your reply.  I am still trying to learn .NET, so bear with me! 🙂  I am not very good at this yet.

 

I was having so many issues, that I decided to start over.  This time I used the VaultList code to get started.  I know it does not really do what I want, but I modified it with the pieces and parts I needed.  Here is the code in it's entirety:

 

 

Imports Microsoft.Web.Services3
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.Connectivity.WebServices
Imports Autodesk.Connectivity.WebServicesTools
Imports Autodesk.Connectivity.Explorer.ExtensibilityTools
Imports ADSK = Autodesk.Connectivity.WebServices
Imports System.IO
Imports System

Public Class GetVaultStandards

    Private Const HOST As String = "SERVERNAME HERE"
    Public m_file As Autodesk.Connectivity.WebServices.File
    Public strVltRoot As String
    Public MAX_FILE_SIZE As Long = 45 * 1024 * 1024
    Public m_vaultExplorer As IExplorerUtil
    Public m_serviceManager As WebServiceManager
    Public m_vault As String
    Public Display As IStatusDisplay
    Public root As Folder
    Public m_outputFolder As String
    Public m_folder As Folder
    Public localFolder As String

    <CommandMethod("VaultGetStandards")> _
    Public Sub VaultGetStandards()
        RunCommand(HOST)
    End Sub

    Public Sub RunCommand(ByVal serverName As String)

        Dim secSrv As SecurityService = New SecurityService()
        secSrv.SecurityHeaderValue = New Autodesk.Connectivity.WebServices.SecuritySvc.SecurityHeader
        secSrv.Url = "http://" + serverName + "/AutodeskDM/Services/SecurityService.asmx"

        secSrv.SignInReadOnly("USERNAME HERE", "PASSWORD HERE", "VAULT HERE")

        Dim docSrv As DocumentService = New DocumentService()
        docSrv.SecurityHeaderValue = New Autodesk.Connectivity.WebServices.DocumentSvc.SecurityHeader
        docSrv.SecurityHeaderValue.UserId = secSrv.SecurityHeaderValue.UserId
        docSrv.SecurityHeaderValue.Ticket = secSrv.SecurityHeaderValue.Ticket
        docSrv.Url = "http://" + serverName + "/AutodeskDM/Services/DocumentService.asmx"

        Dim login As UserPasswordCredentials = New UserPasswordCredentials(serverName, "VAULT HERE", "USERNAME HERE", "PASSWORD HERE", True)

        Using serviceManager As New WebServiceManager(login)
            Try
                Dim root As Folder = docSrv.GetFolderRoot()
                strVltRoot = root.FullName.ToString
                PrintFilesInFolder(root, docSrv)

            Catch ex As System.Exception
                MsgBox(ex.ToString, , "Error")
            End Try
        End Using
    End Sub

    Private Sub PrintFilesInFolder(ByVal parentFolder As Folder, ByVal docSvc As DocumentService)

        Dim files As Autodesk.Connectivity.WebServices.File() = docSvc.GetLatestFilesByFolderId(parentFolder.Id, True)

        If (Not files Is Nothing AndAlso files.Length > 0) Then

            Dim filename As String
            For Each Me.m_file In files
                filename = m_file.Name
                If strVltRoot = "$" Then
                    strVltRoot = "C:/Vault/"
                End If
                'm_listBox.Items.Add(parentFolder.FullName + "/" + file.Name)
            Next m_file

            m_outputFolder = parentFolder.FullName.Remove(0, 2)
            Dim filePath As String = Path.Combine(strVltRoot + m_outputFolder + "/", filename)
            For Each file As Autodesk.Connectivity.WebServices.File In files
                DownloadFile(file, filePath)
                localFolder = strVltRoot + m_outputFolder + "/"
            Next file
        End If

        Dim folders As Folder() = docSvc.GetFoldersByParentId(parentFolder.Id, False)
        If (Not folders Is Nothing AndAlso folders.Length > 0) Then
            'For Each folder As Folder In folders
            For Each Me.m_folder In folders
                PrintFilesInFolder(m_folder, docSvc)
                'FullMirrorVaultFolder(m_folder, localFolder)
            Next m_folder
        End If

    End Sub

    Public Sub DownloadFile(ByVal file, ByVal filePath)
        If Display IsNot Nothing Then
            Display.ChangeStatusMessage("Downloading " + file.Name)
        End If

        ' remove the read-only attribute
        If System.IO.File.Exists(filePath) Then
            System.IO.File.SetAttributes(filePath, FileAttributes.Normal)
        End If

        If file.FileSize > MAX_FILE_SIZE Then
            DownloadFileLarge(file, filePath)
            MsgBox("File too large")
        Else
            DownloadFileStandard(file, filePath)
        End If

        ' set the file to read-only
        System.IO.File.SetAttributes(filePath, FileAttributes.[ReadOnly])
    End Sub

    Public Sub DownloadFileStandard(ByVal file, ByVal filePath)
        Using stream As New FileStream(filePath, FileMode.Create, FileAccess.ReadWrite)
            Dim fileData As Byte()
            Try
                m_serviceManager.DocumentService.DownloadFile(file.Id, True, fileData)

                stream.Write(fileData, 0, fileData.Length)
                stream.Close()
            Catch ex As System.Exception
            End Try
        End Using
    End Sub

    Private Sub DownloadFileLarge(ByVal file, ByVal filePath)
        If System.IO.File.Exists(filePath) Then
            System.IO.File.SetAttributes(filePath, FileAttributes.Normal)
        End If

        Using stream As New FileStream(filePath, FileMode.Create, FileAccess.ReadWrite)
            Dim startByte As Long = 0
            Dim endByte As Long = MAX_FILE_SIZE - 1
            Dim buffer As Byte()

            While startByte < file.FileSize
                endByte = startByte + MAX_FILE_SIZE
                If endByte > file.FileSize Then
                    endByte = file.FileSize
                End If

                buffer = m_serviceManager.DocumentService.DownloadFilePart(file.Id, startByte, endByte, True)
                stream.Write(buffer, 0, buffer.Length)
                startByte += buffer.Length
            End While
            stream.Close()
        End Using
    End Sub

    Private Sub FullMirrorVaultFolder(ByVal m_folder, ByVal localFolder)
        If m_folder.Cloaked Then
            Return
        End If

        If Not Directory.Exists(localFolder) Then
            Directory.CreateDirectory(localFolder)
        End If

        Dim files As ADSK.File() = m_serviceManager.DocumentService.GetLatestFilesByFolderId(m_folder.Id, True)
        If files IsNot Nothing Then
            For Each file As ADSK.File In files
                If file.Cloaked Then
                    Continue For
                End If

                Dim filePath As String = Path.Combine(localFolder, file.Name)
                If System.IO.File.Exists(filePath) Then
                    If file.CreateDate <> System.IO.File.GetCreationTime(filePath) Then
                        DownloadFile(file, filePath)
                    End If
                Else
                    DownloadFile(file, filePath)
                End If
            Next
        End If

        Dim subFolders As Folder() = m_serviceManager.DocumentService.GetFoldersByParentId(m_folder.Id, False)
        If subFolders IsNot Nothing Then
            For Each subFolder As Folder In subFolders
                FullMirrorVaultFolder(subFolder, Path.Combine(localFolder, subFolder.Name))
            Next
        End If
    End Sub

    Public Interface IStatusDisplay
        Sub ChangeStatusMessage(ByVal message As String)
    End Interface

End Class

 The code runs until line 118 where I get a Null Reference error (see attached image and the comments below).  The first file found is copied (partially) to the proper folder (as long as the folder already exists).  I have not gotten the FullMirrorVaultFolder function to work yet (I will save that for later).  The file that is copied, ends up with 0 bytes of data and is obviously corrpt.  I am sure it has something to do with the FileData variable in line 118, but Iam not sure how to correct it.

 

 

 

m_serviceManager.DocumentService.DownloadFile(file.Id, True, fileData)

Immediate Window - A first chance exception of type 'System.NullReferenceException' occurred in VaultGetStandards.dll

 

 

 

Warning 2 - Variable 'fileData' is passed by reference before it has been assigned a value. A null reference exception could result at runtime.
Thanks for any help you can provide!

 

Message 4 of 13
Redmond.D
in reply to: Rob.O

Autodesk Developer Network might be a good place for you to go for help.  They can offer extra programming help and sample code.

 

The problem with line 118 is that you never assigned a value to m_serviceManager, so it has a default value of Nothing.  Nothing is refered to as 'null' is most other langauages, so that explains the NullReferenceException.

 

At a higher level, your code is just a mash-up to two different samples, which is not the best approach.  I recommed a more step-by-step approach.  Start with one sample.  Get it working.  Understand how it works.  Then add to it one piece at a time, verifing that each piece works as you add them.

 

It doesn't help that the VB version of VaultList is a bit mashed-up itself.  If you are using the WebServiceManager there is no need to call new on the DocumentService or SecurityService.  Likewise there is no need to call any of the SignIn functions if the WebServiceManager is being used. 

I recommend focusing on starting with VaultMirror,VaultFileBrowser or the C# version of VaultList.

 

 



Doug Redmond
Software Engineer
Autodesk, Inc.

Message 5 of 13
Rob.O
in reply to: Redmond.D

Thanks for the info Doug!

 

I have restarted the code again from the VaultList C# sample code.  The code is much lighter now, but I am still getting the NullReference error.  I tried to use the VaultMirror C# code, but I keep getting a .DLL error that I cannot resolve.  I wanted to use it so I could figure out what to pass to the m_serviceManager, but I cannot get it to work.

 

So, since I cannot use that as an example, can you give me a little more info on what value I should be passing to the m_serviceManager and possibly an exmple of how to do it?

 

Thanks for your time!

 

 

 

Message 6 of 13
Redmond.D
in reply to: Rob.O

You don't need m_serviceManager.  It's purpose is to make the WebServiceManager object available everywhere in your class.  Another approach is to just pass in the WebServiceManager object to the functions that need it, like in the C# version of VaultList.

 

If you want to use m_serviceManager, just set it to the WebServiceManager object that is created in the Using statement inside of your RunCommand routine.

 



Doug Redmond
Software Engineer
Autodesk, Inc.

Message 7 of 13
Rob.O
in reply to: Redmond.D

Hi Doug!

 

I guess I am just not getting this.  I have done a bit of programming in.NET already and have more or less been able to resolve most of the NullReference Exceptions I have seen, but this one has me stumped.

 

I tried to run the VB version of the VaultBrowser sample (unchanged) and I am getting a NullReferenceException was unhandled on the line of code below (from the OpenFileCommand class):

 

 

vaultExplorer.DownloadFile(file, filePath)

 Again, I have changed nothing in the sample code and this is what I get when I run the code.

 

Everything I have written for the Vault so far works fine until I try to download a file.  If all I want to do is log into the DB, list the files and download each of them with no error handling, no file/folder deletion, etc... how would you do it.  Better yet, I cannot even get a single file to download properly, so at this point, hardcoding a file name to try and download it would be beneficial.

 

I am stumped.

 

Sorry to bother you with this... I know you are busy.

 

Thanks again for your help!

Message 8 of 13
Rob.O
in reply to: Rob.O

Schweet!  I think I finally got it!  I ended up keeping the m_serviceManager and asigning it as a New WebServiceManager.  All seems to work correctly now!

 

Still not sure why the VaultBrowser smaple was causing me errors.

 

Anyway... thanks so much for your help Doug!

 

I will post some final code out here when I am done and maybe (if you have time) you can critique it for me to tell me what I could be doing better!

 

Thanks!

Message 9 of 13
achmidt
in reply to: Rob.O

Just wondering if you finished your script? Can we see it? I`m looking for smth similar, need to pull parts from the vault into the assembly.

 

Thanks,

Alex.

Inventor Virtual Parts Addin

http://apps.exchange.autodesk.com/INVNTOR/en/Detail/Index?id=appstore.exchange.autodesk.com%3Avirtualpartsadd-in_windows32and64%3Aen
Message 10 of 13
waynehelley
in reply to: Rob.O

Hi Dull_Blades,

 

If you still have it, could you please post your finished code?

 

Thanks,

Wayne Helley
Inventor 2013 Certified Professional

Autodesk Inventor Professional 2023
Visual Studio 2022
Windows 10 Pro, 64-bit
Message 11 of 13
Rob.O
in reply to: waynehelley

Hi All,

 

Not sure how I missed these previous requests for the code, but the reciept of a private message prompted me to check this thread again.

 

Below is the code I used.  I take no responsibility for anything that may go wrong if you use this code, so please use at your own risk.  Having said that, it was in use in our company for about a year and a half by 18-20 users and we never had a single issue.  We now have a different process so we no longer use the code.

 

Please ignore the amature nature of the code (the parts I wrote) as these are some of my first .NET programing attempts.

 

Imports Microsoft.Web.Services3
Imports Autodesk.AutoCAD.Runtime

Imports Autodesk.Connectivity.WebServices
Imports Autodesk.Connectivity.WebServicesTools

Imports Autodesk.Connectivity.Explorer.ExtensibilityTools
Imports ADSK = Autodesk.Connectivity.WebServices
Imports System.Windows.Forms
Imports System.IO
Imports System

Public Class GetVaultStandards

    Private Const HOST As String = "XXX.XXX.XX.X"
    Public m_file As Autodesk.Connectivity.WebServices.File
    Public Shared strVltRoot As String
    Public Shared MAX_FILE_SIZE As Long = 45 * 1024 * 1024
    Public m_vaultExplorer As IExplorerUtil
    Public m_serviceManager As WebServiceManager
    Public m_vault As String
    Public root As Folder
    Public Shared m_outputFolder As String
    Public m_folder As Folder
    Public localFolder As String
    Public dwnldFile As Autodesk.Connectivity.WebServices.File
    Public filePath As String
    Public folderpath As String
    Public Shared frmProgress As New Form1

    Public Shared Sub Main()

        ' Show progress bar while files/folders are copied/created
        frmProgress.Visible = True
        frmProgress.Refresh()
        frmProgress.Visible = True
        frmProgress.Refresh()
        RunCommand(HOST)
        frmProgress.Close()

    End Sub

    Public serviceManager As WebServiceManager
    Public Shared strFileCnt As String

    Public Shared Sub RunCommand(ByVal serverName As String)

        ' Create login credentials to proper Vault DB (Standards DB)
        Dim login As New UserPasswordCredentials(serverName, VaultName, UserName, password, True)
        Dim root As Folder

        ' Log in to Vault DB
        Using serviceManager As New WebServiceManager(login)
            root = serviceManager.DocumentService.GetFolderRoot()
        End Using

        Dim m_serviceManager As WebServiceManager
        m_serviceManager = New WebServiceManager(New UserPasswordCredentials(servername, vaultName, UserName, password, True))

        Dim FileArray As Array
        Dim SrchStatus As Autodesk.Connectivity.WebServices.SrchStatus
        Dim files As ADSK.File() = m_serviceManager.DocumentService.FindFilesBySearchConditions(Nothing, Nothing, Nothing, Nothing, True, Nothing, SrchStatus)
        strFileCnt = SrchStatus.TotalHits.ToString

        ' Set root to C:\Program Files
        If root.FullName = "$" Then
            strVltRoot = "C:/Program Files"
        End If

        m_outputFolder = strVltRoot

        ' Set output folder to local drive
        Dim localPath As String = m_outputFolder
        ' Set local path to delete
        Dim localPathDel As String = m_outputFolder + "/Standards"
        ' Delete all files from current standards folder
        If Directory.Exists(localPathDel) Then
            DeleteAllContents(localPathDel)
        Else
        End If
        ' Recreate each folder locally as found in the Vault
        FullMirrorVaultFolder(root, localPath)

    End Sub

    Public vaultExplorer As IExplorerUtil

    Public Shared Sub DownloadFile(ByVal file, ByVal filePath)

        ' remove the read-only attribute
        If System.IO.File.Exists(filePath) Then
            System.IO.File.SetAttributes(filePath, FileAttributes.Normal)
        End If

        If file.FileSize > MAX_FILE_SIZE Then
            DownloadFileLarge(file, filePath)
            MsgBox("File too large")
        Else
            DownloadFileStandard(file, filePath)
        End If

        ' set the file to read-only
        System.IO.File.SetAttributes(filePath, FileAttributes.[ReadOnly])

    End Sub

    Public Shared Sub DownloadFileStandard(ByVal file, ByVal filePath)

        Dim m_serviceManager As WebServiceManager
        m_serviceManager = New WebServiceManager(New UserPasswordCredentials(servername, vaultName, UserName, password, True))

        Using stream As New FileStream(filePath, FileMode.Create, FileAccess.ReadWrite)
            Dim fileData As Byte()

            fileData = Nothing
            m_serviceManager.DocumentService.DownloadFile(file.Id, True, fileData)

            stream.Write(fileData, 0, fileData.Length)
            stream.Close()
        End Using

    End Sub

    Public Shared Sub DownloadFileLarge(ByVal file, ByVal filePath)

        If System.IO.File.Exists(filePath) Then
            System.IO.File.SetAttributes(filePath, FileAttributes.Normal)
        End If

        Dim m_serviceManager As WebServiceManager
        m_serviceManager = New WebServiceManager(New UserPasswordCredentials(servername, vaultName, UserName, password, True))

        Using stream As New FileStream(filePath, FileMode.Create, FileAccess.ReadWrite)
            Dim startByte As Long = 0
            Dim endByte As Long = MAX_FILE_SIZE - 1
            Dim buffer As Byte()

            While startByte < file.FileSize
                endByte = startByte + MAX_FILE_SIZE
                If endByte > file.FileSize Then
                    endByte = file.FileSize
                End If

                buffer = m_serviceManager.DocumentService.DownloadFilePart(file.Id, startByte, endByte, True)
                stream.Write(buffer, 0, buffer.Length)
                startByte += buffer.Length
            End While
            stream.Close()
        End Using

    End Sub

    Private Shared Sub FullMirrorVaultFolder(ByVal m_folder, ByVal localFolder)

        If m_folder.Cloaked Then
            Return
        End If

        If Not Directory.Exists(localFolder) Then
            Directory.CreateDirectory(localFolder)
        End If

        Dim m_serviceManager As WebServiceManager
        m_serviceManager = New WebServiceManager(New UserPasswordCredentials(servername, vaultName, UserName, password, True))

        Dim files As ADSK.File() = m_serviceManager.DocumentService.GetLatestFilesByFolderId(m_folder.Id, True)
        If files IsNot Nothing Then
            For Each file As ADSK.File In files
                If file.Cloaked Then
                    Continue For
                End If

                frmProgress.Label1.Text = "Updating standard files..."
                frmProgress.Label2.Text = "Current file: " + files(0).Name
                frmProgress.Refresh()
                ' Increment for each item in the the Vault Database
                frmProgress.ProgressBar1.Maximum = strFileCnt
                frmProgress.ProgressBar1.Increment(1)

                Dim filePath As String = Path.Combine(localFolder, file.Name)
                If System.IO.File.Exists(filePath) Then
                    If file.CreateDate <> System.IO.File.GetCreationTime(filePath) Then
                        DownloadFile(file, filePath)
                    End If
                Else
                    DownloadFile(file, filePath)
                End If
            Next
        End If

        Dim subFolders As Folder() = m_serviceManager.DocumentService.GetFoldersByParentId(m_folder.Id, False)
        If subFolders IsNot Nothing Then
            For Each subFolder As Folder In subFolders
                FullMirrorVaultFolder(subFolder, Path.Combine(localFolder, subFolder.Name))
            Next
        End If
    End Sub

    Public Shared Sub DeleteAllContents(ByVal folderpath As String)

        DeleteFolder(folderpath)

    End Sub

    Public Shared Sub DeleteFile(ByVal filePath As String)

        System.IO.File.SetAttributes(filePath, FileAttributes.Normal)
        System.IO.File.Delete(filePath)

    End Sub

    Protected Shared Sub DeleteFolder(ByVal dirPath As String)

        Dim subFolderPaths As String() = Directory.GetDirectories(dirPath)
        If subFolderPaths IsNot Nothing Then
            For Each subFolderPath As String In subFolderPaths
                DeleteFolder(subFolderPath)
            Next
        End If

        Dim filePaths As String() = Directory.GetFiles(dirPath)
        If filePaths IsNot Nothing Then
            For Each filePath As String In filePaths
                DeleteFile(filePath)
            Next
        End If
        Directory.Delete(dirPath)
    End Sub

End Class

 

I hope it helps!

 

Rob

Message 12 of 13
Rob.O
in reply to: Rob.O

By the way, this thread was started before the Vault Customization forum was created, so maybe a mod can move it to a new home if necessary.
Message 13 of 13
achmidt
in reply to: Rob.O

Thank you!

Inventor Virtual Parts Addin

http://apps.exchange.autodesk.com/INVNTOR/en/Detail/Index?id=appstore.exchange.autodesk.com%3Avirtualpartsadd-in_windows32and64%3Aen

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report