Where to Store User Settings?
-
There is also a plutil command:
@unknownuser said:
NAME
plutil -- property list utilitySYNOPSIS
plutil [command_option] [other_options] file
...DESCRIPTION
plutil can be used to check the syntax of property list files, or convert
a plist file from one format to another.There is also a pl utility, although the man page says Do not use pl, use plutil instead
-
@dan rathbun said:
Basically on Mac, I'd say the AppData dir was where the user's plist file is kept, where ever that is ?? (mac guys?)
Found it, I think. I have a .plist file named:
~/Library/Preferences/com.google.sketchup7free.plist
Which I found out can be manipulated using the
defaults
command line tool.$ defaults read com.google.sketchup7free
... dumps the SU .plist.
and somthing like this to write/change a setting:
$ defaults write com.google.sketchup7free <key> <value>
-
What about %APPDATA% ? I had the surprise that in Win7, other (user) paths to have restrictions and the only reliable choice was %APPDATA%.
-
@unknownuser said:
What about %APPDATA% ? I had the surprise that in Win7, other (user) paths to have restrictions and the only reliable choice was %APPDATA%.
Yes I said that, in my code example above (for Windows,) I use %APPDATA%, from Ruby it's accessed as "#{ENV['APPDATA'}"]. All the environment vars are accesed via the ENV hash.
On any NT, there are always restrictions to other user account files, if your not an administrator. Vista and Win7 have even more restrictions. But here, we are only talking about saving the current users' settings, either (we have a choice, and may let the user make the choice,) [1] to save them along with the users' app settings, [2] OR along with where they save thier other sketchup user files, such as Watermarks, Materials, etc. We make a companion folder called "Settings" or similar.
-
@honoluludesktop said:
The api:
"The read_defaults method is used to retrieve the string associated with a value within the specified sub-section section of a .INI fileor registry (within the Software > @Last Software > SketchUp section)."
"The write_defaults method is used to set the string associated with a variable within the specified sub-section of a .plist file on the Macor the registry on Windows (within the Software > @Last Software > SketchUp section)."
Can someone tell me more about this?
Yes.. it has errors in the text, and has not been corrected since before Google bought out @Last.
The 1st paragraph should say plist not .INI
Both paragraphs should say "HKCU/Software/Google/SketchupX section (where X is the major version number.)"
The problem with putting settings in the Registry is that there is no remove_default or remove_default_key methods, and the Registry gets cluttered with ophaned keys and values. There is no way to prevent another plugin from overwriting another's values if they choose the same keyname.
If you use a settings file, it would be in it's own plugin folder (likely.)
-
@jim said:
@dan rathbun said:
Basically on Mac, I'd say the AppData dir was where the user's plist file is kept, where ever that is ?? (mac guys?)
Found it, I think. I have a .plist file named:
~/Library/Preferences/com.google.sketchup7free.plist
Which I found out can be manipulated using the
defaults
command line tool.Dont you have a file there for SU 8 also?
Since that folder is used by the defaults utility, I think we should stay out of that folder.
Perhaps if we go up 1 folder, and make a new folder called 'AppData'
"/Users/#{ENV['User']}/Library/AppData/Google/Sketchup #{ver}/#{PluginDir}"
EDIT : Changed 'Settings' to 'AppData'
-
@jim said:
mac some sub-folder in ENV['HOME']?
HOME can be, and often is changed during the session, for various reasons.
I'd say it's unreliable, instead:"/Users/#{ENV['USER']}"
ie: where
pluginDir
is a String argument to a method, a relative path, that you might want tochomp('/')
:<span class="syntaxdefault"> ver </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">version</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">split</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'.'</span><span class="syntaxkeyword">)[</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">]<br /></span><span class="syntaxdefault"> if RUBY_PLATFORM</span><span class="syntaxkeyword">.include?(</span><span class="syntaxstring">'darwin'</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxcomment"># MacOSX<br /></span><span class="syntaxdefault"> appData </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">"/Users/#{ENV['USER']}"</span><span class="syntaxkeyword"><<</span><span class="syntaxstring">'/Library/AppData'</span><span class="syntaxdefault"> <br /> suVer </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">'Google/Sketchup '</span><span class="syntaxkeyword"><<</span><span class="syntaxstring">"#{ver}"<br /></span><span class="syntaxdefault"> suProg </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">'Sketchup'</span><span class="syntaxdefault"> </span><span class="syntaxcomment"># or 'Layout' or 'Style_Builder'<br /></span><span class="syntaxdefault"> return File</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">join</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">appData</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">suVer</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">suProg</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">pluginDir</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> else </span><span class="syntaxcomment"># Win32 RUBY_PLATFORM includes 'mswin' || 'mingw'<br /></span><span class="syntaxdefault"> appData </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">"#{ENV['APPDATA']}"<br /></span><span class="syntaxdefault"> suVer </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">'Google/Sketchup '</span><span class="syntaxkeyword"><<</span><span class="syntaxstring">"#{ver}"<br /></span><span class="syntaxdefault"> suProg </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">'Sketchup'</span><span class="syntaxdefault"> </span><span class="syntaxcomment"># or 'Layout' or 'StyleBuilder'<br /></span><span class="syntaxdefault"> return File</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">join</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">appData</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">suVer</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">suProg</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">pluginDir</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> end<br /></span>
*note difference in Style Builder dir names between platforms.
Basically on Mac, I'd say the AppData dir was where the user's plist file is kept, where ever that is ?? (mac guys?)
On Windows the path returned (minus
pluginDir
,) is where the session.dat file is kept.
EDIT : Changed Mac Appdata location
-
Another alternative, is to create USER subfolders under each plugin subfolder.
The danger with this option, is when people are cleaning up, they might delete the user folders, and loose all their settings for that plugin.
-
Where on the Mac, are the USER folders for Watermarks, Materials, Components, Styles, etc. (as the out-of-box default)??
-
@dan rathbun said:
Dont you have a file there for SU 8 also?
SketchUp 8 won't run on my G4 Cube's RISC CPU (PowerPC).
Coming from a Linux background, user settings are typically stored in a ~/.#{AppName} sub-folder.
@dan rathbun said:
HOME can be, and often is changed during the session, for various reasons.
Not sure when this happens? Is it really that unreliable?
I agree that APPDATA is the appropriate place to store user settings on Windows. But I read somewhere (MSDN blog) that using environmental variable and the Registry are not a reliable way to get them; and there are Win32 function calls to get the actual location. Fortunately, the win32-util include win32-dir which provides nice constants for Window's special folders using these win32 calls.
-
@jim said:
@dan rathbun said:
HOME can be, and often is changed during the session, for various reasons.
Not sure when this happens? Is it really that unreliable?
I agree that APPDATA is the appropriate place to store user settings on Windows. But I read somewhere (MSDN blog) that using environmental variable and the Registry are not a reliable way to get them;.
Well .. yes, the Environment vars can be changed within each process, at whim. Which is what makes them unreliable (including HOME and ~.)
@jim said:
... and there are Win32 function calls to get the actual location. Fortunately, the win32-util include win32-dir which provides nice constants for Window's special folders using these win32 calls.
Yea I have a copy of that (just looked at it this morning,) ... if those constants return the "system" settings, rather than the processes "copy" (that might have been changed,) then they should be more reliable.
Berger's win32-api needs to be bundled (pre-compiled) for BOTH mswin and mingw compiled Ruby. Then put in the Plugins forum (allowing users to choose which they want.)
ThomThom would then use an
include('Win32')
statement if he wants to bring it into his TT_Lib2 namespace (but he really then would not need to.) He'd only need require the load file.
The version (and file locations,) of win32-api should not be tied to the TT_lib2 files, their versions or their file locations. -
I was thinking I'd just add the path to the
api.so
I bundle with TT_Lib2.TT_Lib2 currently (unreleased v2.5) do:
require 'win32/api'
. It does not care which version it is. That way, if it's not laoded by some other plugin it'd load it from the bundled version. (unless there is another version that comes first in the load path array.)I very much doubt any user will care which version is used. They just want stuff to work.
-
Mac question...
is the path:
/Library/Application Support/Google SketchUp *x*/SketchUp/
actually under the HOME path?ie is it really?
/Users/#{ENV['USER']}/Library/Application Support/Google SketchUp *x*/SketchUp/
-
Of course you could simply use the
Sketchup.read_default()
&Sketchup.write_default()
methods which use the PC registry OR the MAC plist ?
To make a user specific section entry you can use...
user=ENV['USERNAME'] if not user=ENV['USER']
which traps the difference in MAC/PC 'user' ID...
Then read/write a 'section' called perhaps
user_section=user+"_JF::DrawHelix"
each named after a specific tool - here I've used Jim's rehash of 'DrawHelix'...
To read a user's 'variable' for that tool using...
Sketchup.read_default(user_section, "values", defaults)
'defaults' could also be
nil
To write/rewrite a user's 'variable' to a new 'value' for that tool...
current=Sketchup.write_default(user_section, "values", values)
You do have to be careful about the type of data you try store...
BUT Jim's rehash of 'DrawHelix' already usesreg_key = "JF::DrawHelix"
- so we'd simply setuser==ENV['USERNAME'] if not user=ENV['USER']
[as above] and then usereg_key = user+"_JF::DrawHelix"
... then usev = Sketchup.read_default(reg_key, "values")
and thenvalues = eval(v)
etc to extract the individual 'array' of values needed for that tools settings, AND then later save them on close with ...
Sketchup.write_default(reg_key, "values", results.inspect)
I think that the Sketchup PC 'registry keys' are saved on an individual 'current-user' basis anyway [HKEY_CURRENT_USER\Software\Google\SketchUp8\JF::DrawHelix] and therefore you wouldn't really need to use the 'user' prefix [although it does no harm to add it]... BUT I'm not sure about the MAC's equivalent 'plist' entries - if that's a global file then the 'user' prefix will serve to separate out each user's entry appropriately...
I really can't see why you need to set up your own user's 'AppData' file/folders for this ?
-
Just wondering if it is wise to use the "APPDATA/Google/SketchUp X" sub-folder name because it is what is actually used by Google SketchUp. Why wouldn't the settings for my plugin go right in (something like) "APPDATA/Jim Foltz/JF Plugins/My Plugin Name/"
-
@jim said:
Just wondering if it is wise to use the "APPDATA/Google/SketchUp X" sub-folder name because it is what is actually used by Google SketchUp.
(1) It's actually
%(#8000BF)[%APPDATA%]
in command scripts, andENV['APPDATA']
in Ruby.(2) This location is meant to be hidden from the user. But an Administrator can make the dir visible easily on XP, but not so easily on Win 6+. One advantage is that Windows Migration wizard can copy files from APPDATA folders when upgrading to newer OS versions, or to another computer. Note that the
%(#8000BF)[%APPDATA%]
path is the "roaming" profile (which is OK, especially for a network setup, where the user may logon to any one of many workstations. This is in contrast to the%(#8000BF)[%USERPROFILE%/Local Settings/Application Data]
path, which is specific to a particular computer or workstation. XP does not have a environment var that points at this, but Win6+ does:%(#8000BF)[%LOCALAPPDATA%]
)
IF you wish the user to easily see any of these settings, you'd need to make a "log viewer" webdialog, or a GUI dialog.@jim said:
Why wouldn't the settings for my plugin go right in (something like) "APPDATA/Jim Foltz/JF Plugins/My Plugin Name/"
It could, ie, something like:
# within your plugin module namespace; if RUBY_PLATFORM =~ /(darwin)/ APPDATA = File.join('Users',ENV['USER'],'Library/Application Support') # or; APPDATA = File.join('~','Library/Application Support') # or; APPDATA = File.join(ENV['HOME'],'Library/Application Support') else # Windows APPDATA = File.join( ENV['APPDATA'],'Google' ) end SUFFIX = "Google SketchUp #{Sketchup.version.to_i.to_s}/SketchUp/Plugins" APPDATA = File.join(APPDATA,SUFFIX) Dir.mkdir(APPDATA) unless Kernel.test(?d,APPDATA) PLUGDIR = 'SomeString' SUBPATH = 'Jim Foltz/JF Plugins' @@datapath = File.join(APPDATA,SUBPATH,PLUGDIR) Dir.mkdir(@@datapath) unless Kernel.test(?d,@@datapath)
-
OH.. sorry Jim... I missed the real question in your query.
You want to use YOUR OWN company name folder "Jim Foltz" instead of the "Google" dir...
.. and then whatever subfolders you wish to organize below that.Well YES, IMHO... no problem there. Keep it separate and protected from inadvertant cleansing (such as when someone tries to cleanup their system for a "clean" reinstall of Sketchup.)
-
Here's an article with some more specific info for working with several recent versions of Windows.
What’s the Recommended Location for Application Files?
The article only confirms what has already been said here: %APPDATA% is the correct folder (or better to use your own sub-folder under %APPDATA%.)
-
But roaming or local?
-
Why not always roaming? Is there a specific case for local?
I might use local if the file(s) were for a license key tied to a specific machine. But otherwise, I can't think of a reason not to use roaming.
Advertisement