Bug since DS v4.11.0.236 DzSIReloadAction: Sets getScriptFileName() == ""
Praxis
Posts: 252
A Heads-Up in case you are suddenly getting wierd problems in your scripts with v4.11.0.383 or v4.12:
Here's the test script (also attached as test_01.dsa):
// test_01.dsa// Script to illustrate a bug in DAZ Studio v4.11.0.383 DzSIReloadAction// DzSIReloadAction can be triggered e.g. by menu: Script IDE Pane > File > Reload Scriptprint( App.longVersionString );print( ' ' );var sFileSpec = getScriptFileName();print( sFileSpec );print( ' ' );if( sFileSpec == '' ) { print( '### BUG ###: getScriptFileName() == ""' );} else { print( 'OK' );}//// In v4.10.0.123:// Works OK, including after executing DzSIReloadAction//// In v4.11.0.383:// Works OK, until after executing DzSIReloadAction// then getScriptFileName() always == ''print( ' ' );
In the v4.11.0.383 Script IDE Pane:
- File > Open Script... // Open test_01.dsa
- [Execute] // It works OK: getScriptFilename() != ""
- File > Reload Script
- [Execute] // BUG: getScriptFilename() == ""
- File > Open Script... // Open test_01.dsa
- [Execute] // BUG: getScriptFilename() == ""
- File > Close Script
- File > Open Script... // Open test_01.dsa
- [Execute] // It works OK: getScriptFilename != ""
- File > Reload Script
- [Execute] // BUG: getScriptFilename() == ""
Request #293041 submitted 03-March-2019
dsa
dsa
test_01.dsa
650B
Post edited by Praxis on
Comments
Hi, I've tested this with DS v4.10.0.123 same issue. Could it be that it is just related to the script execution in Script IDE pane and how it handles the modified source code? I mean I can press the execute button as often as I like getScriptFileName() will return the string. But as soon as I edit the source getScriptFileName() stops working, so I save my changes to the script and reload to get it working again. There shouldn't be an issue with executing the scripts from elsewhere.
[Edit_1:] I suspect the modified script code is held in memory and getScriptFileName() will no longer work becasue the currently modifed script will get a memory pointer instead of the original script file.
Since I saw the first line in Add_Structure_v3.dsa where you have used getScriptFileName() I had to try to understand what you did there to get the path to the running script.
I had a look at http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/app_dz
but didn't found "getScriptFileName()" in there so its an undocumented feature, it also seems to missbehave because I expected to only get the file name not including the path. Anyway I see you found a good workaround, thank you for that example.
Here is my modification / script example. I also found a way to use the DZApp methods to get some other useful paths for possible files save locations by scripts.
I possibly found another bug somehow App.getAbsoluteScriptPath( g_sScriptName ) dosn't return anything for me.
Update v02 Changelog:
Errors:
I don't understand why my for loop runs further than it should even while the end condition getNumContentDirectories() seems to return the right number.
see line 90: for( var i = 0; i <= oContentMgr.getNumContentDirectories(); i++ )
Update v03 Changelog:
Added var sBaseDir = oContentMgr.getContentDirectoryPath( 0 ); to get the first main Library / base Content Directory at index 0
Added var sMappedPath = oContentMgr.getMappedPath( g_sScriptPath, false, false); so contentDirectoryIsMapped( sMappedPath ) gets the actual "Content Directory" portion of the full script path and returns true in my case > This script is executed from a mapped content directory!
Got rid of all the Errors: Content directory index out of range by changing the for loop condition to for( var i = 0; i < oContentMgr.getNumContentDirectories(); i++ ) { I made a stupid mistake before with comparing the directory count with the index by using less or equal <=
Update v04 Changelog:
test_GetScript-Paths-FileName_v04.dsa
Thanks - I had not noticed that behaviour in v4.10 or v4.11 (To summarize: As soon as you alter the code in the Script IDE editor, getScriptFileName() will return "" in that code).
I never use the Script IDE for editing code, because I'm so used to using my own external editor - which is why I find this bug in v4.11 so annoying. I'm currently writing work-around code for the problem.
If I did use the Script IDE for editing, this behaviour would break all my DAZ script applications - which rely on getScriptFileName() to locate associated "library" .dsa files.
Note that getScriptFileName() is documented, as part of the Global unit. Also, the function names are not always consistent - ...Name() and ...Path() functions can sometimes return the full Specification: Drive:Path/Name.Ext - I've got into the habit of testing each one instead of assuming its behaviour.
I think that will work only if your g_sScriptName .dsa file is in one of the DS "default" locations, such as Alpp.getScriptsPath().
If your script file is somewhere else then you may need to do like this instead:
P.
OK thanks so if I need to handle files I have to construct a new file object that gets some sFielSpec that would be the absolute path, the name and the file extension I guess.
So absFileName() is a method of DzFileInfo.
http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/fileinfo_dz
I'm already running this script from a mapped content directory but this is not my first / main content directory. ScriptPath: Z:/DAZStudio - Content Directories/My Library/Scripts/_MyScripts/
If you realy want to save files to content directory folders and export OBJs and such you would also need methods of DzContentFolder.
http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/contentfolder_dz
I have added those with App.getContentMgr()into my newer script version v02 posted above.
I meant that instead of doing this (from your earlier post):
myAbsFileSpec = App.getAbsoluteScriptPath( g_sScriptName );
...you would do this (using a utility function you write like
getAbsoluteFileSpec()per my earlier post):
myAbsFileSpec = getAbsoluteFileSpec( g_sScriptName );
...so you would not need to construct a new file object each time in your main code.
Also, I think you are getting this message:
This script is not executed from a mapped content directory!
because of this line:
if( oContentMgr.contentDirectoryIsMapped( g_sScriptPath ) ) {
...which I think should probably be this instead?:
if( oContentMgr.contentDirectoryIsMapped( g_sScriptPathFileName ) ) {
@Praxis
Thanks for all your suggestions and yes I will have to make use of more utility functions in the future. I'm just looking around in the script examples and the API Reference and collecting methods for getting all kinds of useful paths if you like to execute other scripts, load/save content, load/save files or export OBJs with your script.
I've posted an updated verson above test_GetScript-Paths-FileName_v03.dsa.
I figured out everything I wanted so far. I also included the other formats Import Directories because I thought of maping my default OBJ export path as some of my Import Directories and use those by script modifications of something like Silent_OBJ_Export.dsa.
I'm even thinking of adding some default Import Directory by script if it dosn't already exists while exporting some OBJ so once exported you can browse them form the Content Library pane.
I have updated my script again see the script source above. test_GetScript-Paths-FileName_v04.dsa
I've added the poser content directories to make this script example complete. I've also added the getContentDirectory() methods that return a DzContentFolder object and with this method DzContentFile : getFirstFile() it would get me to the DzContentFile Properties: String : fullPath Holds the full path of the file. (Read Only). Also the DzContentFolder objects got those fullPath properties but I have no idea how to acces those properties.
I also see methods like this DzContentFolder : findBaseDirectory( DirectoryTypes dirTypes, String path ) that return those objects but then I tried this oContentMgr.getRelativePath(NativeDirs , g_sScriptPath )to understand how to work with relative paths. Unfortunately it dosen't work with typing the dirTypes with something like "NativeDirs" so I have no idea how to work with all those methods that uses DzContentFolder or DirectoryTypes.
This bug has been present since v4.11.0.236, and is still present in v4.12.0.47
Ticket # 293041 is still open.
Just saying that it still exists on v4.15.0.2
With a script that has been saved, to have a name?
The test_01a.dsa script attached to the first post of this thread still behaves the same in DAZ Studio v4.15.0.14
And ticket #293041 appears to no longer exist: It is not listed in "My Activities" (with any status), and a search for it says "no requests found".
Yes, with a script that has been saved and has a name.
More info here: https://www.daz3d.com/forums/discussion/508496/getscriptfilename-alternative#Comment_6892251
I've been grinding my teeth at this one all day, as I'm working on a chunk of navigation.
Of course once it's written and saved, it works normally and never throws an error. The problem is *ANY* edit to the script containing that call, while it is live in the IDE.
The way to "fix" it is Save the script, Close it, then Open it again (simply Reloading it does not work), and then it works fine upon Execute. IF you make ANY edit whatsoever in the IDE, even a trailing whitespace somewhere, it will throw the error again until you repeat the ritual.
Basically, I'm just using NPP to write, and using Reload Script to update and test live. Simply updating the script will not make it glitch, only editing with the cursor does.
As soon as the script is chnaged it no longer matches the file, and is instead just in a memory buffer from which it is executed, so it has no filename. Once you save it the version in the IDE is again the file version and so has a name.
That behaviour may or may not be desirable in a code editor, but it's certainly unusual in my experience.
Anyway, why should getScriptFileName() get reset == "" when the script in the IDE is ReLoaded from disk file? (as demonstrated by the script in the 1st post)
It shouldn't. I was discussing cases in which the script in memory does not match the file, and so doesn't have the filename.
http://docs.daz3d.com/doku.php/public/software/dazstudio/4/change_log#4_15_0_23
Thank you for the heads-up (strange that I never got any notification that the ticket had been solved/closed).
Now we just need the next beta to be released...
...and there it is in DIM: v4.15.0.25