What script languages can be used with script rename?

Thanks for pushing me in the right direction. :slight_smile:

I hope so... :wink:

The php5activescript.dll was already on my system, I just hadn't registered it. Now the Hello World script from the PHP manual works, and the DOpus renaming script

@script phpscript function Rename_GetNewName($strFileName, $strFilePath, $fIsFolder, $strOldName, &$strNewName) { $strNewName = "test.txt"; }
at least leads to the following output in the Output window:

[quote]Successfully initialized 'phpscript' engine
Script started successfully[/quote]
But the script seems to crash or something like that - it doesn't do anything, and in the Output window the line

is missing. Even when the function is empty, the script won't "complete". When I try to use $WScript->echo() as in the example script from the PHP manual, DOpus crashes completely!

There's another strange thing: If I want to save it as a preset, the new name appears in the list. When I close the Rename window and open it again, the preset has gone... :confused: I had to create the preset file manually.

Well, since I didn't occupy myself with the Windows Script Host until now, I guess I have to learn quite a lot about it. Unfortunately the interplay of PHP and the WSH seems to be documented very poorly.

Cheers,
Jan

The WScript object won't exist for scripts running inside of Opus. If you want to send a string to the Opus Output Window (Script tab) you have to use something like this (in VBScript as I don't know the PHP syntax):

Dopus.OutputString "Hello World"

Of course, crashing is bad even if the script contains an error but it is likely that the cause of the crash is the PHP scripting engine rather than Opus itself since I doubt Opus knows about WScript or has any direct interaction with what the script does. I might be wrong but PHP is probably wrongly assuming that the WScript object will always exist which is only true if it's running under WScript.

The WScript object won't exist for scripts running inside of Opus. If you want to send a string to the Opus Output Window (Script tab) you have to use something like this (in VBScript as I don't know the PHP syntax):

Dopus.OutputString "Hello World"

I saw that in the manual and already tried to make something out of it. An object in PHP has a $ symbol before the name, and methods are separated from the object name by an arrow:

$Dopus->OutputString("Hello World");

should be the correct syntax. This way DOpus doesn't crash, but also nothing happens - there's no additional output in the Output window. But I'm not sure if the function code is executed at all - as I said, even an empty function doesn't lead to a completion of the script.

DOpus seems to crash whenever there's an error in the code. As I said, I don't know much about the WSH, but the assumption that the error lies there rather than on DOpus' side is probably correct.

Cheers,
Jan

[quote]The WScript object won't exist for scripts running inside of Opus. If you want to send a string to the Opus Output Window (Script tab) you have to use something like this (in VBScript as I don't know the PHP syntax):

Code:
Dopus.OutputString "Hello World"
[/quote]

Yes Nudel,
I have not yet found any method to send a string to the Opus Output Window using PHPscript.
Part of the problem is definitely syntax.
PHP does not understand Dopus.OutputString.
PHP also does not understand $Dopus.OutputString.
The '.' character has a different meaning in PHP.
It is a concatenation operator.
This is obviously different than the intent of Dopus.OutputString.

I have been able to write text files though.
Text files are the best I can do to output data from the rename script.

I know PHP sees an Object Dopus and an Object Rename, but I have not been able to reverse engineer any properties and methods.
PHP has such functions, although I understand them very little.
It is a wonderful technique to crash Dopus though.
The best result I've had are that the objects contain no properties or methods.

The above ActiveScript link to PHP.net documents the dll as :

You know this much better than I do,
but I can't help but think I'm doing something wrong, perhaps in the PHP.ini file.
At the very least, Enigma is finding the same results that I have found .
Well, so far anyway.

[quote="Zippo"]I have not yet found any method to send a string to the Opus Output Window using PHPscript.
Part of the problem is definitely syntax.[/quote]
Hm, this doesn't seem to be the problem - calling

$DOpus->OutputString('whatever');

works perfectly - if it is called from outside the function... :confused:

A call from inside the function is also possible if you explicitly add a function call.

As it seems, the PHP function isn't even called - which is what I suspected. But why? And what can I do about it? :wink:

Me too - but just from outside the function. What about you?

[quote="Zippo"]I know PHP sees an Object Dopus and an Object Rename, but I have not been able to reverse engineer any properties and methods.
PHP has such functions, although I understand them very little.[/quote]
These functions don't seem to work, which is not particularly astonishing, taking into account that those objects aren't "real" PHP objects.

Oh yes, it is... :wink:

Cheers,
Jan

I know nothing about PHP so this may be completely wrong but does PHP interpret an underscore in function names as something special, like to define a member function?

Zippo mentions that there's a Rename object of some sort in PHP (which I think he's found by listing all objects) and the function name is Rename_GetNewName so I wonder if that's turning into a GetNewName function on an object called Rename rather than a Rename_GetNewName function with global scope?

[quote="nudel"]I know nothing about PHP so this may be completely wrong but does PHP interpret an underscore in function names as something special, like to define a member function?

Zippo mentions that there's a Rename object of some sort in PHP (which I think he's found by listing all objects) and the function name is Rename_GetNewName so I wonder if that's turning into a GetNewName function on an object called Rename rather than a Rename_GetNewName function with global scope?[/quote]
It is a name convention to prefix member functions with an underscore, but that's it. Using the underscore in function names is absolutely normal; it's even the preferred notation since almost all of PHP's own functions have an underscore in their names.

You can see the two objects (or what PHP thinks are objects) for example when showing the contents of $GLOBALS:

ob_start(); print_r($GLOBALS); $str_output = ob_get_contents(); ob_end_clean(); $DOpus->OutputString($str_output);
A part of the output of this is

[code] [DOpus] => variant Object

[Rename] => variant Object[/code]

Greetings,
Jan

[code]@script phpscript

$type = variant_get_type($Rename);
$DOpus->OutputString($type);
$DOpus->OutputString("Hello World");[/code]

Outputs:

[quote]Successfully initialized 'phpscript' engine
Script started successfully
9
Hello World
[/quote]

The content type of the Variant Object Rename is 9.
It is an integer specifying a VT_XXX type.
I know it is NOT a string.
The PHP manual refers any questions as to what type the number 9 represents to the MSDN Library.
I couldn't find it there either.
Nudel, do you happen to know ?

Number 9, Number 9, Number 9, ......

9 is VT_DISPATCH - that is, an object derived from the IDispatch interface.

I've found something.

@script phpscript $type = variant_get_type($Rename); $DOpus->OutputString($type); $DOpus->OutputString(com_print_typeinfo($Rename,'GetNewName')); $DOpus->OutputString("Hello World");

Output:

[quote]Successfully initialized 'phpscript' engine
Script started successfully
9
True
Hello World
[/quote]

The real meat of this is the PHP function
bool com_print_typeinfo ( object $comobject [, string $dispinterface [, bool $wantsink]] ) .

[quote]The purpose of this function is to help generate a skeleton class for use as an event sink. You may also use it to generate a dump of any COM object, provided that it supports enough of the introspection interfaces, and that you know the name of the interface you want to display.

comobject should be either an instance of a COM object, or be the name of a typelibrary (which will be resolved according to the rules set out in com_load_typelib()). dispinterface is the name of an IDispatch descendant interface that you want to display. If wantsink is TRUE, the corresponding sink interface will be displayed instead.
[/quote]

If I substitute something random for the string 'GetNewName', the output is :

[quote]Script started successfully
9
Error at line 3, position 0
Unable to find typeinfo using the parameters supplied
False
Hello World
[/quote]

OK, I have some more here now.
Hopefully GPSoft won't go after me for hacking Directory Opus. :sunglasses:

@script phpscript $DOpus->OutputString(com_print_typeinfo($Rename,'GetNewName')); ob_start(); com_print_typeinfo($Rename,'GetNewName'); $typeInfo = ob_get_contents(); ob_end_clean(); $DOpus->OutputString($typeInfo); $DOpus->OutputString("Hello World");

Output:

[quote]Successfully initialized 'phpscript' engine
Script started successfully
True
class IDOpusScript_RenameEvent { /* GUID={CE3B9C86-CF4F-48B2-8D5A-44A82DC02733} /
/
DISPID=501 /
/
VT_HRESULT [25] /
function GetNewName(
/
VT_BSTR [8] [in] / $pszFileName,
/
VT_BSTR [8] [in] / $pszFullPath,
/
VT_I4 [3] [in] / $fIsFolder,
/
VT_BSTR [8] [in] / $pszOldName,
/
VT_PTR [26] [in][out] --> VT_VARIANT [12] */ &$varNewName
)
{
}
}

Hello World
[/quote]

[quote="nudel"]I know nothing about PHP so this may be completely wrong but does PHP interpret an underscore in function names as something special, like to define a member function?

Zippo mentions that there's a Rename object of some sort in PHP (which I think he's found by listing all objects) and the function name is Rename_GetNewName so I wonder if that's turning into a GetNewName function on an object called Rename rather than a Rename_GetNewName function with global scope?[/quote]

The underscore is a function of VBScript, it's not an intrinsic part of the function name in Opus. There's an object called "Rename", which has a member function called "GetNewName" - not a global function called Rename_GetNewName.

Eg, in C++ it would be Rename::GetNewName.

I got this far with ActivePerl today:

[code]@script PerlScript
use Win32::OLE qw(EVENTS);

package MyEvents;
sub GetNewName {
$DOpus->OutputString("*** Sub called! ***");
}

package main;
Win32::OLE->WithEvents( $Rename, 'MyEvents', 'IDOpusScript_RenameEvent' );

$DOpus->OutputString("*** Main ***");[/code]

The "*** Main ***" message will be displayed, which is good, but then Opus will crash, which is bad.

The crash is happening inside of the ActivePerl DLL. Win32 OLE/Event support is said to be at "alpha" level and unstable/subject to change so my fear is that this simply won't work with Perl.

I think my script is right because if I change the $Rename to anything else, or the IDOpusScript_RenameEvent to anything else, then the crash does not happen and the sub is not called. So presumably the crash indicates that the sub is being called (or at least looked for), but then ActivePerl crashes the process.

I'm not sure where to go next, except maybe to ask for help on the ActiveState forums or try another language. :slight_smile:

(BTW, I was saddened to see that ActivePerl still installs to C:\Perl. Gah. It isn't 1985...)

Thanks much Jon !
Working on it in PHP Nudel.
Just a short late night PHP note:

The problem is that the Script completed line is never displayed when the $Dopus object or $Rename object is used.
I can write an arbitrary PHP script without using those objects and all is fine.
The Script Completed line is there !

$Rename members still error as undefined.
So, I'm wondering if another dll needs to be registered with regsvr32 ?
I tried php_win32std.dll and php_win32service.dll but is isn't proper.
It loaded with an error.
But then it is worthy to note that I only installed a "lite" copy of php guessing at what extensions I really needed.

Other than that I'm down to php.ini .....

I'm working on it though ...
Keep up the good work Nudel !
And thanks Jon !

[quote]I can write an arbitrary PHP script without using those objects and all is fine.
The Script Completed line is there ! [/quote]
Duh....
Tonight I'm not seeing the script completed line at all again.
Well, I'll try again after restoring my backup and installing a more complete version of PHP.

9.1.0.2 is out now and will try calling an alternative function/event which doesn't need pass-by-reference. Maybe that will make things work for some languages.

(I don't think it will help with Perl since Perl does let you set things by reference, and even has a specific thing for setting a ByRef variant string. The problem with Perl is it seems to crash when script events are called.)

[quote="nudel"]9.1.0.2 is out now and will try calling an alternative function/event which doesn't need pass-by-reference. Maybe that will make things work for some languages.

(I don't think it will help with Perl since Perl does let you set things by reference, and even has a specific thing for setting a ByRef variant string. The problem with Perl is it seems to crash when script events are called.)[/quote]

It at least works with JavaScript:

@script jscript
function Rename::GetNewName2 ( strFileName, strFilePath, _fIsFolder, strOldName, strNewName ){
 return strFileName.replace(/[._]/g,' ');
}

The above strips . and _ from filenames, all occurences, including the extension separator (just a test, so didn't bother with something fancy).

Btw, I noticed that the GetNewName2 doesn't use the [out,retval] flags on any variable, not sure of how this would affect things among the languages.

It works very well with Perl too:

@script perlscript
sub Rename_GetNewName2{
my( $strFileName, $strFilePath, $_fIsFolder, $strOldName, $strNewName )=@_;
  return "Test".$strFileName;
}

The above returns Test prepended on every filename. Nothing fancy, as I said.

Wonderful news myarmor !

Still nothing working here in PHP :frowning: :unamused:
I worked about two hours on it this afternoon.
I still can't see any values for the variants.
I've tried many things .....

It would be best to get PHP working as object oriented though.
The PHP5 syntax is quite nice then .
Well, we do have $DOpus->OutputString() !

Great stuff, myarmor!

I see now that I was making the Perl example far more complicated than it had to be. I could've sworn I had tried a simple sub called Rename_GetNewName2 before embarking on the Win32::OLE events crash-fest dead-end, but obviously I messed something up in all my faffing around. :slight_smile: Great to see it is worked out now, and so simple to boot.

I've summarised the different script syntaxes into a post over in the Rename forums:

[Rename scripts in JScript, VBScript and PerlScript)