Save as copy

Hi,
I’m trying to save my doc as a copy with RhinoCommon for rhino6 (It’s meant to be a background backup).

At the moment I’m doing this:

Dim BackupName As String = CombinePath(AutoSaveDirectory, Date.Now.ToString("yy-MM-dd-HH-mm-ss-") & doc.Name)
        Dim Opt As New FileIO.FileWriteOptions With {
                    .WriteUserData = True,
                    .IncludePreviewImage = False,
                    .SuppressDialogBoxes = True
                    }
         doc.WriteFile(BackupName, Opt)

But it changes doc.Path to the new name, which obviously is wrong for a backup.
Any idea?

Hi @Matthieu_from_NAVINN,

We have a solution coming in SR5.

https://mcneel.myjetbrains.com/youtrack/issue/RH-45380

– Dale

Thanks Dale. Any general idea of when SR5 would be released?

Hi @Matthieu_from_NAVINN,

Probably around the first of June. I’m hoping you’ll see an SR5 release candidate next week.

– Dale

1 Like

Hi @Dale, i tried the new SR5 function doc.Write3dmFile(path,FileWriteOption) and it raise an unmanaged exception:
System.AccessViolationException : 'Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée.'

With the same path (I target a directory on desktop) I did not have this issue with doc.WriteFile(path,FileWriteOption)

And this exception is not caught by a try-catch loop, so it makes the program crash.

Here is my full code:

    'Save code
    If doc.Name = "" Then Exit Sub
    Dim BackupPath As String = My.Computer.FileSystem.CombinePath(AutoSaveDirectory, Date.Now.ToString("yy-MM-dd-HH-mm-ss-") & doc.Name)
    RhinoApp.WriteLine("MSP: AutoSaving project to ""{0}"".", AutoSaveDirectory)
    Dim Opt As New FileIO.FileWriteOptions With {
    .WriteUserData = True,
    .IncludePreviewImage = False,
    .SuppressDialogBoxes = True
    }
    'TODO: check rhino version (need v6.5)
    BackupPath = BackupPath.Replace("\", "\\")
    Try
        If doc.Write3dmFile(BackupPath, Opt) = True Then
            RhinoApp.WriteLine("Next Save in {0} seconds", AutoSaveInterval)
        Else
            RhinoApp.WriteLine("AutoSave failed and will be disabled.")
            Me.Settings.SetBool("MSP_Setting_AutoSaveEnabled", False)
        End If
    Catch ex As Exception
        MsgBox(ex.Message, MsgBoxStyle.Exclamation, "MSP Autosave error")
    End Try

Hi @Matthieu_from_NAVINN,

This seems to work here:

Protected Overrides Function RunCommand(ByVal doc As RhinoDoc, ByVal mode As RunMode) As Result

  If String.IsNullOrEmpty(doc.Path) Then
    Return Result.Nothing
  End If

  Dim path = IO.Path.GetDirectoryName(doc.Path)
  Dim fname = IO.Path.Combine(path, EnglishName() + ".3dm")

  Dim fwo As New FileIO.FileWriteOptions With 
    {
    .WriteUserData = True,
    .IncludePreviewImage = False,
    .SuppressDialogBoxes = True
    }

  Try
    If doc.Write3dmFile(fname, fwo) = True Then
      RhinoApp.WriteLine("{0} saved successfully.", fname)
    Else
      RhinoApp.WriteLine("{0} save failed.", fname)
    End If
  Catch ex As Exception
    RhinoApp.WriteLine(ex.Message)
  End Try

  Return Result.Success

End Function

What am I missing?

– Dale

Hi @Dale,
I did a few more tests, it seems the crash occurs because my save code is in a .net timer event. (As a manual command your code works fine).

If I use exactly your code from the timer event, it crashes with a protected memory error, while if I just change doc.Write3dmFile to doc.WriteFile it works. Could it be caused by a memory / Hard drive access different between the two methods?

Hi @Matthieu_from_NAVINN,

I would suggest calling either Write3dmFile or WriteFile on Rhino’s main thread. In an RhinoApp.OnIdle event handler is a good place.

– Dale

Thanks @dale, it works from RhinoApp.OnIdle !