INTERACT FORUM
Windows => Third Party Plug-ins, Programs, and Skins => Topic started by: Mr ChriZ on January 31, 2007, 01:41:12 pm
-
Description
This plugin allows you full access to the Media Center Programming Interface
using Scripts written in either C# or VB.NET.
These can be compiled and run on the fly with Media Center open!
The programming interface is exactly the same one as used by all the interface
plugins out there.
The Script's have full access to the .NET framework. Theres next to nothing you can't do.
Screenshot
This image here (http://img74.imageshack.us/img74/46/vbscriptkx6.png) shows what the plugin looks like when running.
Pre-requesits
Make sure you have the latest version of the .NET Framework 2.0. This is installed as standard in Windows Vista, 7, 8 etc but may need installing for Windows XP.
.NET 2.0 must be installed. .NET 3.0/.NET 4.0 on their own will not suffice.
Where do I get it?
Now available here for instant download
This is a beta version
Click Here Go to Download Site (http://accessories.musicex.com/mediacenter/mc_data/plugins/833.mjp)
Installation
Close Media Center before Installation.
Go through the setup program.
Open Media Center,
Go to Services and Plugins in the tree.
Scripting plugin should be there.
Acknowledgments
This plugin would not be possible without the exceptional genius of Oleg Shilo
who wrote the C# Scripting engine
http://www.codeproject.com/csharp/cs-script_for_CP.asp
http://www.members.optusnet.com.au/~olegshilo
or the use of #Develops Editor
http://www.icsharpcode.net/OpenSource/SD/Default.aspx
Current Build Status as of 23/06/2007
>Release Candidate 1 Version 0.6.5.0
- Minor Release Fixing Kill Bug
[0.6.0.0]
* Scripts are now started using a helper command line tool ScriptRunner.exe
* Scripts start in their own Application Domain, allowing handling of events
and threads etc.
* Scripts can be started without the script plugin
* Textbox output is now performed using standard output
Current Plugin Supports
>VB Scripts New!
>Template Scripts to start you off
>Real Time Editing of scripts (You type, it saves)
>Undo/Redo by Ctrl-Z, Ctrl-Y
>Creating of new scripts
>Renaming Scripts (You type it renames, You type the wrong thing it breaks)
>Exploring Script Directory
>Output for Compile Errors
>Compilation and running of scripts
>Starting One Script From Another!
>Script running on a new thread
>LED Indication of Thread Running
>Ability to kill that thread
>Detection of file changes
>Ability to output strings to the output textbox (Via TextBox reference)
>Syntax Highlighting
>Line Numbers
>#Develops Editor
There are some obvious desirables in the future
such as
>Java Script? (If People want it)
>Remote starting of a script
>Script Backup System
>Optional non real-time editing interface
>Running Scripts on Startup of MC
>Refresh to find new scripts
>Modifying of Templates (You can edit these in another editor if you like, they are under The template in the MC Plugin Directory\Script Plugin)
>Conversion of Scripts to .EXE's (Scripting engine can do this to!)
>Intellisense?
>Your Idea here
What will the next build center on?
Unknown
Known Bugs
Kill Script Not Available When it should be...
Usage notes...
>Don't change the init method declaration else my plugin won't be able to find it!
>Theoretically you can create another class in the same script file and then create
an instance of that class from init
>Source Code will be made public as soon as I have time to tidy it up a bit, and make it worth reading!
>MediaCenter Interface is described here http://www.jrmediacenter.com/DevZone/MJAutomation.html
>If you really want the source code in it's current form just ask!
Sample Scripts
Can be found here (http://yabb.jriver.com/interact/index.php?topic=33020.0)
Feel free to add to them!
-
now that nice! i earn part of my living programming databases, but never understood this net stuff. i do have some ideas for plugins.. this could be just what i need to get me started.
thanks
-
maybe i ask something very stupid, and in the wrong thread (in which case i happely delete it). i changed some things in the template trying to understand how this mc automation works. for a test i wanted to make a messagebox telling me how much songs there are in playing now.
following the logic from the template i expected that this would work (i disabled the messagebox).
Imports System
Imports System.Windows.Forms
' //css_reference System.dll;
' //css_reference System.Windows.Forms.dll;
' //css_reference MediaCenter.dll;
Module Script
Sub Init( mediaCenterInterface as MediaCenter.MCAutomation, outputTextBox as Textbox)
dim aantal as MediaCenter.IMJCurPlaylistAutomation
aantal=mediaCenterInterface.GetNumberFiles()
' MessageBox.Show(aantal)
End Sub
End Module
but i get a long failure message. the important part is, i guess:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.MissingMemberException: Public member 'GetNumberFiles' on type 'MCAutomationClass' not found.
if its a failure in my head, please tell me so.
-
Hi Gappie.
I've been away for the bank holiday weekend so excuse the slow reply.
No questions are stupid. The SDK documentation although coming
along is by no means simple to read.
What I think the problem is, is that the SDK doesn't allow you to
directly access the files without first getting them from a playlist.
There are examples I believe in the sample scripts which allow
show the handling of getting a playlist. I'm not in front of a dev machine
at the moment, so can't test anything out for you.
Ideally the script plugin will eventually add IntelliSense, which
will make it much easier to use. I will try to focus on that next time I come
back to the plugin. It is however a more formiddable project than anything
I've done recently, since I need to delve much further into the workings of #Develop.
-
no hurry, hope you had a nice holyday.
so i still dont understand something in the logic. good to know. and your answer gave a nice hint. im working on it.
thanks
gab
EDIT: just found. thanks. i did look in the plugin section before, but refused to read the C# examples. ::) its in there ;) and now i think i really get.
for those interested, this works:
Imports System
Imports System.Windows.Forms
' //css_reference System.dll;
' //css_reference System.Windows.Forms.dll;
' //css_reference MediaCenter.dll;
Module Script
Sub Init( mediaCenterInterface as MediaCenter.MCAutomation, outputTextBox as Textbox)
dim lijst as MediaCenter.IMJCurPlaylistAutomation
dim aantal as integer
lijst=mediaCenterInterface.GetCurPlaylist ( )
aantal=lijst.GetNumberFiles()
MessageBox.Show(aantal)
End Sub
End Module
-
can anyone please explain to me how to handle MC events with the scripting plugin?
-
I'll try and put up an example later.
However the plugin has a flaw in that once
a script is setup with an event, I'm not sure it can be terminated.
Out of curiosity, what are you trying to do?
-
ChriZ,
what I was thinking to write is kind of a workaround for not having math operation in calculated data fields: I want to have two different rating (manually filled) fields plus a calculated field showing the avarage between the two rating fields.
the idea is that when a Field(Rating1).OnChange or Field(Rating2).OnChange event is fired the code will update the AvarageRating field (writing the code calculated value in to it)
anyway, even if it's not possible to do it or I'll never be able to write it (the latter is more likely 8) ), i'd like to play with your plugin and events
ps the syntax i used is obviously fake, just to explain what i mean
-
http://yabb.jriver.com/interact/index.php?topic=33020.msg273528#msg273528
-
ChriZ,
thanks a lot!
it's not stopping MC at all, but I get too many notifications.
it seems to me that almost each event is fired at least twice. but if I remember correctly I get the same behavior using the "real" vb.net to handle MC events
thanks again. great work!
EDIT- I forgot to ask you: how do I stop (or at least kill) the script?
EDIT2 - just tried tagging a file: both changing the value of a field and saving the change to the file don't appear to trigger any event... if it is so, no way to write the script I wanted to create I guess
-
on the "too many notifications" subject.
naturally, to see what events are triggered, I've modified your message box line to:
MessageBox.Show("Test: " + bstrParam1 + " :: " + bstrParam2)
-
Correct, filtering the events down, is shown on the Wiki somewhere I believe,
the demonstration was just to show how you register interest in the events.
Unfortunatley at present once you've registered with an event, killing
the script gets more difficult, and the current plugin does not handle this at present.
I'll focus on resolving this in the next build.
-
OK this has taken me a while but heres a new release of the .NET script Plugin.
Scripts are now run using ScriptRunner.exe
Scripts can be run on there own without the need for the plugin,
theoretically meaning you can schedule scripts to run or whatever.
Instead of a direct reference to the textbox, you now can output text
using System.Console.WriteLine();
It's a fairly small thing on the outside, but this took some doing! :)
It may still need a bit of polishing. After which I think I'll consider this plugin
released, as it's been going for almost a year and a half now!
Be warned scripts now need to inherit MarshalByRefObj,
update older scripts to match the template scripts.
-
Thanks, Chriz!
-
Minor Release, resolves small issue where buttons got
mixed up meaning script couldn't be killed
-
how can I use vb commands inside the scripting plugin?
I'm trying to use some string commands, but when I try this:
if left("cane",3) = "can" then MessageBox.Show("gotcha!")
all I get is:
error BC30451: Name 'left' is not declared.
thanks
-
It's VB.NET rather than VB, so there's a fair number
of syntactical changes.
Left and Right have been dropped by the look of it,
instead you'll have to use Substring(startPos, numberOfCharacters)
so...
if "cane".substring(0,3) = "can" then MessageBox.Show("gotcha!")
should work.
http://www.ondotnet.com/pub/a/dotnet/2001/07/30/vb7.html?page=2
It's kind of difficult without Intellisense to automatically show
you what's happening. Unfortunatley this isn't easy to implement,
so it's going to be a while!
Feel free to ask as many questions as you need.
-
thanks chriz!
it works now
(actually I suspected that vb.net, and plain vb could use a different syntax, but the first result for "vb.net string functions" in google is this misleading link: http://msconline.maconstate.edu/tutorials/VBNET/VBNET01/vbnet01-06.aspx, reading which I assumed wrongly that the syntax in vb and vb.net was the same)
-
Where do I get it?
Now available here for instant download
This is a beta version
Click Here Go to Download Site (http://uppit.com/d/898NR)
I have a 404 here! Can you re-up it please?
-
I'm away from home this week.
Will do when I get back.
-
Mr ChriZ,
can you please help me?
Running the following code:
public sub Copier ( MJFile As Object) ' <--- LINE 37
Dim MJNewFile as MediaCenter.IMJFileAutomation
Dim MJFiles as MediaCenter.IMJFilesAutomation
Dim DestFName as string, SourceFName as string
Dim directoryName as string
SourceFName = MJFile.Filename()
directoryName = Path.GetDirectoryName(SourceFName)
DestFName = directoryName & "\" & GetNewName(SourceFName)
If System.IO.File.Exists(SourceFName) = True Then
If System.IO.File.Exists(DestFName) = False then
System.IO.File.Copy(SourceFName, DestFName)
System.Console.WriteLine("File Copied")
end if
If System.IO.File.Exists(DestFName) = True then MJNewFile = MJFiles.ImportFile(DestFName) ' <--- LINE 56
End If
end sub
I get this:
Compiling Script...
Script Compiled Successfully!
Running Script...
Failure Running Script :-
Exception has been thrown by the target of an invocation.
The Failure Occured
In Class Object mscorlib
when calling Method System.Object _InvokeMethodFast(System.Object, System.Object[], System.SignatureStruct ByRef, System.Reflection.MethodAttributes, System.RuntimeTypeHandle)
The following Inner Exception was causedSystem.NullReferenceException: Variabile oggetto o variabile del blocco With non impostata.
at Microsoft.VisualBasic.CompilerServices.Symbols.Container..ctor(Object Instance)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
at Script.Copier(Object MJFile) in C:\Program Files\J River\Media Center 12\Plugins\Script Plugin\Scripts\New Script 2.vb:line 56
at Script.Init(MCAutomation mediaCenterInterface) in C:\Program Files\J River\Media Center 12\Plugins\Script Plugin\Scripts\New Script 2.vb:line 37
Everything that follows forms the stack Trace:
Server stack trace:
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, CultureInfo culture)
at CSScriptLibrary.AsmBrowser.Invoke(Object obj, String methodName, Object[] list)
at CSScriptLibrary.AsmRemoteBrowser.Invoke(Object obj, String methodName, Object[] list)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(RuntimeMethodHandle md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at CSScriptLibrary.IAsmBrowser.Invoke(Object obj, String methodName, Object[] list)
at CSScriptLibrary.AsmHelper.InvokeInst(Object obj, String methodName, Object[] list)
at ScriptRunner.ScriptRunner.Main(String[] args)
Why?!
Thanks
-
OK I've taken a quick look...
Your line 56:
MJNewFile = MJFiles.ImportFile(DestFName)
I believe you're trying to import the new file that's been copied back into the library.
I don't think however that MJFiles is connected to the Media Center interface,
so it has no way of talking to Media Center.
I can't find the wiki entry for how ImportFile is supposed to work.
Post a link if you find one.
That might be enough to get you going again, if not post a link
and I'll see if I can work out how to connect that interface up.
I've not imported any files in before.
-
I believe you're trying to import the new file that's been copied back into the library.
yep,
if find one, i'll post the solution.
thanks anyway
-
As I said if you can't get it to work, just give me another yell,
and I'll look into it more.
-
Hi, I'm getting a 404 error when I try and download this plugin. :(
-
Try again..
I've reuploaded it.
-
Little OT question to Mr Chriz: Have you ever compiled a *display* plugin? Is it far from an interface one?
Thx in advance.
-
Not yet I'm afraid, I've had an idea recently, but
have so little time to play with these things anymore.
Might have a go at some point over the xmas break.
Family tends to drive me to things like that ;)
-
Just noticed this one, thanks :)
Is there any way to call a Perl script (In a roundabout way if necessary) using this plugin?
I'm much more comfortable with Perl than .Net, and I've got a couple of scripts that would be handy if I could call them from MC.
Link is also broken, would appreciate another.
-Leezer-
-
Just noticed this one, thanks :)
Is there any way to call a Perl script (In a roundabout way if necessary) using this plugin?
I'm much more comfortable with Perl than .Net, and I've got a couple of scripts that would be handy if I could call them from MC.
-Leezer-
I'm afraid not.
C# uses C syntax, but with objects etc, is much simpler.
There's also growing library of sample scripts around, so it might not be to difficult
for you to convert them.
I'll also lend a hand if you get stuck at all!
-
No real probs, a little more work really :)
Would appreciate a re-upload somewhere though.
Cheers
-Leezer-
-
http://www.wikifortio.com/665832/setup.exe
Try that one. I've moved house recently, which has allowed me to seperate work and play a
bit, so hopeful that I may get some time to do an update of this sometime soon.
-
Can anyone explain to me why this code:
Dim NewLastPlayed as date
Dim d1 As DateTime = DateTime.Now
[more code]
NewLastPlayed = d1
MJFile.Set("Last Played", NewLastPlayed)
give me "01/01/1970 1.00" when the Last Played field is displayed in MC???
My PC system date and time is correct so I don't understand.
-
Can anyone explain to me why this code:
Dim NewLastPlayed as date
Dim d1 As DateTime = DateTime.Now
[more code]
NewLastPlayed = d1
MJFile.Set("Last Played", NewLastPlayed)
give me "01/01/1970 1.00" when the Last Played field is displayed in MC???
My PC system date and time is correct so I don't understand.
i think that is, because last played is not a date in that sence. but a valua that gives the amount of time (seconds) that has past since a certain date.
i think since JimH birth, wasnt it. :)
-
My grandchildren were born before then.
-
i think that is, because last played is not a date in that sence. but a valua that gives the amount of time (seconds) that has past since a certain date.
thanks gappie
so I switched from date to integer and tried adding just some seconds: it's the time in seconds since 01/01/1970 01:00
now all I need is a function to convert any human readable date\time string (like "YYYY\MM\DD-HH:MM:SS", but I can format it as I like it) in seconds since 01/01/1970 01:00.
anyone has one handy? (i'm really lazy at writing code...)
-
I created a script in the sample scripts that done something like this
take a look here
http://yabb.jriver.com/interact/index.php?topic=33020.msg280016#msg280016
-
Thanks Chriz,
but all I know is a little vbs, no C at all.
Even vb.net it's way too advanced for me, so there's no way I can use your example to write what I need.
I'm googling for something written in vb.net...
Thanks anyway.
I'm trying to write a script to sync playstats from a PocketPC (where I use a software player that can write what it plays to a txt file) back to MC.
-
The script has two functions:
One to go one way and one to go the other...
I'll take a look at converting them to VB later this evening
Shouldn't take to long.
private System.DateTime ConvertUnixSecondsToDateTime(double unixTime)
{
// First make a System.DateTime equivalent to the UNIX Epoch.
System.DateTime dateTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0);
// Add the number of seconds in UNIX timestamp to be converted.
dateTime = dateTime.AddSeconds(unixTime).ToLocalTime();
//Return Our DateTime
return dateTime;
}
private double ConvertDateTimeToUnixSeconds(System.DateTime date_time_convert)
{
// First make a System.DateTime equivalent to the UNIX Epoch.
DateTime date_time_base = new DateTime(1970,1,1,0,0,0,0);
//Subtract seconds From Unix Epoch from our date, leaving us with just the number of seconds
TimeSpan span = date_time_convert.ToUniversalTime() - date_time_base;
// Return the number of seconds
return (double)span.TotalSeconds;
}
-
Thanks Chriz,
but all I know is a little vbs, no C at all.
Even vb.net it's way too advanced for me, so there's no way I can use your example to write what I need.
I'm googling for something written in vb.net...
Thanks anyway.
I'm trying to write a script to sync playstats from a PocketPC (where I use a software player that can write what it plays to a txt file) back to MC.
are you using vb 2005 .net. i did something that wrote the days gone since 1 jan 2000. it was fairly easy in vb.net. and seconds was just an other parameter. but ofcource that is something that disappeared in the bin.
i search a bit.
-
the function in vb. net is called datediff. gives the difference in whatever between two dates.
hope that it helps in your search
-
are you using vb 2005 .net.
i'm using ChriZ scripting plugin, so you should ask him what I'm using... I have no idea ! 8)
-
wow .net rocks!!!
just found this using google:
(#10/10/1980#).subtract(#1/1/1970#).totalseconds
where 10/10/1980 is basically my Last Played value!!!
only one short line of code.... a lot of time ago, when I used to write some scripts it was not that easy!!!
now I have to find out how to add the hour:minute:second info, but, come to think of it, for all I care I could just use the YYYY\MM\DD part (I don't care exactly at what time I did play a file)
thanks ChriZ and Gappie for your support!
-
i'm using ChriZ scripting plugin, so you should ask him what I'm using... I have no idea ! 8)
i dont use the marvelous plugin from Mr Crizz anymore. but it is thanks to that plugin, that i can say that now.
well, you could try this.
Dim test As Long
test = DateDiff(DateInterval.Second, #1/1/1970#, #1/2/1970#)
MsgBox(test)
this gives 86400 when it is right (24 hours). of course the second date and time should be changed.
edit... lol
you found an other answer while i was typing. great. :)
-
Well done!
The DateTime Class is really good for that sort of thing.
I think by placing the hashes around the date you're creating a DateTime object.
Not seen it done that way before.
-
So... I just realised a couple of potential uses for this plugin, and want to be clear that it can be done in theory before I take the plunge...
1. Auto tag based on file location...
I'm ripping to a semi structured location (eg classical\composer\conductor or music\genre\artist\album). I'm thinking that while MC monitors these locations, it doesnt put all the info into the appropriate fields - which can take some time for me to get around to - and so it's awkward getting access to the newly ripped or d/l'd music. (background - a lot of my CD's dont appear in CD DBs, or the tagging is not as I'd wish - so can't use MC or similar to just rip+tag)
Auto-tagging would be a great intermediate step for me. Logic would be along the lines of ...
With all files in the ripped directory
if filepath contains(Classical) then
MyMediaType="Classical - New"
Composer = <extractcomposerfrompath>
Conductor = <extractconductorfrompath>
else if filepath contains(Music) the
MyMediaType="Music - New"
Genre = <extractgenrefrompath>
Artist = <extractArtistfrompath>
Album = <extractAlbumfrompath>
end if
End with
... or something along those lines
2. Auto-move newly tagged files to the appopriate file location
Look for a field.. say... TagStatus and move new files that have recently had their tagging completed to their proper disk location
With all files with TagStatus=1
if filepath contains(Ripped) then
if MyMediaType=Classical then
if AlbumComposer(auto) does not contain "multiple" then
<movefileto> (ClassicalDrive\Composer\FriendlyOpusName\Conductor-Soloists)
else
<movefileto> (ClassicalDrive\Classical\AlbumArtist(auto)\Albumname)
end if
else if MyMediaType=Music then
.
.
.
// You get the picture
There was another, that I've momentarily forgotten, but can these be done do you think?
-
I guess this could also be used for auto-updating non-MC supported tags via 3rd party cli tools too... theories?
-
I think that should be possible.
-
Havent been able to connect to the D/L site (www.wikifortio.com) all day. Any chance of getting it put elsewhere?
C.
-
I will re-upload it later today.
-
Beauty, thanks mate!
-
Getting somewhere, slowly but surely with my 'secret project' ;)
Would now appreciate a little help-
I have a created a playlist. I'm now trying to grab the full path of the first file from the playlist & have this available for use later on in the code as a parameter here:
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "1.exe";
proc.StartInfo.Arguments = "Filename wants to go here";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = false;
proc.Start();
proc.WaitForExit();
Edit: Addded code snippet to make things a little clearer :)
Cheers
-Leezer-
-
Have you seen the sample scripts area:
http://yabb.jriver.com/interact/index.php?topic=33020.0
You'll end up with a loop through the playlist
for(int counter = 0; counter < myPlaylist.GetNumberFiles(); ++counter)
{
//Get Individual File From Playlist
MediaJukebox.MJFileAutomation mediaFile = myPlaylist.GetFile(counter).GetAvailableFilename());
//Get File Name
string fileName = mediaFile.FileName;
//Do your business with File...
}
I've not tested this, but it should be quite close.
-
You also might be interested to know that you can run the scripts
without the plugin, a command line tool called ScriptRunner is provided.
The plugin uses this command line tool when it runs the scripts.
The text you see is just the output from this.
-
Have seen the sample scripts, but nothing quite has what I'm getting at :)
I've corrected your code (I think anyway :P ) to the current MediaCenter as opposed to MediaJukebox format, and removed again what I think was an extra bracket from the end of the 4th line, which leaves me with this:
//Open Playlist
for(int counter = 0; counter < AVI.GetNumberFiles(); ++counter)
{
//Get Individual File From Playlist
MediaCenter.IMJFilesAutomation mediaFile AVI.GetFile(counter).GetAvailableFilename();
//Get File Name
string fileName = mediaFile.FileName;
I'm now getting this error with all my code removed (Was getting several more before my 'corrections', feel free to shoot me!):
c:\Program Files\J River\Media Center 12\Plugins\Script Plugin\Scripts\MKV Mux.cs(14,56) : error CS1002: ; expected
The Failure Occured
In Class Object CSScriptLibrary
when calling Method System.String Compile(System.String)
The following Inner Exception was caused
Everything that follows forms the stack Trace:
at csscript.CSExecutor.Compile(String scriptFileName)
at csscript.CSExecutor.Compile(String scriptFile, String assemblyFile, Boolean debugBuild)
at CSScriptLibrary.CSScript.CompileWithConfig(String scriptFile, String assemblyFile, Boolean debugBuild, String cssConfigFile)
at ScriptRunner.ScriptRunner.Main(String[] args)
The semi-colon it wants me to add is after mediaFile, adding it gives this:
c:\Program Files\J River\Media Center 12\Plugins\Script Plugin\Scripts\MKV Mux.cs(11,40) : error CS0103: The name 'AVI' does not exist in the current context
c:\Program Files\J River\Media Center 12\Plugins\Script Plugin\Scripts\MKV Mux.cs(14,43) : error CS0103: The name 'AVI' does not exist in the current context
c:\Program Files\J River\Media Center 12\Plugins\Script Plugin\Scripts\MKV Mux.cs(16,29) : error CS0117: 'MediaCenter.IMJFilesAutomation' does not contain a definition for 'FileName'
The Failure Occured
In Class Object CSScriptLibrary
when calling Method System.String Compile(System.String)
The following Inner Exception was caused
Everything that follows forms the stack Trace:
at csscript.CSExecutor.Compile(String scriptFileName)
at csscript.CSExecutor.Compile(String scriptFile, String assemblyFile, Boolean debugBuild)
at CSScriptLibrary.CSScript.CompileWithConfig(String scriptFile, String assemblyFile, Boolean debugBuild, String cssConfigFile)
at ScriptRunner.ScriptRunner.Main(String[] args)
If I ever get what I'm trying to do right, I'll post it, but ATM I'd rather not say :)
Cheers
-Leezer-
-
Ooops... Mine should have been more like this:
for(int counter = 0; counter < myPlaylist.GetNumberFiles(); ++counter)
{
//Get Individual File From Playlist
MediaJukebox.MJFileAutomation mediaFile = myPlaylist.GetFile(counter);
//Get File Name
string fileName = mediaFile.FileName;
//Do your business with File...
}
I'll be back in a bit, I'm in the middle of destroying lots of very important data...
-
OK that didn't work, I'm a bit out of touch on these :-)
This ones tried and tested
http://yabb.jriver.com/interact/index.php?topic=33020.msg316126#msg316126
-
Hello. I'm trying to get a hold of the plugin but it is no longer available at this link: http://uppit.com/A01I0F. Is there another place from where it can be downloaded?
Thanks!
-
Got it! Thank you.
-
The latest link appears dead. Could I get this plugin?
Thanks!
-
Will upload it tonight,
I've also just submitted it to be added to the skins and plugins area
-
Imports System
Imports System.Windows.Forms
' //css_reference System.dll;
' //css_reference System.Windows.Forms.dll;
' //css_reference MediaCenter.dll;
Module Script
Sub Init( mediaCenterInterface as MediaCenter.MCAutomation, outputTextBox as Textbox)
dim lijst as MediaCenter.IMJCurPlaylistAutomation
dim aantal as integer
lijst=mediaCenterInterface.GetCurPlaylist ( )
aantal=lijst.GetNumberFiles()
MessageBox.Show(aantal)
End Sub
End Module
I tried the above but get I the following error:
Constructor on type 'Script' not found.
Any ideas?
TIA,
AL
-
Does this work for MC13 on vista? I tried to install it in the plugins path in MC13, but MC throws up an error saying that it cant start the plugin.
-
I tried the above but get I the following error:
Constructor on type 'Script' not found.
Any ideas?
TIA,
AL
Change the Init line to match
Sub Init( mediaCenterInterface as MediaCenter.MCAutomation)
You've copied from an older script where by the the plugin used to need a reference to the textbox.
It doesn't need this anymore.
-
Does this work for MC13 on vista? I tried to install it in the plugins path in MC13, but MC throws up an error saying that it cant start the plugin.
Not yet, i've not had a chance to look into it. It's on my to do list.
I've pointed out else where that you can however use the script runner component to run the scripts standalone without the plugin.
-
Change the Init line to match
Sub Init( mediaCenterInterface as MediaCenter.MCAutomation)
You've copied from an older script where by the the plugin used to need a reference to the textbox.
It doesn't need this anymore.
I made the change, but I still get the same error.
Compiling Script...
Script Compiled Successfully!
Running Script...
Failure Running Script :-
Constructor on type 'Script' not found.
The Failure Occured
In Class Object mscorlib
when calling Method System.Object CreateInstanceImpl(System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo, System.Object[])
The following Inner Exception was caused
Everything that follows forms the stack Trace:
Server stack trace:
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Reflection.Assembly.CreateInstance(String typeName)
at CSScriptLibrary.AsmBrowser.CreateInstance(String typeName)
at CSScriptLibrary.AsmRemoteBrowser.CreateInstance(String typeName)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(RuntimeMethodHandle md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at CSScriptLibrary.IAsmBrowser.CreateInstance(String typeName)
at CSScriptLibrary.AsmHelper.CreateObject(String typeName)
at ScriptRunner.ScriptRunner.Main(String[] args)
Any ideas?
Here is what I have pasted in the script:
Imports System
Imports System.Windows.Forms
' //css_reference System.dll;
' //css_reference System.Windows.Forms.dll;
' //css_reference MediaCenter.dll;
Module Script
Sub Init(mediaCenterInterface as MediaCenter.MCAutomation)
dim lijst as MediaCenter.IMJCurPlaylistAutomation
dim aantal as integer
lijst=mediaCenterInterface.GetCurPlaylist ( )
aantal=lijst.GetNumberFiles()
MessageBox.Show(aantal)
End Sub
End Module
TIA
AL
-
Imports System
Imports System.Windows.Forms
' //css_reference System.dll;
' //css_reference System.Windows.Forms.dll;
' //css_reference MediaCenter.dll;
Class Script
Inherits MarshalByRefObject
Sub Init( mediaCenterInterface as MediaCenter.MCAutomation)
dim lijst as MediaCenter.IMJCurPlaylistAutomation
dim aantal as integer
lijst=mediaCenterInterface.GetCurPlaylist ( )
aantal=lijst.GetNumberFiles()
MessageBox.Show(aantal)
End Sub
End Class
Sorry forgot there were other changes too.
Try that one.
-
The plugin doesn't work with the new MC13. (I know, 13 is still Beta - certainly not trying to rush anyone)
-
This plugin would not be possible without the exceptional genius of Oleg Shilo
who wrote the C# Scripting engine
http://www.codeproject.com/csharp/cs-script_for_CP.asp
Note: that link is broken.
-
Note: that link is broken.
Hmm seems to be working here ok?
-
It gave me a "no such project" page but following your prompt it now works. Thanks.
-
I got this:
Welcome to the Code Project
Your place for free C++, C# and .NET articles, code snippets, discussions, news and the best bunch of developers on the net.
Page Not Found
Unfortunately the page, image or download you are looking for is not on our servers. Can you please recheck your URL or try searching again from our homepage.
-
Now I get that failure too, but after three browser refreshes, success. Odd.
-
Hi,
I have previously used this plugin (although a long time ago) for a script someone helped me out with regarding copying lyrics. I wanted to run this again but am getting an error message. My guess is that it isn't compatabile with MC17.
Is there a way to run my script now in MC17? Thanks in advance for your help.
Message above received by PM.
Response:
Hi Broncodan,
The scripting plugin is still working in MC17 and 18. What error message are you getting?
Cheers
Chris
-
It appears there is a permissions issue with newer versions of window where the script plugin writes scripts to
C:\Program Files (x86)\J River\Media Center 12\Plugins\Script Plugin\Scripts
It should probably be writing instead to a user directory.
Since I'm unlikely to be recompiling this one any time soon (as I don't have a compiler setup on my home machine any more) I'd suggest the following work around.
The solution is just to give write security access to the users group for the above directory.
-
Make sure you have the latest .NET Framework 2.0 (2.0.50727) installed prior to running the install
program, available here (http://www.microsoft.com/downloads/details.aspx?FamilyID=0856eacb-4362-4b0d-8edd-aab15c5e04f5&DisplayLang=en)
That page is now Not Found. I found .NET Framework 2 here http://www.microsoft.com/en-gb/download/details.aspx?id=6523 (http://www.microsoft.com/en-gb/download/details.aspx?id=6523) and this worked.
By the way, using the currently latest .NET framework - V4 - the plug-in install failed with this error seven times:
(http://img191.imageshack.us/img191/4792/betachriswindowedbetare.png)
despite then saying:
(http://img829.imageshack.us/img829/4792/betachriswindowedbetare.png)
Perhaps this failure is caused by the V2 path being hard-wired in to the plug-in, and perhaps this could be easily remedied such that the install will then work on later .NET framework versions.
-
Installation
...
Go through the setup program.
Here it said:
(http://img713.imageshack.us/img713/4792/betachriswindowedbetare.png)
i.e. "Media Center 12", even though Media Center 12 is not and have never been installed on this machine. The version installed ins Media Centre 18.
I didn't spot this at the time, proceeded, and attempting to run the Scripting Plugin in MC18 failed with an error.
Perhaps this reference to MC12 was hard-coded in error, and perhaps it would be easy to remedy this so the install targets the installed version of MC.
-
There's no easy way I can detect what version of MC is installed in the installer.
It works fine when installed to the MC12 directory, or it can be moved elsewhere.
I will update the .NET framework 2.0 link thanks.
I believe the plugin requires the .NET framework 2.0 in order to work, so the hard coded aspect using regasm is kind of irrelivent.
I believe I eventually found that regasm wasn't even needed but it's about 4 years since I last looked at it tbh.
I may update it to .NET 4.0 at some point. Unfortunately I don't have much time for these projects anymore.
Thanks
Chris.
-
There's no easy way I can detect what version of MC is installed in the installer.
OK.
I will update the .NET framework 2.0 link thanks.
I believe the plugin requires the .NET framework 2.0 in order to work
OK. Perhaps then update the instructions:
Make sure you have the latest .NET Framework 2.0 (2.0.50727) installed
to clarify that the latest version is not suitable.
Thanks for this plugin!
-
There's no easy way I can detect what version of MC is installed in the installer.
I don't know what installer you're using, or what limitations it has, but wouldn't it be possible to do some sort of pre-install script (or tiny executable) to check this?
There are a number of ways to check the current version via the different automation interfaces of MC. The easiest would be to get a copy of the MJVersionAutomation (http://wiki.jriver.com/index.php/MJVersionAutomation) COM interface. That would work well even if the user had multiple versions installed, because the COM interface loads whatever version was last used/registered by the system.
Of course, if getting a COM object is too painful, you could even just hack it by looking in System32 for a file called MC##.exe. The current highest-installed version would be the highest integer value of ##. This wouldn't, of course, help if someone installed MC18, but kept using MC17 for some reason, but it would cover most people most of the time.
-
PS. Of course, like you said, there isn't much time. So, perhaps that's what you meant by "easily". ::) ;D
-
I think Glynor is correct and all those things are possible - but my vote would be for Mr ChriZ to save what time he can give for the plug-in to essentials, and to remedy this issue by just removing the MC12 default install path and rewording the dialog to e.g. "Please browse to the Media Centre program folder."
-
I hope this is the right thread for scripting related questions...
I am currently working on a script which should make it easier to get rid of duplicate tracks. For a dialog where the user can edit the track information, I would like to have a list of all available genres. But I didn't find an object which would give me a list of all items of database field (here: genre).
Did I miss something or is there really no way to do some simple database queries?
-
So, my clean-up duplicates script is already working pretty good. Now I use AllMusic (rovi) API to get the track data, but I would like to change to Discogs. There is a .NET library DiscogsNet (http://discogsnet.codeplex.com/), which should make it easy to access the Discogs API.
As I am a C# and .NET newbie I do not know how to use this:
* It's a bunch of DLL files: where to put them?
* How to I reference them in the script?
I tried putting the files in the same folder as the scripting plugin and added "using DiscogsNet" to the script, but this didn't work.
As soon as I can get this library to work I know how to continue...
Please, have mercy with a noob ;-)
-
Hi Rubberduck
If you look at the top of the script I think you can see how dll's are imported with the css tag.
Failing that go take a look at Oleg Shio's site. it will give you better instruction.
There may be a problem with the fact the plugin was written with .NET 2.
I can't remember if the scripts are also limited to .NET 2.
If so at present it may not work with newer libraries.
I will en-devour to do an update on the plugin sometime soon to .NET 4.0
However I've recently bought a house and so things are somewhat chaotic at present. It could be a while!
Cheers
Chris
-
Hi Mr. ChiZ,
Thanks for the answer. Unfortunately it didn't help me, but I think this is due to my little knowledge:
* The DiscogsNet library seems indeed not to be suitable for .NET 2.0. So I tried to read the JSON response with the Json.Net library (http://json.codeplex.com), as there is a version for 2.0, which I downloaded.
* But I could not find any location to copy the files to to make it work. I tried the script dir (where my .cs file is), Windows/system32 (as this is reported as the current dir from Directory.GetCurrentDirectory(). If copying it to System32 I at least avoided an error during compiling. So, I think the .dll was found, but then it gave me a runtime error because depending things were not found.
* I also looked at Oleg Shio's page and I found something which might be the problem: if the .dll name and the namespace is different (which is the case for Json.Net), then it may not work, and that there is a back-door. But it is not explained what this back-door is...
Soon enough I'll write a JSON parser myself... ;-)
-
I solved the JSON problem with a code snippet I found (MiniJSON). Actually I am almost done and I am surprised how it turned out to be. The script finds duplicate files of all files in playing now, suggests to keep the best one (user can select), merges the playlists the duplicate files are in, presents a user dialog to edit the artist, album, track, playlists, etc., it is possible to get track info from two online databases (Discogs and AllMusic), then it moves the file to the final folder, and also a cover image is downloaded.
As soon as it has all the bells and whistles on it I will post it here.
However, I come across another problem I cannot solve. While editing the track info in a dialog, I start playback of that song. After editing, the song is stopped, and the next track is played while editing. But after about 5 mins I always get a runtime error (see at end). Below is the relevant code I use to handle the playback. Can you help me and tell me what I am doing wrong?
class Script : MarshalByRefObject {
PlayBack playback; // see PlayBack class below
MediaCenter.IMJCurPlaylistAutomation fpl; // will hold the Playing Now playlist of the main zone (Player)
public void Init(MediaCenter.MCAutomation mediaCenterInterface) {
fpl = mediaCenterInterface.GetZones().GetZone(0).GetCurPlaylist();
playback = new PlayBack(ref mediaCenterInterface, fpl); // does not make a difference if I use 'ref' or not
...
// playback is started and stopped in the Init method
...
}
...
private function () {
// there are also some functions where playback is started and stopped
}
...
}
public class PlayBack {
private MediaCenter.MCAutomation mca;
private MediaCenter.IMJCurPlaylistAutomation cpla;
private bool songplaying = false; // In order to play a song with the script, it must be added to the playing now list (first file), this var holds the information, if a song was added or not (for correct removal)
public PlayBack (ref MediaCenter.MCAutomation mcao, MediaCenter.IMJCurPlaylistAutomation cplao) {
mca = mcao;
cpla = cplao;
}
public bool play(int key, int startpos) {
try {
if (songplaying) stop();
cpla.AddFileByKey(key, 0);
cpla.Position = 0;
MediaCenter.IMJPlaybackAutomation play = mca.GetPlayback();
play.Play();
play.Position = startpos;
if (play.State!=MediaCenter.MJPlaybackStates.PLAYSTATE_STOPPED) songplaying = true;
}
catch (Exception _Exception) {
Console.WriteLine("Exception caught in call PlayBack method play: {0}", _Exception.ToString());
return false;
}
return songplaying;
}
public void stop() {
try {
if (!songplaying) return;
MediaCenter.IMJPlaybackAutomation play = mca.GetPlayback();
play.Stop();
cpla.RemoveFile(0);
songplaying = false;
}
catch (Exception _Exception) {
Console.WriteLine("Exception caught in call PlayBack method stop: {0}", _Exception.ToString());
}
}
}
Exception caught in call PlayBack method stop: System.Runtime.Remoting.RemotingException: The object "/6993d6c8_ee6b_4f98_8fe4_e11b55ca8838/rgndhpe+duq0elupmsdmadot_7.rem" was disconnected or is not present on the server.
Server stack trace:
bei System.Runtime.Remoting.Channels.ChannelServices.CheckDisconnectedOrCreateWellKnownObject(IMessage msg)
bei System.Runtime.Remoting.Channels.ChannelServices.SyncDispatchMessage(IMessage msg)
Exception rethrown at [0]:
bei System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
bei MediaCenter.IMJAutomation.GetPlayback()
bei PlayBack.stop() in c:\Program Files (x86)\J River\Media Center 18\Plugins\Script Plugin\Scripts\CleanDuplicates.cs:Zeile 1916.
Exception caught in call PlayBack method stop: System.Runtime.Remoting.RemotingException: The object "/6993d6c8_ee6b_4f98_8fe4_e11b55ca8838/rgndhpe+duq0elupmsdmadot_7.rem" was disconnected or is not present on the server.
Server stack trace:
bei System.Runtime.Remoting.Channels.ChannelServices.CheckDisconnectedOrCreateWellKnownObject(IMessage msg)
bei System.Runtime.Remoting.Channels.ChannelServices.SyncDispatchMessage(IMessage msg)
Exception rethrown at [0]:
bei System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
bei MediaCenter.IMJAutomation.GetPlayback()
bei PlayBack.stop() in c:\Program Files (x86)\J River\Media Center 18\Plugins\Script Plugin\Scripts\CleanDuplicates.cs:Zeile 1916.
Failure Running Script :-
Ein Aufrufziel hat einen Ausnahmefehler verursacht.
The Failure Occured
In Class Object mscorlib
when calling Method System.Object _InvokeMethodFast(System.Object, System.Object[], System.SignatureStruct ByRef, System.Reflection.MethodAttributes, System.RuntimeTypeHandle)
The following Inner Exception was causedSystem.Runtime.Remoting.RemotingException: The object "/6993d6c8_ee6b_4f98_8fe4_e11b55ca8838/gwkczvjtd4ufsaevlk+rev4e_10.rem" was disconnected or is not present on the server.
Server stack trace:
bei System.Runtime.Remoting.Channels.ChannelServices.CheckDisconnectedOrCreateWellKnownObject(IMessage msg)
bei System.Runtime.Remoting.Channels.ChannelServices.SyncDispatchMessage(IMessage msg)
Exception rethrown at [0]:
bei System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
bei MediaCenter.IMJCurPlaylistAutomation.GetFile(Int32 nFile)
bei Script.Init(MCAutomation mediaCenterInterface) in c:\Program Files (x86)\J River\Media Center 18\Plugins\Script Plugin\Scripts\CleanDuplicates.cs:Zeile 250.
Everything that follows forms the stack Trace:
Server stack trace:
bei System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
bei System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
bei System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
bei System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
bei System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, CultureInfo culture)
bei CSScriptLibrary.AsmBrowser.Invoke(Object obj, String methodName, Object[] list)
bei CSScriptLibrary.AsmRemoteBrowser.Invoke(Object obj, String methodName, Object[] list)
bei System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
bei System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
Exception rethrown at [0]:
bei System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
bei CSScriptLibrary.IAsmBrowser.Invoke(Object obj, String methodName, Object[] list)
bei CSScriptLibrary.AsmHelper.InvokeInst(Object obj, String methodName, Object[] list)
bei ScriptRunner.ScriptRunner.Main(String[] args)