I’m trying to do something immediately after Rhino documents are saved. I figured that RhinoDoc.EndSaveDocument was the event to subscribe to, but it’s not working. I created a plugin with only this additional code (no commands):
My expectation was that a copy of any saved Rhino document would appear as C:\output.3dm. Instead, creating a new document, adding a box or something, and then attempting to save as “C:\test.3dm” yields this output:
Command: _Save
Could not copy file post-saving: Could not find file ‘C:\test.3dm’.
File successfully written as C:\test.3dm
And sure enough, C:\test.3dm exists, but C:\output.3dm doesn’t. RhinoDoc.EndSaveDocument isn’t documented, but given the existence of RhinoDoc.BeginSaveDocument, I assumed it did what I wanted. However, it appears to fire before the document is saved, not after. Is there any way to do what I want?
Protected Overrides Function OnLoad(ByRef errorMessage As String) As Rhino.PlugIns.LoadReturnCode
AddHandler Rhino.RhinoDoc.EndSaveDocument, AddressOf SaveDocument
Return Rhino.PlugIns.LoadReturnCode.Success
End Function
Private Function SaveDocument(ByVal sender As Object, ByVal e As Rhino.DocumentSaveEventArgs)
'Do what you want to do
'For this to work first use a command thats in your plugin. Don't know how to load it on rhinoopening
MsgBox("hi")
Return Nothing
End Function
This is it for vb.net.
If you first use one of your own command to addhanddler it will work
As you can see in my example code, I’m able to subscribe to EndSaveDocument, and it’s firing. The problem is that it’s firing before the document is saved, and I need to do something after the document is saved.
I see, sorry. Missed that one Thought this was the problem.
Maybe have a background worker?
First when the file is opened have a variable that has current time.
Have another variable that keeps changing and checking if the save time is changed.
Compare these 2 and if they dont agree. Set your action to work.
I have tried to work around this with a filesystem watcher, and it’s sort of functional, but it definitely doesn’t work when the document save has been triggered by a user as a result of Rhino being closed; at some point, my filesystem watcher handler is going to be interrupted by the fact that the program has been unloaded. Or sometimes it doesn’t, and I have a ghost Rhino process hanging around, and some other cleanup code never gets run. I just don’t see any way of avoiding these unmanageable race conditions (via checking the filesystem directly) without a proper event firing after a document save. Is there any chance that this will get changed in a future RhinoCommon?
Maybe the RhinoApp.Closing event can help you out for the case of save-on-close that you describe above. Hopefully that event gets fired after the file has been saved…
I have to say though, it is not expected behaviour that EndSaveDocument is triggered before the file is written. With you, I hope that it gets changed in the future.
This issue was recently closed on Github (https://github.com/mcneel/rhinocommon/issues/168) as unreproducable by @dale, but it’s still affecting me (x64, SR11, Windows 8), and since he told me to start a thread here to discuss it, I’m just bumping my (super) old one. (I’ve been using the workaround @stevebaer suggested this past year.)
1.) When you detect a EndSaveDocument event, set a flag indicating such.
2.) When you detect an Idle event - RhinoApp.Idle - check your flag (and check for the file in this case).
Ok, using RhinoApp.Idle seems to be doing the trick, but I am still curious about RhinoDoc.EndSaveDocument’s behavior. If it’s not firing before the save is complete, then why doesn’t the file exist on disk during the handler’s execution?
An update for anyone also trying to use this solution: You need to also check the flag in RhinoApp.Closing, because if a document is closed as part of Rhino closing, Idle will never fire again.