INTERACT FORUM

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1]   Go Down

Author Topic: Passing string variables to COM Automation functions in VBScript  (Read 14414 times)

freebirds

  • Recent member
  • *
  • Posts: 6
Passing string variables to COM Automation functions in VBScript
« on: February 10, 2014, 12:58:58 pm »

Im writing a basic script to use some jriver functions (VBScript in windows7) but I have a problem passing parameters in variables (see example)

Duration = jriver.GetFile("C:\Evocacion.wma").GetFormattedDuration --------------  This works fine

Dim fileName
fileName = "C:\Evocacion.wma"
Duration = jriver.GetFile(fileName).GetFormattedDuration  ------------  This does not work as the fileName variable is not interpreted as a string

I also tried fileName = chr(34) + "C:\Evocacion.wma" + chr(34) ------- Same as previous one (does not work)

Will appreciate any help
Logged

AndrewFG

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 3392
Re: Passing string variables to COM Automation functions in VBScript
« Reply #1 on: February 10, 2014, 02:36:24 pm »

^

I am a bit rusty on VBscript, but did you try declaring "Dim fileName as string" rather than just "Dim fileName"

And also you may find that you need to write c:\\ rather just c:\


Logged
Author of Whitebear Digital Media Renderer Analyser - http://www.whitebear.ch/dmra.htm
Author of Whitebear - http://www.whitebear.ch/mediaserver.htm

freebirds

  • Recent member
  • *
  • Posts: 6
Re: Passing string variables to COM Automation functions in VBScript
« Reply #2 on: February 10, 2014, 02:44:58 pm »

Thank you..but I can't declare a type for a variable con the VBScript I am using. Tried your suggestion but didn't work.

Thanks for the reply
Logged

glynor

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 19608
Re: Passing string variables to COM Automation functions in VBScript
« Reply #3 on: February 10, 2014, 08:23:36 pm »

You shouldn't need to escape the \ character in VBScript.  I'm not sure what is happening, but I don't think you've diagnosed it correctly.  Can you post more of your script so we can see what's going on?

I tested the following script:

Code: [Select]
Option Explicit

dim fileName
fileName = "c:\Evocacion.wma"

wscript.echo fileName

And the results were:

U:\Users\glynor\Desktop>cscript.exe test.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

c:\Evocacion.wma


Also, make sure the c:\Evocacion.wma file actually exists.  If it doesn't exist, or hasn't been imported into MC, then the GetFile() command from MC returns an empty object (it comes back, but when you check any of the properties, they're blank).  One thing that could be happening, if you aren't actually using that test file, is that spaces could be breaking it.  If the filename has spaces, you have to quote it.  Because the quotes are considered the "string delimiter", you do have to escape the quotes with a double-quote, like so:

Code: [Select]
fileName = """M:\Audio\Music\A\The Avett Brothers\Emotionalism\03 - Paranoia in B-Flat Major.mp3"""
Logged
"Some cultures are defined by their relationship to cheese."

Visit me on the Interweb Thingie: http://glynor.com/

freebirds

  • Recent member
  • *
  • Posts: 6
Re: Passing string variables to COM Automation functions in VBScript
« Reply #4 on: February 10, 2014, 11:41:44 pm »

Thank you for your reply...

Here is the code that doesn't work

Code: [Select]
      Dim fileSize
      Dim a
      Dim fieldValue
      Dim field
      Dim size
      Dim MCFile

      Set jriver = CreateObject("MediaJukebox Application")
      SongToPlay = "C:\Evocacion.wma"
      MsgBox("File : " & SongToPlay)                           
      Set MCFile = jriver.GetFile(SongToplay)
      size = MCFile.GetFormattedFileSize()
      MsgBox("Size : " & size)
      MsgBox("Duration : " & MCFile.Duration)
      MsgBox("Duration : " & MCFile.GetFormattedDuration())
      field = "Conductor"
      MsgBox("Old Conductor : " & MCFile.Get(field,true))
      fieldValue = "New Conductor"
      a = MCFile.Set(field,fieldValue)
      if a then
         MsgBox("Success")
      else
         MsgBox("Failure")
      End if
      MsgBox("New Conductor : " & MCFile.Get(field,true))
 

Two problems there....jriver.GetFile(SongToPlay) does not work, as for some reason the variable SongToPlay is not changed into its value before passing the parameter.  But if I change SongToPlay for "C:\Evocacion.wma" it works fine

Same happens with the MCFile.Get(field,true) function, the variable field is  not changed into its value before passing the parameter. But when I change it to MCFile.Get("Conductor",true) it works fine.

The file does exists and it is already loaded into JRiver. I do get the correct information on the file when I use the literal string instead of the variable.

Thank you
Logged

glynor

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 19608
Re: Passing string variables to COM Automation functions in VBScript
« Reply #5 on: February 11, 2014, 12:18:00 am »

There are a few problems in there, but the main problem is this:

Set MCFile = jriver.GetFile(SongToplay)

That's not the same variable as:

SongToPlay = "C:\Evocacion.wma"

Capitalization counts.  (Notice, the lower-case "p" in "play" in the GetFile() method call, and the uppercase "P" elsewhere.  Yep, that's two different variables.)

So, that answers your question.  However, you're going to keep making mistakes like that.  You absolutely need to use Option Explicit at the top of your vbscript file.  Option Explicit in VB forces you to DIM all variables before using them.  Without it, you don't need ANY of those dim commands you have in there at all, because VB will auto-create variables when you first "use" them.  That's why you're able to assign to your jriver and SongToPlay variables even though you didn't put a dim statement for them anywhere in there.  So, since you don't have Option Explicit at the top of your script, you don't need to DIM anything at all (they'll be all auto-created).

This might seem convenient at first glance.  In fact, you might think: "well, then, why do you even need the DIM command at all".  Well, now you know why: Because it is very easy to make a typo and accidentally create new variables.  With Option Explicit on, it will tell you exactly where you made the mistake, because you have to "thoughtfully create" all variables (and then re-use the same exact name with no typos to do anything useful with them).  More here: http://www.w3schools.com/vbscript/vbscript_variables.asp

So, if you add Option Explicit to the top of your script there, it is going to throw errors when you try to run it.  It'll actually throw an error first when it tries to use the "jriver" variable, because you don't currently have a DIM statement for that one.  But, assuming you had done that for all of your variables, it would have thrown an error on this line:

Set MCFile = jriver.GetFile(SongToplay)

Complaining about an Unexpected Identifier (which means: you didn't DIM a variable) and give you the exact line number and character where the error occurred.  You'd then look at it and go "oh, crud, I fat-fingered that one".

Option Explicit is your friend.
Logged
"Some cultures are defined by their relationship to cheese."

Visit me on the Interweb Thingie: http://glynor.com/

glynor

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 19608
Re: Passing string variables to COM Automation functions in VBScript
« Reply #6 on: February 11, 2014, 12:33:25 am »

Another thing I'll mention...

Download my MCAutoQueue application.  After you install it, in the installation directory's Processors folder, you'll find a vbscript called CopySidecar.vbs.  This is a pretty old script and I haven't updated it any time recently (I do my work in C# and other languages for now).  I'm honestly not even 100% sure it still works, and even if it does, I wouldn't recommend using it for anything (it is, essentially, a previous version of MCFileIngester, which is much more powerful, so use that if you want to do something like what it does).

However, it shows how to connect to MC, parse command line options, and play with files in MC and on the filesystem.  It is fairly well commented and might be instructive.  For example...

Code: [Select]
Function blnMCWriteTags(sourceFile)
'This procedure connects to an instance of MC and then forces it to update the tags for the given sourceFile
'For video files, this causes MC to write a JRSidecar.xml file out to disk

'Connect to MC instance (try running object first)
Dim objMC
On Error Resume Next
Set objMC = GetObject(, "MediaJukebox Application")
If Err.Number = 429 Then
On Error Goto 0
'Then, create a new object
Set objMC = CreateObject("MediaJukebox Application")
End If

'Get the File object from MC
Dim objMCFile
Set objMCFile = objMC.GetFile(sourceFile)

'Check to see if MC can access the MJFileAutomation.Filename() property (if not, the file is probably not there)
If objMCFile.Filename() = "" Then
ReportError "MC ERROR:" & VbCrLf & VbCrLf & "File record not found: " & VbCrLf & sourceFile & vbCRLF & vbCRLF & "Source file is likely not in the active MC Database.", 0, 1
End If

Or, if you happen to be interested in writing in C# instead, I have a wrapper Library that makes it super-easy to access MC via COM, and has all sorts of pre-built utility methods.  It isn't done, and is kind-of constantly in flux, which is why I've never published it (and there are a bunch of "old mistakes" I'd like to fix before I do), but I'd be happy to send you a PM with a download link if you want to use it.  MCAutoQueue and all of my other utilities are built on top of it, and it works quite well as-is, even if some of it is ugly.

If you're learning anyway, C# is a better language than VB, and you can get a free copy of Visual Studio that is perfectly well suited for writing console applications from Microsoft (you want the one called Express 2013 for Windows Desktop).  I'm not 100% sure if there are any limits to the express version that would make my library not work, but probably not.  If the express version can use COM at all, it'll almost certainly work.

Of course, then the machine you're going to use these on will need to have the .NET runtimes installed.  If you require these to work on machines were that isn't the case, or you don't want to compile them to EXEs for other reasons, then maybe you're better off either sticking with vbscript or (better) learning Perl or Python.
Logged
"Some cultures are defined by their relationship to cheese."

Visit me on the Interweb Thingie: http://glynor.com/

freebirds

  • Recent member
  • *
  • Posts: 6
Re: Passing string variables to COM Automation functions in VBScript
« Reply #7 on: February 11, 2014, 07:06:55 pm »

Thank you very much for your help...

I actually did have the variables declared (in a part of the script I didn't copy) using the option Explicit, also the VBScript I am using is not case sensitive. I believe there is a problem with the VBScript I am using because it is not sending the value of the variable in the parameter, instead it is sending the name itself. I will follow your advise and try Visual Studio.

Regards
Logged

glynor

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 19608
Re: Passing string variables to COM Automation functions in VBScript
« Reply #8 on: February 11, 2014, 07:32:23 pm »

I'm reasonably sure that VB is case insensitive when you compile it, but this is really a "trick".  The compiler automatically fixes case mismatches when you compile the application.

To my knowledge, and in my experience, the CLR (Common Language Runtime) is case sensitive, and this is what applies when you run a non-compiled VBScript in Windows.  As I mentioned above, though, I haven't messed with VBScript stuff in a long while, so I could be remembering wrong (or getting mixed up).

If you're writing a script, and not compiling it down to an EXE, then it doesn't matter what the tool you're using does.  It matters how the interpreter reads the script at runtime.  And this is governed by Windows and the CLR, unless you've got something really oddball on there.
Logged
"Some cultures are defined by their relationship to cheese."

Visit me on the Interweb Thingie: http://glynor.com/

glynor

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 19608
Re: Passing string variables to COM Automation functions in VBScript
« Reply #9 on: February 11, 2014, 07:35:58 pm »

Hmmm... Actually, it looks like I'm remembering wrong.  I can't find a recent official word from Microsoft (though I didn't look hard), but I found some old circa-2000 documentation that says that variable names are case insensitive even in VBScript.

Dunno.  I might be able to figure it out if you post the whole script.
Logged
"Some cultures are defined by their relationship to cheese."

Visit me on the Interweb Thingie: http://glynor.com/

freebirds

  • Recent member
  • *
  • Posts: 6
Re: Passing string variables to COM Automation functions in VBScript
« Reply #10 on: February 12, 2014, 02:20:52 am »

Now I am a little worried....I tried writing the program in Visual Studio with Visual Basic, and get the same thing....string variables are not evaluated to their values before passing to the MC functions. It happens with all functions where I send a variable.

Here is the complete code in VB

Code: [Select]
Class MainWindow

    Dim JRiver

    Sub initJRiver()

        Dim field As String
        Dim fieldValue As String
        Dim fileNameParam As String
        Dim MCFile
        Dim a As Boolean

        On Error Resume Next
        JRiver = GetObject(, "MediaJukebox Application")

        If Err.Number = 429 Then
            On Error GoTo 0
            'Then, create a new object
            JRiver = CreateObject("MediaJukebox Application")
        End If

        MsgBox("Number of fields : " & JRiver.GetFields().GetNumberFields())    ' Works fine -- result is the number of fields in MC
        MsgBox("Version : " & JRiver.GetVersion.Major)                          ' Works fine -- result is 19

        'Get the File object from MC
        fileNameParam = fileName.Text
        MsgBox("fileNameParam : " & fileNameParam)
        MCFile = JRiver.GetFile(fileNameParam)                                  ' Does not work but if I change fileNameParam with the actual string "C:\Evoacion.wma" works fine
        'Check to see if MC can access the MJFileAutomation.Filename() property (if not, the file is probably not there)
        If MCFile.Filename() = "" Then
            MsgBox("MC ERROR:" & vbCrLf & vbCrLf & "File record not found: " & vbCrLf & fileName.Text & vbCrLf & vbCrLf & "Source file is likely not in the active MC Database.", 0, 1)
        Else
            MsgBox("Duration = " & MCFile.Duration)
            MsgBox("File Size = " & MCFile.GetFormattedFileSize())
            field = "Conductor"
            fieldValue = "Daniel Lederman"
            MsgBox("Old " & field & " : " & MCFile.Get(field, True))            ' Does not work, but if I change fiel with the actual string "Conductor" it works fine
            a = JRiver.MCFile.Set(field, fieldValue)                            ' Does not work, but if I change the variables for the actual strings, it works fine   
            If a Then
                MsgBox("Success, New " & field & " : " & MCFile.Get(field, True))    ' Does not work, but if I change field with the actual string "Conductor" it works fine
            Else
                MsgBox("Failure")
            End If
        End If
    End Sub

    Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        MessageBox.Show("Calling Init JRiver with: " & fileName.Text)
        initJRiver()
    End Sub

End Class

Thanks again for taking the time
Logged

freebirds

  • Recent member
  • *
  • Posts: 6
Re: Passing string variables to COM Automation functions in VBScript
« Reply #11 on: February 12, 2014, 02:30:42 am »

Found the solution in a microsoft documentation site:

"If you specify a data type for an argument passed by reference, you must pass a value of that type for the argument. You can work around this by passing an expression, rather than a data type, for an argument. Visual Basic evaluates an expression and passes it as the required type if it can.
The simplest way to turn a variable into an expression is to enclose it in parentheses. For example, to pass a variable declared as an integer to a procedure expecting a string as an argument"

I changed all calls to MC functions that use variables to ...GetFile((fileName)) instead of GetFile(fileName)

Hope this helps someone else
Logged
Pages: [1]   Go Up