rs.OpenfileName() - not remembering last used folder in instance


#1

This is going to be a little complicated to explain.

I often run two Rhino instances on two screens, each importing files from a separate source like a USB stick and sending files to a specific laser cutter.

Key1>Rhino1>Laser1
Key2>Rhino2>Laser2

In V5, we had the problem that using either the Rhino Import command or getting a file to use in a script using rs.OpenFileName() always defaulted to the last-used directory ignoring which instance sent the command. So if I imported something in instance 2 of Rhino, going back to instance 1 and calling Import would open the directory last used by instance 2 (Key2) and not the directory last used by instance 1 (Key1).

In V6, huzzaahhh! this is fixed! Each instance keeps its own directory for Rhino native Open and Import, there is no longer “crosstalk” between instances. I think @stevebaer is responsible for that fix, many thanks!

But… the problem unfortunately persists in a scripted situation using OpenFileName(). That seems not to have been modified, the result is that OpenFileName() has a common “last-used directory” entry for all running instances. So it remains like V5. And, unfortunately, mostly all my laser file import work is done via script - as I run a lot of automated checks and fixes to files before cutting.

So, is there any way that OpenFileName() could remember which instance it’s called from and use the same directory as the previous call in that instance?

As a corrolary, is there a RhinoCommmon method for accessing the last-used folders by Open or Import? rs.WorkingFolder() does not do it - I’m not even really sure what rs.WorkingFolder() calls.

Thanks, --Mitch


(Dale Fugier) #2

Hi @Helvetosaur,

Rather than use the rhinoscriptsyntax method, you might consider just using straight .NET.

import System

def TestOpenFileDialog():
    dialog = System.Windows.Forms.OpenFileDialog()
    dialog.Filter = "All Files|*.*"
    if dialog.ShowDialog():
        return dialog.FileName
    return None

print TestOpenFileDialog()

– Dale


#3

Hi @dale,
Unfortunately, that still does not remember which instance the open file dialog came from, if I have two running Rhino instances, it always remembers the last file’s opened folder, even if that was in the other instance…

I think I’m going to attack this in another way, maybe use something like document user data to store the last used folder in the currently opened file and retrieve it… Need to think about the logic here a bit.

But, my question remains - since Rhino V6 remembers per instance what the last directory used was, for Open and Import, where is that data being stored?

Thanks, --Mitch


(Dale Fugier) #4

Hi @Helvetosaur,

OK, so perhaps this works better?

import System
import Rhino
import scriptcontext as sc

def TestOpenFileDialog(path):
    dialog = System.Windows.Forms.OpenFileDialog()
    dialog.Filter = "All Files|*.*"
    if System.IO.Directory.Exists(path):
        dialog.InitialDirectory = path
    else:
        dialog.InitialDirectory = Rhino.ApplicationSettings.FileSettings.WorkingFolder
    if dialog.ShowDialog():
        return dialog.FileName
    return None

def Test():
    path = Rhino.ApplicationSettings.FileSettings.WorkingFolder
    if (sc.sticky.has_key("InitDir")):
        path = sc.sticky["InitDir"]
    
    fname = TestOpenFileDialog(path)
    if fname:
        print fname
        path = System.IO.Path.GetDirectoryName(fname)
        if path:
            sc.sticky["InitDir"] = path

Test()

I’m sure Rhino’s file dialog stores last used folders in the settings xml file.

– Dale


#5

OK, thanks @dale

Yeah, that’s the general direction I’m going, I thought about Sticky first, but then also got worried that there might be crosstalk between instances. Later I realized that is not the case. Sticky does however survive changing documents in the same instance of Rhino. So I also thought about putting an entry into document data, which would really be specific to the open document. In this particular case leaving the entry in the document when I’m finished doesn’t matter, as these are all temporary working documents and get trashed afterward. One way or the other, that part will work OK.

However, I am now going round trying to programmatically get to my preferred start directory if a previous one doesn’t exist - i.e. the first time I open an instance of Rhino and run my import script. Ideally I would like it to get to “This PC” so I can see all the drives attached - I need to eventually choose between one of multiple removable drives plugged into the computer - but getting there directly appears to be impossible in one shot as “This PC” isn’t really a folder. So I’ll still need to jump through at least one more hoop on that.

–Mitch


(Willem Derks) #6

Hi Mitch, I’m on my phone so this is just an untested guess: what if you feed it a non-existing folder. Maybe that default to “This PC”?


#7

Hi Mitch, this works on my Win7:

fd = System.Windows.Forms.OpenFileDialog()
fd.InitialDirectory = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
fd.ShowDialog()

It may also work if you pass an *.lnk file pointing to “My Computer”. But then you have the user name hardcoded …
_
c.


#8

Wow, @clement, that looks like it should work… thanks! How did you find that? I did a bunch of websearching to try and find some info, but didn’t see anything.

I had tried with various .ink as well, but I never got it to work, maybe I did something wrong though.

Cheers, --Mitch


#9

Hi Mitch, i found it on stackoverflow, but now found something even better:

fd.InitialDirectory = "shell:MyComputerFolder"

Does this work in Win10 too ?

_
c.


#10

Geez, I looked at a number of posts there and didn’t find that. Must have used the wrong keywords…

Cool, this works too and is nicer looking, I am testing on 8.1 here, need to fire up my Win10 laptop and test later.

Edit: Yes, it does work fine in Win 10!

Thanks, --Mitch


#11

@dale @clement Just to let you know this is now working super well in my import script - thanks much!

"""Custom open file dialog.  Stores last used directory in sticky dictionary.
Remembers last used directory per Rhino instance. If previous directory does not
exist, defaults to "This PC" (My Computer) folder to select drive.
This is working pretty well in initial tests!!  26.02.18"""

import System
import Rhino
import scriptcontext as sc

def CustomOpenFileDialog(path,filter,default_ext,default_dir):
    dialog = System.Windows.Forms.OpenFileDialog()
    dialog.Filter = filter
    dialog.DefaultExt=default_ext
    
    if System.IO.Directory.Exists(path):
        dialog.InitialDirectory = path
    else:
        dialog.InitialDirectory = default_dir
    if dialog.ShowDialog():
        return dialog.FileName
    return None

def TestOpenFile():
    default_dir="shell:MyComputerFolder"
    filter="3dm Files|*.3dm|DXF Files|*.dxf|DWG Files|*.dwg||"
    default_ext="3dm"
    if (sc.sticky.has_key("LastUsedDirec")): path = sc.sticky["LastUsedDirec"]
    else: path = default_dir
    
    fullpath = CustomOpenFileDialog(path,filter,default_ext,default_dir)
    if fullpath:
        direc = System.IO.Path.GetDirectoryName(fullpath)
        filename=System.IO.Path.GetFileName(fullpath)
        if direc: sc.sticky["LastUsedDirec"] = direc
        print "Full path={}".format(fullpath)
        print "Directory={}".format(direc)
        print "Filename={}".format(filename)
    else:
        print "Canceled"
TestOpenFile()

–Mitch