Forum Moderators: Lobo3433, Staff Forum Coordinators: Anim8dtoon
Poser Python Scripting F.A.Q (Last Updated: 2026 Apr 22 10:09 am)
Here are some of the details, bit by bit.
This query is related to my old Smart+ script
That script used to run fine on my system until I upgraded to Windows 10 - but it **wasn't **Windows 10 that caused the problem.
It was the fact that I'd always had Poser installed on a separate drive from Windows, i.e. a non C: drive, before.
But when I upgraded to Windows 10 I had to uninstall all my software first, and when I reinstalled it I put everything on the same drive as Windows.
So with my previous setup I didn't have problem - the script could write my :Runtime:Python:poserScripts:3DCheapskate:SmartPlus:TempPose.pz2 file to poser.AppLocation()without any problem.
However, once Poser was installed on the C drive the dreaded UAC prevented the script from writing the file - insufficient privelege/permissions/whatever.
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
The fix for that temporary pose file is simple - don't use poser.AppLocation(), use poser.TempLocation() instead
I've already posted about that here.
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
However, that TempPose.pz2 file is not what I'm wondering about.
Obviously, since I already have a solution.
What I am wondering about is this:
Two of my scripts, the WorldBall and the Smart+ ones, use datafiles to store various stuff.
Up until now the scripts have only needed to read those datafiles, but since I've already looked at the Smart+ code and found the fix for the temporary pose file, I'm thinking about finishing something I put to one side 4 years ago - helper scripts for setting up new Smart+props (4 years ago I did an interim release... and left it at that)
The Smart+ datafiles is under poser.AppLocation() at :Runtime:Python:poserScripts:3DCheapskate:SmartPlus:SmartPlusData.txt
I could of course probably move that to poser.TempLocation(), but something tells me that's not the way to do it.
I know that EZSkin2 keeps a list of all the figures that the user has set up by importing from its confguration file and/or manually adding from EZSkin's editor tab. But I can't work out where that information is actually stored.
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
While poser.TempLocation() is eminently suitable for my temporary pose file (which was a workaround for an olde Poser bug, mentioned at the bottom of this post), it is totally unsuitable for the data files. I'm (and I assume others are too) in the habit of clearing crap frommy system every now and then, and 'temp' folders and suchlike usually go first.
So I'm really wondering two things:
Where is the best place to put my non-temporary datafiles ? (Remember that I have to be able to pick up the path from a PoserPython call, so that seems torestrict it to poser.AppLocation())
How did SnarlyGribbley do it for the configuration data in EZSkin2 ?
(N.B. The thread title "How do you avoid UAC problems writing to poser.AppLocation() subfolders ?" was based on the assumption that this is where everybody who writes scripts requiring datafiles puts them)
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
Thanks adp001/ironsoul, those all sound reasonable.
Calling poser.TempLocation() fromPP2014 on my Windows 10 system returns 'C:Users:USERNAME:AppData:Local:TempPoser Pro:10'
...which is a few levels down from %APPDATA% (I guess 'C:Users:USERNAME:AppData)
...which is itself I guess one level below %USERPROFILE, 'C:Users:USERNAME
And I've now found the EZSkin files. They're in the same area, but under 'Roaming' not 'Local',e.g. C:Users:USERNAME:AppData:Roaming:Poser Pro:10
SoI guess that the original query "How do you avoid UAC problems writing to poser.AppLocation() subfolders ?" is best answered by "Don't try to write there !"
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
3dcheapskate posted at 2:22PM Fri, 24 April 2020 - #4387153
SoI guess that the original query "How do you avoid UAC problems writing to poser.AppLocation() subfolders ?" is best answered by "Don't try to write there !"
Right. AppLocation is protected for a reason. No other software should be able to modify (infect?) installed apps.
My original code for writing a temporary pose file in the wrong place was this...
sTmp = os.path.join('Runtime','Libraries','Pose','3DCheapskate','SmartPlus','TempPose.pz2')
poserpath=os.path.split(poser.AppLocation())
fileaddr = os.path.join(poserpath[0],sTmp)
pose=open(fileaddr,"w")
...which as I've said is easy to fix using poser.TempLocation() instead of poser.AppLocation()...
sTmp = poser.TempLocation() # Returns something of the form C:UsersAppDataLocalTempPoser Pro10
fileaddr = os.path.join(sTmp,'TempPose.pz2')
pose=open(fileaddr,"w")
...and that should work fine on both Windows and MacOS.
Regarding the datafiles, which is what I'm now looking at. Ploughing through my code I've realized that my datafiles weren't necessarily in the main Poser runtime, i.e. the one under poser.AppLocation() - although they might be.
They can be in any mapped Poser runtime. So I originally used script like this to find them (not forgetting to check for failure to find the file and finding multiple files)...
try:
aLibs = poser.Libraries()
for lib in aLibs:
filetocheck = os.path.join(lib,'Runtime','Python','poserScripts','3DCheapskate','SmartPlus','SmartPlusData.txt')
if os.path.exists(filetocheck):
...
...which I could fix for PP2014 Windows like this...
sTmp = os.environ['APPDATA']
fileaddr = os.path.join(sTmp,'Roaming','Poser Pro','10','SmartPlusData.txt')
if os.path.exists(fileaddr):
...
...but like I said,that would be specific to PP2014 (or Poser 10) on Windows.
Suggestions ?
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
Might as well post the relevant bits of the script as it stands,so you can see what I was doing.
For the Smart+ script this is how I find the datafile:
...
# Locate the smart plus datafile
sDatafile = os.path.join('Runtime','Python','poserScripts','3DCheapskate','SmartPlus','SmartPlusData.txt')
smartdatafile = locateDataFile(sDatafile
...
...and this is the locateDataFile() function, which checks the Poser applocation first, and then each mapped runtime in turn
# sFilename is the path in OS-specific format starting at Runtime
def locateDataFile(sFilename):
locatedfile = ""
filetocheck = ""
global sTempErrLog
# Check for the data file in the application location (Poser 6 PoserPython doesn't provide a method to scan mapped runtimes)
poserpath=os.path.split(poser.AppLocation())
filetocheck = os.path.join(poserpath[0],sFilename)
if os.path.exists(filetocheck):
locatedfile = filetocheck
else:
# If it's not found then log it so we can inform user later if necessary
sTempErrLog = sTempErrLog+"nFILE NOT FOUND: "+filetocheck
# Check for the data file in the mapped libraries (if already found we still check for multiple copies, but use the first one we found)
try:
aLibs = poser.Libraries()
for lib in aLibs:
filetocheck = os.path.join(lib,'Runtime','Python','poserScripts','3DCheapskate','SmartPlus','SmartPlusData.txt')
if os.path.exists(filetocheck):
if locatedfile == "":
locatedfile = filetocheck
else:
poser.DialogSimple.MessageBox("Multiple 'SmartPlusData.txt' files found")
else:
# If it's not found then log it so we can inform user later if necessary
sTempErrLog = sTempErrLog+"nFILE NOT FOUND: "+filetocheck
except: # Poser 6 will always cause an exception because the Libraries() function doesn't exist
pass
return locatedfile
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
...and here the equivalent bit for the WorldBall script:
##################################
# Functions: readWorldBallData()
##################################
# Set up the global envlist[] using data from WorldBallData.txt
def readWorldBallData():
envdatafile = ""
filetocheck = ""
# Check for the data file in the application location
poserpath=os.path.split(poser.AppLocation())
filetocheck = os.path.join(poserpath[0],'Runtime','Python','poserScripts','3DCheapskate','WorldBall','WorldBallData.txt')
if os.path.exists(filetocheck):
envdatafile = filetocheck
# Check for the data file in the mapped libraries (if already found we still check for multiple copies)
try:
aLibs = poser.Libraries()
for lib in aLibs:
filetocheck = os.path.join(lib,'Runtime','Python','poserScripts','3DCheapskate','WorldBall','WorldBallData.txt')
if os.path.exists(filetocheck):
if envdatafile == "":
envdatafile = filetocheck
else:
poser.DialogSimple.MessageBox("Multiple 'WorldBallData.txt' files found")
except:
pass
# Return if we didn't find the file, open it and read all the data in if we did
if envdatafile == "" or not os.path.exists(envdatafile):
return False
else:
f = open(envdatafile)
...
...which I think is basically the same thing.
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
It's well known since MS invented the registry and left older ini-file concept that you never ever install non-Windows-stuff on C: drive under the ruling of Windows. Especially no application software, only exeption may be system software like printer drivers or such stuff. Best possibility divers drives or for one drive partitioning it ... best C: only system, D: for application and E: for the data as such. Even a very good idea for backup handling C: and D: are only urgent if changng something but E: need a fix turnus. OK, since in software development a permanently renovation of their "green" stuff (banana ware) is up-to-date even C: and D: needs more often a backup but not day by day.
If multi drives or partitioning is not suitable the second best idea is to have on C: a directory besides the Windows stuff like "AllMySoftware" and install all application stuff in that. Such a directory is outside of Windows control and therefor no UAC trouble. B.t.w. running stuff outside of the Windows directories is also bringing a win-question if you want to do so but isn't disturbing file writing in that locations. And the win capabilities to save against maleware writing are even rather unsave. So no need to cope with the MS restrictions to much.
Have had for years to maintain users pc's which was setup by dealers according to the MS guidelines and its only a question of time that those pc's are gigantic rubbish graveyards and the user have no space and also not finding anything back again (secretary around 6 month, normal office clerks 1 to 1,5 years, chiefs up to 5-7 years
). Round about 2-5 hours work for the maintance guys and dolls to clean up one pc depending on how much sensefull stuff is hidden between all the temp and such rubbish ... 
Previously I had all my apps on a separate drive, which is why I never noticed the UAC problem.
But most people (including me now) have all their apps, Poser included, installed to the standard Windows (or MacOS) location.
So I need to fix my scripts need to avoid this UAC* problem. Regardless of what I personally think.
*I assume that MacOS has a similar permissions thing to Windows UAC.
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
P.S. I posted the code snippets of how I'm currently finding the Smart+ andWorldball datafiles mainly for my own reference, so that I don't have to find my scripts and plough through them every time I want to check what I was doing before.
Both of those work without any problem on a Windows system, even with Poser installed to the Windows-approved location on the C drive, and even with with the datafiles under poser.AppLocation(). Because I'm only reading the files at present.
The problem will come when I try to write the files from my script.
Regarding the locations proposed by adp001 and ironsoul, and taking into account the location that SnarlyGribbley's EZSkin and EZMat use for saving their datafiles, I think that one of the following locations is probably the best:
C:Users:USERNAME:AppData:Local:Poser:MYDATAFILE.TXT
C:Users:USERNAME:AppData:Roaming:Poser:MYDATAFILE.TXT
I'm not sure of the difference between the Local and Roaming folders, so can anybody advise which would be better,and why ?
And I don't think it's necessary for me to use different locations for different Poser versions.The exact same scripts currently work in Poser 6,9 and PP2014*, and I want to avoid unnecessary duplication of the datafile.
I may also want to add a '3DCheapskate' subfolder. I've always found it useful to be able to simply do a Windows Explorer search using that to find where I've put all my files !
Any thoughts, comments, suggestions ?
*I no longer have Poser 6 or 9 installed, so I obviously can't say that with any certainty for any changes I make
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
I'm not sure. I'm using PP2014 (now running from the Windows-approved C drive location), but my scripts are all in an external runtime on a separate drive.
But that's a good point. And maybe the UAC problem I was getting was precisely because I was running the script from a location outside the Poser installation ?
I think I need to run the old version of my script, the one prior to the "use poser.TempLocation() instead of poser.AppLocation()" fix, from within Poser's Python directory just to make sure.
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
Just tried that simple test, running my script from C:Program Files:Smith Micro:Poser Pro 2014:Runtime:Python:poserScripts:3DCheapskate:SmartPlus:
When it writes the temporary pose file under poser.AppLocation() it works fine.
So the whole UAC problem came about because, with my specific setup, I was running the script from an external runtime
Anyway, mainly for my own reference, here's the full function in its original form. No need to use poser.TempLocation() ... unless you run the script from an external runtime.
def parentprop(ac,par):
scn = poser.Scene()
if ac.IsProp():
scn.SelectActor(ac)
propin=ac.InternalName()
propen=ac.Name()
parin=par.InternalName()
paren=par.Name()
sTmp = os.path.join('Runtime','Libraries','Pose','3DCheapskate','SmartPlus','TempPose.pz2')
poserpath=os.path.split(poser.AppLocation())
fileaddr = os.path.join(poserpath[0],sTmp)
pose=open(fileaddr,"w")
pose.write("{ntactor $CURRENTnt{nttsmartparent "+parin+"nt}n}n")
pose.close()
scn.LoadLibraryPose(fileaddr)
else:
print "FAILED:", propin," is not a prop"
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
What's wrong with using poser.PrefsLocation() and creating subfolders in that to store your retained script preferences/data files?
On macOS, at least, that's located within the User account hierarchy: Users:[USERNAME]:Library:Application Support:Poser Pro:11. To keep it associated with Poser but not clutter up Poser's own Preferences folder, you could locate it up one directory level.
Verbosity: Profusely promulgating Graham's number epics of complete and utter verbiage by the metric monkey barrel.
Okay, back to square one.
If, and only if, (a) Poser was installed in the Windows-recommended location under C:Program Files, and (b) my script is run from an external runtime not on the C: drive, then my Smart+ script crashes when it tries to (over)write.
Using _poser.TempLocation() _instead of poser.AppLocation() resolves that, and _shouldn't _cause any new problems. Except that poser.TempLocation() is not available in Poser 6 - it was introduced in either 7, 8,or 9.
Considering just the Smart+ script, I have a single datafile, SmartPlusData.txt, used by both Poser and DAZ Studio.
If the user has multiple versions of Poser I want them all to use the same datafile.
If the user has both Poser and DAZ Studio I want them both to use the same datafile.
The solution I adopted 4 years ago was to put the datafile in any single Poser runtime (I chose an external Poser 6 runtime) and to ensure that runtime was mapped from every Poser version and every DAZ Studio version that I had installed.
Since the scripts have only ever had to read this datafile I've had no problem so far.
However, now that I want to write to this datafile (and I want to be able to write to it from** any** of the Poser or DAZ Studio versions that I have installed) I can see a similar UAC problem coming.
So I'm trying to decide on the best location for this datafile. Windows and MacOS.
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
For your script it would be the best to have a folder beneath USERPROFILE. Because it is not Poser and not DAZ specific. Nor does the config depend on a special version. And even if, a folder structure is possible:
[USERPROFILE]/[SCRIPTNAME]/[config|data]/[version]/*
Don't overcomplicate basically simple things :)
I'm aware that Windows users are blessed with neverending backward compatibility, but what are the returns from continuing to support Poser 6 or 7? Will you get sales (I'm not assuming anything, here) from those users not able or willing to move with the times. Mac users who have managed to migrate from Motorola PowerPC platforms running System 9 or earlier to OS X, now just called macOS have long had to wave goodbye to the ability to run anything earlier that Poser 2010.
I have quite a few scripts with a page of code trying to keep track of where preferences live from Poser 6 upwards. Since the implementation of PoserPrefs() method, that's all redundant unless you really need to support users of such old versions of Poser. What do you get out of that? Are there problems with your code that need to be fixed for users on those platforms or are you implementing new features? Users of old Poser versions may not be able to run them on Windows 10 (I do not know whether this is true or not), so they would never encounter UAC issues.
Write new code for new platforms, and let the old ones run the old software. If it works now, it won't need an update until they upgrade their OS/Poser version, in which case they can make use of new features which streamline your codebase. Draw a line in the sand.
[End devil's advocate mode] ;-)
Verbosity: Profusely promulgating Graham's number epics of complete and utter verbiage by the metric monkey barrel.
3dcheapskate posted at 12:43PM Sat, 25 April 2020 - #4387265
But that's a good point. And maybe the UAC problem I was getting was precisely because I was running the script from a location outside the Poser installation ?
A running script inside Poser looks like Poser is doing something (same process, because Poser-Python is an integral component of Poser). Means: your script is able to write to all places Poser can.
as an0malaus said PrefsLocation is the best place to store config data
config = os.path.join(poser.PrefsLocation(), "3DCheapskate", "scriptname" )
if not os.path.exists( config )
os.makedirs( config )
config = os.path.join( config, scriptname.data )
poser.TempLocation and poser.PrefsLocation are not subject to the UAC -
as adp pointed out "A running script inside Poser looks like Poser is doing something (same process, because Poser-Python is an integral component of Poser). Means: your script is able to write to all places Poser can."
however to check if UAC is a potential problem ( for writing anything to poser.Applocation ) # not usually a good idea to store config data here
def is_running_as_admin():
'''
Checks if the script is running with administrative privileges.
Returns True if is running as admin, False otherwise.
'''
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
from sys import platform
if platform == "win32":
import ctypes
if is_running_as_admin():
appLoc = os.path.dirname( poser.Applocation() ) # Poser Main Directory
# --- create alternative storage folder ---
else:
drive = "c:/"
appLoc = os.path.join(drive,"Temp","Runtime","Libraries","pose" ) # build your path here
if not os.path.exists( appLoc ): # check folder exists
os.makedirs( appLoc ) # build folder if it does not exist
Locked Out
Thanks everybody, lots of good feedback there.
Regarding the temporary pose file TempPose.pz2, poser.TempLocation() is almost certainly the best place for that. The file is created-and-written/overwritten by the script and then immediately loaded by the script (it's a workaround for stuff that PoserPython doesn't do properly, mentioned at the bottom of this post), so the fact that each version of Poser uses one from a different location doesn't matter.
However, the datafile is another matter. I think I mentioned that, not only do I want all versions of Poser that are installed on the system to use the same single datafile, but all versions of DAZ Studio too. poser.PrefsLocation() is therefore not an option since DAZ Studio has no way to access that location. So it really has to be one of the os.environ[WHATEVER] locations.
And since Poser and DAZ Studio both run on Windows and Mac, os.environ[WHATEVER] has to be one that exists on both. Does the environment variable USERPROFILE exist on a Mac ?
Also, looking at the existing subfolders in os.environ[USERPROFILE] on my system (i.e. C:/Users/[username]/) I don't think a '3DCheapskate' or 'SmartPlus' folder at that level (alongside the Windows standard Desktop, Downloads, Documents, etc folders) would be appropriate, although SmithMicro DLM and GIMP have created folders there (and that has always irritated me). So I'm leaning towards perhaps C:/Users/[username]/AppData/Roaming/3DCheapskate-Poser-DAZ-SmartPlus. 'Roaming' rather than 'Local' because there are already 'DAZ 3D', 'Poser', and 'Poser Pro' folders in the latter, but none in the former. And the rather long folder name '3DCheapskate-Poser-DAZ-SmartPlus' because I've always hated folder names that leave you wondering who put them there and what they're for.
So that shouldbe okay for Windows. But what about a Mac ? What's the equivalent to 'C:/Users/[username]/AppData/Roaming' there, where both Poser and DAZ Studio put user files ?
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
Erratum (previous post - edit timeout - GRRR): I got my 'former' and 'latter' crossed !
There are 'DAZ 3D', 'Poser', and 'Poser Pro' folders in 'Roaming, but not in 'Local'
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
I believe the purpose of the %APPDATA% location in Windows is a safe place for applications to store data, the folder is normally hidden in explorer so less likely a user will delete when spring cleaning their c: drive. For Mac Users there appears to be a similar folder called "~/Library" - I'd recommend you check this with a Mac user rather thsn take my word for it.
Assuming this is correct you could do the following
if os is windows
myFolder = os.environ['APPDATA'] + '/ 3DCheapskate-Poser-DAZ-SmartPlus'
else if os is macos.
myFolder = '~/Library/3DCheapskate-Poser-DAZ-SmartPlus'
Another suggestion is to create a file called README.txt in the 3DCheapskate-Poser-DAZ-SmartPlus directory that contained a brief explanation what the directory is used for.
Thanks. Google searches for "mac environment variables", "mac appdata", etc yielded a variety of locations of which ~Library or ~/Library was one (or two). So I'm hoping that a Mac user/scripter willenligthen me
Since there's also aDAZ Script element to this I've asked over on the DAZ scripting forum - Accessing environment variables from DAZ Script,& Mac equivalent of %APPDATA% ?
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
Also asked the specific question on this forum - Environment variables - Mac equivalent of APPDATA
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
I've just started trying to use the new %APPDATA% based location in Windows 10.
First minor surprise:
...
sTmp = os.environ['APPDATA']
print "%APPDATA% is: ", sTmp
...
...prints...
%APPDATA% is: C:UsersdAppDataRoaming
So the "Roaming" bit is already included in %APPDATA%.
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
Note: Using os.getenv('APPDATA') also works. Somebody used that in one of the replies here or in another thread.
So which is better to use, os.environ[] or os.getenv() ?
And why ?
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
And another thought:
...
sTmp = os.getenv('APPDATA')
print "%APPDATA% is: ", sTmp
fileaddr = os.path.join(sTmp,'3DCheapskate-Poser-DAZ-SmartPlus','SmartPlusData.txt')
if os.path.exists(fileaddr):
print "DATAFILE LOCATED: ", fileaddr
locatedfile = fileaddr
else:
...
gives me...
%APPDATA% is: C:UsersdAppDataRoaming
DATAFILE NOT FOUND: C:UsersdAppDataRoaming3DCheapskate-Poser-DAZ-SmartPlusSmartPlusData.txt
So I now see a minor problem I hadn't thought of before. I can easily put the default datafile in the required location on my computer. But when I release the updated script (and related stuff) how do I get the default datafile into the correct location on the user's system ?
I see two options:
Tell the user they have to put it there.
Create the file from within my script.
Any thoughts,suggestions, recommendations ?
(and yes, I think this is now getting off-topic from the thread title, which I don'tlike to do. So maybe time to start a new thread.)
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
Looks like for most operating systems os.getenv is a wrapper for os.environ but with an optional default parameter that can save a few code lines. Stackoverflow has a discussion here https://stackoverflow.com/questions/16924471/difference-between-os-getenv-and-os-environ-get
os.environ copies the process environment variables at start-up into a dictionary object for ease of use, it might have been getenv was original intended to point directly at the process environment space until someone decided it wasn't a good idea. Modifying the environment space was useful for a child process to communicate to its parent but these days programs use shared memory so its no longer necessary.
Ah yes, thanks again. I thought I'd read something over the past few days (without noting a URL) about one raising an exception and the other returning none if the requested environment variable doesn't exist.
(I'd missed os.environ.get(), which appears to be halfway between the two)
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
FVerbaas posted at 6:32PM Mon, 04 May 2020 - #4387763
Why not write your persistent data in a subfolder of the relevant runtime folder? It is accessible to all users.
That's interesting, and puzzling. Looking at my original locateDataFile() function (which I posted here) that was an alternative location right from the start.
I think that I originally wrote the script when Poser 6 was my main version, and for some reason decided that poser.AppLocation() was the best place for the datafile. But since DAZ Studio 3 couldn't get at that location I decided that any runtime mapped by both Poser 6 and DAZ Studio 3 would be okay for users (like me) who used both. (I actually mapped the Poser 6 default runtime from DAZ Studio, and later versions of Poser when I got them). I have no idea why I didn't simply scrap the poser.AppLocation() option when I realized that!
So using a subfolder of the relevant runtime folder has always been okay when the datafile was read only. But the runtime would now have to be writable, not just by the version of Poser to which it belongs (assuming it's the default runtime for that version, located under/alongside the application), but by any other version of Poser and/or DAZ Studio which maps the runtime.
Sothe key question I guess would be something like "can DAZ Studio 4 write to the PP2014 default runtime?"
And I guess the answer will be "No".
(I have a vague, and possibly incorrect, memory that Poser 6 scripts had to be in the main runtime under/alongside the application, and recall that since my scripts had to be there it made sense to keep the datafile with them. My later Posers and my DAZ Studios all had the default eFrontier Poser 6 runtime mapped since that was where I had all the DAZ Generation 4 figures installed - remember that old EXP problem ?
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.
The only instance able to decide where an app or script is able to write to is: Windows. User X should be able to write to all data-areas owned by user X. Remember: apps are usually installed by the user Administrator, so the application folders are not writable by a user without admin rights. This is the reason why new Poser versions installs data in a global accessable document folder. This was different with earlier Windows versions.
This site uses cookies to deliver the best experience. Our own cookies make user accounts and other features possible. Third-party cookies are used to display relevant ads and to analyze how Renderosity is used. By using our site, you acknowledge that you have read and understood our Terms of Service, including our Cookie Policy and our Privacy Policy.
How do you avoid UAC problems writing to poser.AppLocation() subfolders ?
(Apologies for the brevity of this post. I spent half an hour writing all the details, but when I hit 'Submit'... the forum s**tware simply deleted everything I'd typed)
The 3Dcheapskate (also available in DAZ and HiveWire3D flavours) occasionally posts sensible stuff. Usually by accident.
And it usually uses Poser 11, with units set to inches. Except when it's using Poser 6 or PP2014, or when its units are set to PNU.