Hi All,
<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
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!
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.
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
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.
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!
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.
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!
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!
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.
Hi Dull_Blades,
If you still have it, could you please post your finished code?
Thanks,
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
Thank you!