View Full Version : Get Script Path
MysteryX
2nd October 2015, 23:45
I have an AviSynth shader that I call like this
Shader("GammaToLinear.cso")
This is defined within SuperRes.avsi, which is in the same folder as the .cso file. I have another script in a different folder that imports SuperRes.avsi.
The problem is that the Shader filter fails to find the .cso file, probably because it has a different active folder.
How can I get the path of SuperRes.avsi that is calling the filter, from within the C++ code?
MysteryX
3rd October 2015, 03:18
Never mind, I'll just add a "folder" parameter so that you can specify where to find the files.
StainlessS
3rd October 2015, 17:43
Never mind, I'll just add a "folder" parameter so that you can specify where to find the files.
Perhaps you might set default if not called with folder provided.
See ScriptDir, ScriptName, ScripFile, v2.6 only.
http://avisynth.nl/index.php/Internal_functions
There also exists script functions to do similar (use search)
eg http://forum.doom9.org/showthread.php?t=66627
MysteryX
3rd October 2015, 18:05
I'm pretty such those will return the main AVS file being loaded, not the imported AVSI file's path. When loading a file in C++ without specifying a path, I believe it by default loads from the folder of the main AVS file.
StainlessS
3rd October 2015, 19:06
D:\TEST\TEST2\B.avs
Function Dir() {
Return ScriptDir()
}
Function File() {
Return ScriptFile()
}
Function Name() {
Return ScriptName()
}
Return Name
D:\TEST\A.avs
N=Import("TEST2\b.avs") # EDIT: N return is identical to the argument to Import ie "TEST2\b.avs"
RT_DebugF("Name_1=%s\nName_2=%s",Name(),N,name="TESTING: ")
Colorbars
Outputs this
00000002 0.39082286 [920] TESTING: Name_1=D:\TEST\a.avs
00000003 0.39084291 [920] TESTING: Name_2=TEST2\b.avs
Note, Name_2 is exactly as given by call to import (change to eg TEST2/b.avs and that is what you will get back) [Changed slash].
Perhaps of interest, post by IanB:- http://forum.doom9.org/showthread.php?p=1590412#post1590412
and more: http://forum.doom9.org/showthread.php?p=1590402#post1590402
EDIT: Added Colors
MysteryX
27th October 2015, 22:43
This returns it on the script side. How do I go about getting this path from the C++ side?
MysteryX
5th November 2015, 23:37
const char* V = env->Invoke("ScriptDir", args[0].AsClip()).AsString();
Shouldn't this work to return ScriptDir? I'm getting Invalid Arguments error. Why?
TheFluff
5th November 2015, 23:45
const char* V = env->Invoke("ScriptDir", args[0].AsClip()).AsString();
Shouldn't this work to return ScriptDir? I'm getting Invalid Arguments error. Why?
because you're passing it an invalid argument (the function takes zero arguments, you're passing one)
i realize literacy is not widespread these days but you could at least try to read the error message
MysteryX
6th November 2015, 00:56
I also tried both of these which also fail.
env->Invoke("ScriptDir", NULL);
env->Invoke("ScriptDir", AVSValue());
Wilbert
11th November 2015, 23:21
I expected this too work. What error does it give?
const char* V = env->Invoke("ScriptDir", AVSValue()).AsString();
or perhaps
const char* V = env->Invoke("ScriptDir", AVSValue(0,0)).AsString();
MysteryX
12th November 2015, 03:37
or perhaps
const char* V = env->Invoke("ScriptDir", AVSValue(0,0)).AsString();
This one works!!
MysteryX
12th November 2015, 03:42
Unfortunately... none of these 3 values returns the path of the AVSI file.
ScriptDir returns F:\AVSMeter\
ScriptFile returns Preview.avs
ScriptName returns F:\AVSMeter\Preview.avs
I'm checking this within ExecuteShader, which is called from SuperRes.avsi, and I want to locate the AVSI folder to try to load the CSO files in the same folder. This still won't work.
Groucho2004
12th November 2015, 09:50
Unfortunately... none of these 3 values returns the path of the AVSI file.
ScriptDir returns F:\AVSMeter\
ScriptFile returns Preview.avs
ScriptName returns F:\AVSMeter\Preview.avs
Of course not, they return exactly what you asked for in your thread title.
However, reading your first post it is clear that you want something completely different. :rolleyes:
There are two ways to import a avsi file into a script:
1. Implicitly, by using the auto-load directory entry in the registry
2. Explicitly, by using "Import()" in your script
In the first case you'll just get the auto-load directory from the registry and add the name of your avsi file.
If "Import()" is used in the script you'll have to parse the script itself to get the path/name of the avsi file.
Note:
With AVS+ there are a few more things to consider (http://avisynth.nl/index.php/AviSynth%2B#AviSynth.2B.27s_Plugin_Autoloader). There may be several auto-load folders specified in the registry, in separate registry branches for 64/32 Bit Avisynth, you'll have to enumerate the relevant ones. Also, AVS+ supports "AddAutoloadDir" which you have to take into account when parsing the script.
TheFluff
12th November 2015, 10:58
I think the correct answer here is "don't do that". I would suggest baking the shader files you want to ship with the plugin into the dll itself and then supply a filename argument for users who want to use their own shaders, and let them sort their path names out themselves.
MysteryX
12th November 2015, 17:04
Or leave it the way it currently is. The DLL is designed to be generic so I can't hard-code any shaders into it.
When I create scripts, the first line is always something like
PluginPath="C:\MyScripts\"
which I use for loading any script or resource. I'll just pass PluginPath as the last argument as it currently is, period.
Gavino
12th November 2015, 17:31
There are two ways to import a avsi file into a script:
1. Implicitly, by using the auto-load directory entry in the registry
2. Explicitly, by using "Import()" in your script
In the first case you'll just get the auto-load directory from the registry and add the name of your avsi file.
If "Import()" is used in the script you'll have to parse the script itself to get the path/name of the avsi file.
I'm not able to try it out at the moment, but I'm pretty sure the ScriptXXX functions will give the desired imported file locations for both implicit and explicit importing. See StainlessS example at post#5 for the explicit case.
Perhaps MysteryX is calling (Invoke'ing) the functions at run-time (from a GetFrame()), in which case the top-level script name will be considered to be current.
MysteryX
12th November 2015, 17:46
Perhaps MysteryX is calling (Invoke'ing) the functions at run-time (from a GetFrame()), in which case the top-level script name will be considered to be current.
Yes... so you mean I could read that value from within SuperRes.avsi, and not have to bother passing it as function argument. If I only deal with that value internally within SuperRes.avsi to get the path and then append that to every file that needs to be loaded, then I don't need to change anything on the DLL side.
In StainlessS' sample, the second path is relative and not absolute; I'd have to see whether that's an issue.
And then, it would return the path to the AVSI file including the file name. How can I trim out the file name to keep only the folder, using AVS scripting?
StainlessS
12th November 2015, 18:48
How can I trim out the file name to keep only the folder, using AVS scripting?
From RT_Stats,
RT_FilenameSplit(string filename,int "get"=15)
Splits the un-named filename string into component parts selected by 'get' bit flags arg and returns the
parts joined together.
'Get' (default 15, 1 -> 15), If set, Bit 0=DRIVE, 1=Dir, 2=Name, 4=Extension.
Add 1 for Drive (bit 0), add 2 for Dir (bit 1), add 4 for Name (bit 2), add 8 for Extension (bit 3).
Some combinations do not make sense, eg Drive + Extension (1+8=9). Below sensible options.
1 = Drive (includes trailing ':')
2 = Dir (includes trailing '\')
3 = Drive + Dir
4 = Name
6 = Dir + Name
7 = Drive + Dir + Name
8 = Extension (includes leading '.')
12 = Name + Extension
14 = Dir + Name + Extension
15 = Drive + Dir + Name + Extension
Assuming a current working directory of eg "D:\avs\avi\", 'filename'="test.avi" and 'get'=15, returns "D:\avs\avi\test.avi",
so given a relative filename and default 'get'=15, is equivalent to RT_GetFullPathName(filename).
You're welcome to steal source from there, OR in native AVS, do a "RevStr()" to make string 'back-to-front',
find first '\' (or ''/'), strip characters up to found slash/backslash, and reverse string again. Not too difficult.
MysteryX
12th November 2015, 19:06
Is RT_FilenameSplit within AviSynth 2.6 or is it an external library? I don't want to create any additional dependency.
in native AVS, do a "RevStr()" to make string 'back-to-front',
find first '\' (or ''/'), strip characters up to found slash/backslash, and reverse string again. Not too difficult.
Easy when you know AviSynth syntax; otherwise it requires googling every simple command and a lot of trial and error for the most simple task.
What would that command look like?
StainlessS
12th November 2015, 20:04
RT_ is plugin.
This seems to work OK, is a little bit awkward without using GScript
Function GetFNPath(String FN) {
FN=RevStr(FN) n1=FindStr(FN,"\") n2=FindStr(FN,"/")
n=(n1==0)?n2:(n2==0)?n1:Min(n1,n2) # Find smallest non-zero
FN = (n>1)? MidStr(FN,n): FN # Strip up to (but NOT including) slash [Leave at least eg "D:\")
return FN.revStr
}
Function Test(String FN) {Ret = GetFNPath(FN) Return "'" + FN + "' === " + "'" + ret + "'"+Chr(10)}
Colorbars().KillAudio
S=""
A="D:\"
B="D:/"
C="D:\PATH\"
D="D:\PATH\PATH2\Fred.txt"
E="D:\PATH\PATH2\Fred.txt"
F="D:/PATH\PATH2\Fred.txt"
G="D:\PATH/PATH2/Fred.txt"
H="PATH/PATH2/Fred.txt"
I="Fred.txt"
J=".\Fred.txt"
K="..\Fred.txt"
S=S+Test(A)
S=S+Test(B)
S=S+Test(C)
S=S+Test(D)
S=S+Test(E)
S=S+Test(F)
S=S+Test(G)
S=S+Test(H)
S=S+Test(I)
S=S+Test(J)
S=S+Test(K)
RT_Debugf("%s",S,name="TEST:")
S=RT_StrReplace(S,Chr(10),"\n")
Subtitle(s,lsp=0)
Result from DebugView
00000002 1.51947868 TEST: 'D:\' === 'D:\'
00000003 1.51949728 TEST: 'D:/' === 'D:/'
00000004 1.51952112 TEST: 'D:\PATH\' === 'D:\PATH\'
00000005 1.51954496 TEST: 'D:\PATH\PATH2\Fred.txt' === 'D:\PATH\PATH2\'
00000006 1.51956892 TEST: 'D:\PATH\PATH2\Fred.txt' === 'D:\PATH\PATH2\'
00000007 1.51959288 TEST: 'D:/PATH\PATH2\Fred.txt' === 'D:/PATH\PATH2\'
00000008 1.51961672 TEST: 'D:\PATH/PATH2/Fred.txt' === 'D:\PATH/PATH2/'
00000009 1.51964056 TEST: 'PATH/PATH2/Fred.txt' === 'PATH/PATH2/'
00000010 1.51966465 TEST: 'Fred.txt' === 'Fred.txt'
00000011 1.51968873 TEST: '.\Fred.txt' === '.\'
00000012 1.51971257 TEST: '..\Fred.txt' === '..\'
MysteryX
12th November 2015, 20:15
I added this to SuperRes.avsi
folder = GetFNPath(ScriptDir()) # also tried ScriptName()
It is still returning the path where the main script file is located, not where SuperRes.avsi is located.
StainlessS
12th November 2015, 20:26
All the given script function does is strip off the file name + extension parts from supplied full path filename.
it answers this question
How can I trim out the file name to keep only the folder, using AVS scripting?
EDIT:
From your post #17
In StainlessS' sample, the second path is relative and not absolute; I'd have to see whether that's an issue.
It is relative because the argument given to Import was relative, read post #5 again (see EDIT: in Blue).
StainlessS
12th November 2015, 21:46
Perhaps MysteryX is calling (Invoke'ing) the functions at run-time (from a GetFrame()), in which case the top-level script name will be considered to be current.
Yes... so you mean ...
I think that above means that if you are trying to get path of some script other than the main script, that you will fail.
The subordinate scripts are by that time without any path, and exist only in memory (as far as Avisynth is concerned),
if you need to find path then you must at least do it in a plugin constructor, before frame serving starts and when paths
still exist.
That is how it seems to me, failing that, this seems good advise
... and then supply a filename argument for users who want to use their own shaders, and let them sort their path names out themselves.
EDIT: Also, you should only really use *.AVSI extension for auto load script in autoload plugin directory (ie NOT imported).
MysteryX
12th November 2015, 22:14
Calling it in the plugin constructor, or even in the Init function, still returns the same.
I'll just leave it that way and ask for the folder as a parameter.
Gavino
13th November 2015, 14:11
I think that above means that if you are trying to get path of some script other than the main script, that you will fail.
The subordinate scripts are by that time without any path, and exist only in memory (as far as Avisynth is concerned),
if you need to find path then you must at least do it in a plugin constructor, before frame serving starts and when paths
still exist.
Yes, that's what I meant.
Thanks for explaining it better. :)
So I don't understand why doing that doesn't work for MysteryX.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.