Bug since DS v4.11.0.236 DzSIReloadAction: Sets getScriptFileName() == ""

PraxisPraxis Posts: 123

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 Script

print( 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:

  1. File > Open Script...        // Open test_01.dsa
  2. [Execute]                       // It works OK: getScriptFilename() != ""
  3. File > Reload Script
  4. [Execute]                       // BUG: getScriptFilename() == ""
  5. File > Open Script...        // Open test_01.dsa
  6. [Execute]                       // BUG: getScriptFilename() == ""
  7. File > Close Script
  8. File > Open Script...        // Open test_01.dsa
  9. [Execute]                       // It works OK: getScriptFilename != ""
  10. File > Reload Script
  11. [Execute]                       // BUG: getScriptFilename() == ""

Request #293041 submitted 03-March-2019

 

dsa
dsa
test_01.dsa
650B
Post edited by Praxis on

Comments

  • Syrus_DanteSyrus_Dante Posts: 983
    edited July 8

    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.

     https://www.daz3d.com/forums/discussion/303561/a-script-to-create-a-polylines-dforce-add-on-modifier-for-a-bouncing-ball

    Add_Structure_v3.dsa

    // Path to this executing Script's .dsa file:
    var g_sScriptPath = getScriptFileName().left( 1 + getScriptFileName().searchRev( '/' ) );

     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:

    • Added methods of DzContentFolder to get acces to the mapped Content Directories
    • Added a check if(  oContentMgr.contentDirectoryIsMapped( g_sScriptPath ) ) I wasn't expecting this result > This script is not executed from a mapped content directory!
    • Added a check oContentMgr.doDirNumCheck(); this is giving me a warning that I have to many (>10) Content Directories mapped that can slow down content loading

    Errors:

    • general\dzcontentmgr.cpp(4768): Content directory index out of range in DzContentMgr::getContentDirectory()
    • general\dzcontentmgr.cpp(4826): Content directory index out of range in DzContentMgr::getImportDirectory()
    • Script IDE print > This script is not executed from a mapped content directory!

    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:

    • Added bug detection: if( g_sScriptPathFileName == "" )
    • Added the listing of Poser Content Directories
    • Added DzContentFolder object arrays for all Native Daz, Poser and Import Directories
    • Added getRelativePath() but disabled because not working: //var sScriptPathRelative = oContentMgr.getRelativePath(NativeDirs , g_sScriptPath ); //not working don't know how to set the 'DirectoryTypes'
    • Disabeled because not working: //var g_sScriptsPathAbsolute = App.getAbsoluteScriptPath( g_sScriptFileName );
    • Replaced all DzContentMgr path strings with arrays storing the path strings or DzContentFolder objects

    test_GetScript-Paths-FileName_v04.dsa

    // DAZ Studio version 4.10.0.123 filetype DAZ Script
    /**********************************************************************
    
    	Copyright (C) 2002-2019 Daz 3D, Inc. All Rights Reserved.
    	Script code: MODIFIED! No warranty of any kind.
     
    	This script is provided as part of the >> Daz Script Developer Discussion
    	
    	Creative Commons Attribution 3.0 Unported (CC BY 3.0)
    	- http://creativecommons.org/licenses/by/3.0
     
    	To contact Daz 3D or for more information about Daz Script visit the
    	Daz 3D website:
     
    	- http://www.daz3d.com
    	
    **********************************************************************
    test_GetScript-Paths-FileName_v04.dsa
    **********************************************************************
    Script Example: by Syrus_Dante 2019-07-08
    Source: http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/app_dz
    Source: http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/global
    Source: http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/contentmgr_dz
    Source: http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/contentfolder_dz
    Source: http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/specific_ui/set_content_library_container/start
    Source: https://www.daz3d.com/forums/discussion/303561/a-script-to-create-a-polylines-dforce-add-on-modifier-for-a-bouncing-ball
    **********************************************************************/
    
    var g_sScriptPathFileName = getScriptFileName();	// Return Value: Path and filename with extension of the current script
    var g_sScriptPath = getScriptFileName().left( 1 + getScriptFileName().searchRev( '/' ) );						//only keep what is left from the last / in the string
    var g_sScriptFileName = getScriptFileName().right(g_sScriptPathFileName.length - g_sScriptPath.length);		//only keep what is right at reversed index: full-length minus path-length
    var g_sScriptName = getScriptFileName().slice( 1 + getScriptFileName().searchRev( '/' ) , - 4 );				//only keep filename by slicing: at front last / at end remove 4 that is the file extension
    
    var g_sScriptsPath = App.getScriptsPath();		// Return Value: The absolute path of the directory where support script files are stored.
    //var g_sScriptsPathAbsolute = App.getAbsoluteScriptPath( g_sScriptFileName );	// Searches in default locations for a script file of the given name. 
    var g_sGeneratedScriptsPath = App.getGeneratedScriptsPath();	// Return Value: The absolute path of the directory where support script files that are automatically generated are stored.
    var g_sUtilitiesPath = App.getUtilitiesPath();			// Return Value: The absolute path of the base directory for all binary utilities.
    var g_sLoadSavePath = App.getLoadSavePath();			// Return Value: Last directory that files were loaded or saved to/from. //this seems to be related to scene load/save that was last used but only if executed from the main menu
    var g_sDocumentsPath = App.getDocumentsPath();			// Return Value: The absolute path of the user documents folder for the application.
    
    (function( ){
    	var sLine = "\n--------------------------------------------------------------------------------\n";
    	//print all collected paths / filenames
    	print("\n\nCollected running Script file path & name available by Global getScriptFileName():");
    	print(sLine);
    	if( g_sScriptPathFileName == "" ) {
    		print('> sorry BUG occured with: getScriptFileName() == ""');
    		print("> can not detect the path and name of this script!");
    	} else {
    		print("ScriptPathFileName:",	g_sScriptPathFileName);
    		print("ScriptPath:",			g_sScriptPath);
    		print("ScriptFileName:",		g_sScriptFileName);
    		print("ScriptName:",			g_sScriptName);
    	}
    	print("\n\nCollected paths available by DzApp:");
    	print(sLine);
    	print("ScriptsPath:",				g_sScriptsPath);
    //	print("ScriptsPathAbsolute:",		g_sScriptsPathAbsolute);
    	print("GeneratedScriptsPath:",		g_sGeneratedScriptsPath);
    	print("UtilitiesPath:",				g_sUtilitiesPath);
    	print("LoadSavePath:",				g_sLoadSavePath);
    	print("DocumentsPath:",			g_sDocumentsPath);
    
    	var oContentMgr = App.getContentMgr();
    	if( oContentMgr ){
    		var sDefaultContentDir = oContentMgr.getDefaultContentDir();	// try to get the "default" content directory - unfortunatly this is returning me an old path no longer mapped in the Content Directory Manager
    		var sBaseContentDir = oContentMgr.getContentDirectoryPath( 0 );		// Set the base to the first mapped (index 0) native formats directory - that is also refered to as base or main content library
    		//String : getRelativePath( DirectoryTypes dirTypes, String absolutePath ) 
    //		var sScriptPathRelative = oContentMgr.getRelativePath(NativeDirs , g_sScriptPath ); //not working don't know how to set the 'DirectoryTypes'
    		// arrays that will store a string or object of all mapped:
    		var aContentDirDazPaths = [];			//Native Daz Content Directories
    		var aContentDirPoserPaths = [];		//Poser Content Directories
    		var aContentDirImportPaths = [];		//Import Directories
    		var aContentDirDazFolders = [];		//Native Daz Content Directories DzContentFolder objects
    		var aContentDirPoserFolders = [];		//Poser Content Directories DzContentFolder objects
    
    		oContentMgr.doDirNumCheck();		//Causes the content manager to check the number of mapped content directories, and display a warning to the user if it is excessive. 
    
    		if( g_sScriptPathFileName == "" ) {
    			print('> sorry BUG occured with: getScriptFileName() == ""');
    			print("> can not detect if the script got executed from a mapped content directory!");
    		} else {
    			// String : getMappedPath( String path, Boolean useImportFolders, Boolean isRelative )
    			// Attempts to extract the mapped directory portion of path.
    			var sMappedPath = oContentMgr.getMappedPath( g_sScriptPath, false, false);	//take the absolut path of this script, is not an importDir, is not relative
    			if(  oContentMgr.contentDirectoryIsMapped( sMappedPath ) ) {
    				print("\n\n> This script is executed from a mapped content directory!");
    			} else {
    				print("\n\n> This script is not executed from a mapped content directory!");			
    			}
    			print("> MappedPath:",			sMappedPath);
    		}
    		print("\n\nCollected content manager paths available by DzContentMgr:" + sLine );
    		print("DefaultContentDir:",			sDefaultContentDir);
    		print("BaseContentDir:",			sBaseContentDir);
    //		print("ScriptPathRelative:",		sScriptPathRelative);	//not working
    
    		print("\n\nNumber of Mapped Native Daz ContentDirs:", oContentMgr.getNumContentDirectories() + sLine );
    		var i = 0;
    		for( i = 0; i < oContentMgr.getNumContentDirectories(); i++ ) {
    			aContentDirDazPaths [i] = oContentMgr.getContentDirectoryPath(i);		//String : getContentDirectoryPath( Number which ) 
    			print("ContentDirectoryPath Nr." + (i+1) + ":", aContentDirDazPaths [i] );
    		}
    		print("\n\nContentDir Native Daz DzContentFolder objects array:" + sLine );
    		for( i = 0; i < oContentMgr.getNumContentDirectories(); i++ ) {
    			aContentDirDazFolders [i] = oContentMgr.getContentDirectory(i);	//DzContentFolder : getContentDirectory( Number which )
    			print("DzContentFolder Nr." + (i+1) + ":", aContentDirDazFolders [i] );
    		}
    		print("\n\nNumber of Mapped PoserDirs:", oContentMgr.getNumPoserDirectories() + sLine );
    		for( i = 0; i < oContentMgr.getNumPoserDirectories(); i++ ) {
    			aContentDirPoserPaths [i] = oContentMgr.getPoserDirectoryPath(i);		//String : getPoserDirectoryPath( Number which ) 
    			print("PoserDirectoryPath Nr." + (i+1) + ":", aContentDirPoserPaths [i] );
    		}
    		print("\n\nContentDir Poser DzContentFolder objects array:" + sLine );
    		for( i = 0; i < oContentMgr.getNumPoserDirectories(); i++ ) {
    			aContentDirPoserFolders [i] = oContentMgr.getPoserDirectory(i);		//DzContentFolder : getPoserDirectory( Number which ) 
    			print("DzContentFolder Nr." + (i+1) + ":", aContentDirPoserFolders [i] );
    		} 
    		print("\n\nNumber of Mapped ImportDirs:", oContentMgr.getNumImportDirectories () + sLine );
    		for( i = 0; i < oContentMgr.getNumImportDirectories (); i++ ) {
    			aContentDirImportPaths [i] = oContentMgr.getImportDirectoryPath(i);		//String : getImportDirectoryPath( Number which )
    			print("ImportDirectoryPath Nr." + (i+1) + ":", aContentDirImportPaths [i] );
    		}
    	}
    })();
    dsa
    dsa
    test_GetScript-Paths-FileName.dsa
    3K
    DazStudioWarning-ToManyContentDirectories.png
    457 x 125 - 9K
    ContentDirectoryManager_MyMappedNativeContentDirs.png
    476 x 463 - 20K
    test_GetScript-Paths-FileName_v02-Error01-IndexOutOfRange.png
    1260 x 1041 - 80K
    dsa
    dsa
    test_GetScript-Paths-FileName_v02.dsa
    5K
    dsa
    dsa
    test_GetScript-Paths-FileName_v03.dsa
    6K
    test_GetScript-Paths-FileName_v03.png
    1260 x 1041 - 87K
    test_GetScript-Paths-FileName_v04.png
    1260 x 1041 - 83K
    dsa
    dsa
    test_GetScript-Paths-FileName_v04.dsa
    9K
    Post edited by Syrus_Dante on
  • PraxisPraxis Posts: 123

    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.

    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 possibly found another bug somehow App.getAbsoluteScriptPath( g_sScriptName ) dosn't return anything for me.

    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:

    function getAbsoluteFileSpec( sFileSpec )
    {
      var oFileInfo = new DzFileInfo( sFileSpec );
      var sAbsFileSpec = oFileInfo.absFileName();
    
      // v4 Sample scripts always do this after "new DzFileInfo()":
      oFileInfo.deleteLater();    // Don't leak memory
      
      return sAbsFileSpec;
    }

    P.

     

  • Syrus_DanteSyrus_Dante Posts: 983

    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

    Praxis said:

    I possibly found another bug somehow App.getAbsoluteScriptPath( g_sScriptName ) dosn't return anything for me.

    I think that will work only if your g_sScriptName .dsa file is in one of the DS "default" locations, such as Alpp.getScriptsPath().

    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.

  • PraxisPraxis Posts: 123
    edited July 8

    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.

    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 ) ) {

     

     
     
    Post edited by Praxis on
  • Syrus_DanteSyrus_Dante Posts: 983
    edited July 7

    @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.

    Post edited by Syrus_Dante on
  • Syrus_DanteSyrus_Dante Posts: 983
    edited July 8

    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.

    Post edited by Syrus_Dante on
  • PraxisPraxis Posts: 123

    This bug has been present since v4.11.0.236, and is still present in v4.12.0.47

    Ticket # 293041 is still open.

     

Sign In or Register to comment.