Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Foobar2000 IPC (Read 6016 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Foobar2000 IPC

I didn't find anything that worked on the newest version in terms of foobar2000 ipc. winamp_ipc and comserver were both old and burried from what I could tell. So were the threads about this topic so I decided to register and post a new one. I hope this thread is in the right place.

I came up with this method:
http://shadow.vs-hs.org/library/article.php?id=40

The code samples are obviously in Visual Basic but it should be easy to translate to any language. No code download is available at this moment.

HTH

Foobar2000 IPC

Reply #1
Sorry if this might sound ignorant, but i see you're finding the exe, the installdir and then combining it all into "..\foobar2000.exe /command:somecommand".     

Is there any advantage of using messages instead of Process.Start("foobar2000.exe", "/command:somecommand")  ?

This is just out of interest. Since i think that achieves same functionality (at least what's in the example code) and truncates the code to a single line.


Foobar2000 IPC

Reply #2
Sorry if this might sound ignorant, but i see you're finding the exe, the installdir and then combining it all into "..\foobar2000.exe /command:somecommand".     

Is there any advantage of using messages instead of Process.Start("foobar2000.exe", "/command:somecommand")  ?

This is just out of interest. Since i think that achieves same functionality (at least what's in the example code) and truncates the code to a single line.


The reason why I did not want to go for Process.Start() was because, say when I adjust volume, it will create what... 10 new processes just to adjust the volume 10 times? But yes the end result is the same, just without the process spam.

Foobar2000 IPC

Reply #3
I understand the supposed overhead of creating a new process for each volume increment, but i think foobar2000 uses minimal of code to see if it's running and then passing the args to the main window and quiting the additional process anyway. Also volume increment might not be the best example in this case, since foobar has global shortcuts for that which you could also emulate i think.     

But i see your point


Foobar2000 IPC

Reply #4
I understand the supposed overhead of creating a new process for each volume increment, but i think foobar2000 uses minimal of code to see if it's running and then passing the args to the main window and quiting the additional process anyway. Also volume increment might not be the best example in this case, since foobar has global shortcuts for that which you could also emulate i think.     

But i see your point


Correct again. However, a lot of processes these days seem to block media keys. The keypresses do not always make it to f2k. I have created this program that takes care of the problem for me, and thus needed foobar2000 to play ball with it. My application currently fixes this "bug" on:

Battlefield 1942
Adobe Flash Plugin (youtube etc.)
Libre and Open Office
Skyrim

Edit: and those are just the processes I have problems with, I'm sure there is a lot more of them out there. Fixing the problem with my app is a matter of checking a checkbox.

Foobar2000 IPC

Reply #5
I have tryed to copy your interesting script in a "test.vbs" file and execute with cscript "test.vbs" but i have error.
How to use?
Code: [Select]
Private Foobar2000InstallDir As String = "" ' = HKLM\SOFTWARE\SOFTWARE\Wow6432Node\foobar2000\InstallDir
Private Foobar2000Exe As String = "" ' = Path.Combine(Foobar2000InstallDir,"foobar2000.exe")

Imports System.Runtime.InteropServices

Public Class WINAPI
<StructLayout(LayoutKind.Sequential)> _
Public Structure COPYDATASTRUCT
Public dwData As IntPtr
Public cbData As Int32
Public lpData As IntPtr
End Structure

Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr

Public Const WM_COPYDATA As Int32 = &H4A
End Class

Private Function FoobarPostMessage(cmd As String) As Boolean
cmd = cmd & Chr(0) & Foobar2000InstallDir & Chr(0)
Dim hWnd As IntPtr = WINAPI.FindWindow("{75D55AF6-03A2-457a-9933-D4EC2CB25684}", Nothing)
If hWnd = IntPtr.Zero Then Return False
Dim cds As WINAPI.COPYDATASTRUCT
Dim lpcds As IntPtr
Dim lpcmd As IntPtr = Marshal.StringToHGlobalAnsi(cmd)
cds.dwData = New IntPtr(1)
cds.lpData = lpcmd
cds.cbData = cmd.Length
lpcds = Marshal.AllocHGlobal(Marshal.SizeOf(cds))
Marshal.StructureToPtr(cds, lpcds, False)
WINAPI.SendMessage(hWnd, WINAPI.WM_COPYDATA, IntPtr.Zero, lpcds)
Marshal.FreeHGlobal(lpcmd)
Marshal.FreeHGlobal(lpcds)
Return True
End Function

Select Case PressedKey
Case Keys.MediaPlayPause
FoobarPostMessage(Foobar2000Exe & " /play")
Case Keys.MediaStop
FoobarPostMessage(Foobar2000Exe & " /stop")
Case Keys.MediaNextTrack
FoobarPostMessage(Foobar2000Exe & " /next")
Case Keys.MediaPreviousTrack
FoobarPostMessage(Foobar2000Exe & " /prev")
Case Keys.VolumeUp
FoobarPostMessage(Foobar2000Exe & " /command:up")
Case Keys.VolumeDown
FoobarPostMessage(Foobar2000Exe & " /command:down")
End Select

Foobar2000 IPC

Reply #6
It Visual Basic (.vb), not Visual Basic Script (.vbs)
It's not that you can't make it in VBS, but isn't Shpeck handling this Winamp mode for you?


Foobar2000 IPC

Reply #8
It Visual Basic (.vb), not Visual Basic Script (.vbs)
It's not that you can't make it in VBS, but isn't Shpeck handling this Winamp mode for you?


It seemed like Shpeck (wasn't that the one with the visualization wrapper?) did a lot more than just play,pause,next,previous etc. I was looking for a simpler solution.

It Visual Basic (.vb), not Visual Basic Script (.vbs)

also in vbs it return error 800A0401


As romor said, the code is written in Visual Basic .NET, not VBS. The difference should not be significant (?) but I can't help you with any errors as I have never used vbs.

You need to fill in the values for these variables. The comments at the end of the line hint at what the values are supposed to be.
Private Foobar2000InstallDir As String = "" ' = HKLM\SOFTWARE\SOFTWARE\Wow6432Node\foobar2000\InstallDir
Private Foobar2000Exe As String = "" ' = Path.Combine(Foobar2000InstallDir,"foobar2000.exe")

The Select statement "Select Case PressedKey" needs to be inside a function. The "PressedKey" variable is of type System.Windows.Forms.Keys. In my application the PressedKey value comes from my keyboard hook.

Foobar2000 IPC

Reply #9
It seemed like Shpeck (wasn't that the one with the visualization wrapper?) did a lot more than just play,pause,next,previous etc. I was looking for a simpler solution.


Yes, of course, I was just trying to help him if he needs functionality

VBS is totally different from VB.NET. It runs on any Windows machine, it's interpreted and has different syntax etc. It's not trivial to translate your script but it can be made if someone has skills and desire to do it

Foobar2000 IPC

Reply #10
It seemed like Shpeck (wasn't that the one with the visualization wrapper?)

what it is Shpeck?

As romor said, the code is written in Visual Basic .NET, not VBS. The difference should not be significant (?) but I can't help you with any errors as I have never used vbs.


i rewrite script but not work
Code: [Select]
Private Foobar2000InstallDir As String = "c:\Programmi\Foobar2000" ' = HKLM\SOFTWARE\SOFTWARE\Wow6432Node\foobar2000\InstallDir
Private Foobar2000Exe As String = "foobar2000.exe" ' = Path.Combine(Foobar2000InstallDir,"foobar2000.exe")

Imports System.Runtime.InteropServices

Public Class WINAPI
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure COPYDATASTRUCT
        Public dwData As IntPtr
        Public cbData As Int32
        Public lpData As IntPtr
    End Structure

    Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr

    Public Const WM_COPYDATA As Int32 = &H4A
End Class

Private Function FoobarPostMessage(cmd As String) As Boolean
        cmd = cmd & Chr(0) & Foobar2000InstallDir & Chr(0)
        Dim hWnd As IntPtr = WINAPI.FindWindow("{75D55AF6-03A2-457a-9933-D4EC2CB25684}", Nothing)
        If hWnd = IntPtr.Zero Then Return False
        Dim cds As WINAPI.COPYDATASTRUCT
        Dim lpcds As IntPtr
        Dim lpcmd As IntPtr = Marshal.StringToHGlobalAnsi(cmd)
        cds.dwData = New IntPtr(1)
        cds.lpData = lpcmd
        cds.cbData = cmd.Length
        lpcds = Marshal.AllocHGlobal(Marshal.SizeOf(cds))
        Marshal.StructureToPtr(cds, lpcds, False)
        WINAPI.SendMessage(hWnd, WINAPI.WM_COPYDATA, IntPtr.Zero, lpcds)
        Marshal.FreeHGlobal(lpcmd)
        Marshal.FreeHGlobal(lpcds)
        Return True
End Function

Public Function tasti()
    Private PressedKey As System.Windows.Forms.Keys
    Select Case PressedKey
            Case Keys.MediaPlayPause
                    FoobarPostMessage(Foobar2000Exe & " /play")
            Case Keys.MediaStop
                    FoobarPostMessage(Foobar2000Exe & " /stop")
            Case Keys.MediaNextTrack
                    FoobarPostMessage(Foobar2000Exe & " /next")
            Case Keys.MediaPreviousTrack
                    FoobarPostMessage(Foobar2000Exe & " /prev")
            Case Keys.VolumeUp
                    FoobarPostMessage(Foobar2000Exe & " /command:up")
            Case Keys.VolumeDown
                    FoobarPostMessage(Foobar2000Exe & " /command:down")
    End Select
End Function


cscript "k:\fb2k.vbs"



Foobar2000 IPC

Reply #13
1) You need to set Foobar2000Exe to InstallDir & "\foobar2000.exe". So in your case it would be "c:\Programmi\Foobar2000\foobar2000.exe".
2) Your tasti function needs to set a value for PressedKey, such as Keys.MediaPlayPause. Private PressedKey As System.Windows.Forms.Keys = Keys.MediaPlayPause.

Other than that it looks good.

Foobar2000 IPC

Reply #14
Great post!
how you have found the the string in WM_COPYDATA lpData?
Spy++ not show it.

Foobar2000 IPC

Reply #15
Great post!
how you have found the the string in WM_COPYDATA lpData?
Spy++ not show it.


Disassembly. Took me 2 days as I wasn't expecting it to use SendMessage and my knowledge of assembly is very limited. Spy++ should be able to see it, however, as it says on my webpage "Note that this is not the actual Foobar2000 window.". Look for a window with the classname {75D55AF6-03A2-457a-9933-D4EC2CB25684}.

Foobar2000 IPC

Reply #16
for me work previous not prev:
Case Keys.MediaPreviousTrack
            FoobarPostMessage(Foobar2000Exe & " /previous")