|
|
#1 |
|
Junior Member
|
Solution: Get FileName from external app/dll
It IS possible!
Some guy wrote the pointers aren´t valid, because every process has its own 32bit memory address block. Thats True, but there are some nice functions which let you access the memory space of another process... I wrote an example how to get the FileName....in Delphi, but the functions should be the same in C or whatever: code: First we get the Winamp handle, as usual. Then we get the actual played track, as usual. Then the Pointer to the Filename (MPointer). This Pointer is not valid in our dll´s process memory. So we need to Read in Winamp´s process memory. ReadProcessMemory(); does this. OpenProcess gives us a new handle, on which we have Read/Write Access. Otherwise we get an EAccessViolation. the filename is stored in dat2. With C there may be some string copy actions necessary. But this should be no problem... I hope i helped some of you "I don´t like a winamp plugin" guys ![]() Heiko S. PS: I wrote a simple example dll for mIRC which puts out the usual stuff on command. (trackname, time, kbps etc..) Any questions about that are welcome. And Sorry for neglecting any existing name conventions
|
|
|
|
|
|
#2 |
|
ist death
Join Date: May 2000
Posts: 3,704
|
yeah, nice. which windows OS did you test that in ?
|
|
|
|
|
|
#3 |
|
Junior Member
|
Windows 2000
So i think for Win95/98/ME/ NT it should work surely. Windows XP...idk (but i may look...tomorrow..) Heiko S. |
|
|
|
|
|
#4 |
|
Junior Member
|
-deleted
|
|
|
|
|
|
#5 |
|
ist death
Join Date: May 2000
Posts: 3,704
|
i was only afraid about win2k and similar, but if it works then it's OK.
|
|
|
|
|
|
#6 |
|
Senior Member
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
|
the probable conversion to vb..... but it doesnt work
Dim hwndWinamp As Long Dim TempHandle As Long Dim dat2 As String * 256 Dim TrackPos As Long Dim temp As Long Dim MPointer As Long Public Const WM_USER = &H400 Public Const PROCESS_VM_READ = &H10 Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long Dim pTemp As Long Dim nTemp As Long Public Function ShowTitle() As String hwndWinamp = FindWindow("Winamp v1.x", vbNullString) TrackPos = SendMessage(hwndWinamp, &H400, 0, 125) MPointer = SendMessage(hwndWinamp, &H400, TrackPos, 211) temp = GetWindowThreadProcessId(hwndWinamp, TempHandle) hwndWinamp = OpenProcess(PROCESS_VM_READ, False, TempHandle) pTemp = lstrcpy(dat2, dat2) nTemp = ReadProcessMemory(hwndWinamp, MPointer, pTemp, 256, temp) temp = CloseHandle(hwndWinamp) ShowTitle = dat2 End Function it shows that the read process memory works, that it copies 256, but all that's in my string is null characters, it doesnt change anything, nothing at all. changing anything around gives me some lovely access violations, the worst being where visual studio disappears without a trace..now if only my frozen programs could do that, anyway, that's where I'm at, any help would be most appreciated, thnx in advance. |
|
|
|
|
|
#7 |
|
Junior Member
|
Hi again,
I don´t know much about VB... But here are some things i found: First I changed my code to equal your VB Code. Old: var dat2: array[0..500] of Char; New: var dat2: PChar; //Pointer to char Now I initialized dat2 in two different way´s. dat2:= PChar('Just a 256 byte long String to hold the Filename..........'); PChar() returns a Pointer to a String; If it´s intialized this way, ReadProcessMemory fails. The output is the original "Just a long enough......" Now I used AllocMem(X: Cardinal), which returns a pointer to X Bytes of Memory. dat:=AllocMem(256); If its done this way, ReadProcessMemory succeeds. Maybe there´s a function like AllocMem in VB? Heiko S. |
|
|
|
|
|
#8 |
|
Senior Member
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
|
Bows down to Heiko
Dim hwndWinamp As Long Dim TempHandle As Long Dim dat2 As String Dim TrackPos As Long Dim temp As Long Dim MPointer As Long Public Const WM_USER = &H400 Public Const PROCESS_VM_READ = &H10 Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long Dim pTemp As Long Dim nTemp As Long Public Function ShowTitle() As String hwndWinamp = FindWindow("Winamp v1.x", vbNullString) TrackPos = SendMessage(hwndWinamp, &H400, 0, 125) MPointer = SendMessage(hwndWinamp, &H400, TrackPos, 211) temp = GetWindowThreadProcessId(hwndWinamp, TempHandle) hwndWinamp = OpenProcess(PROCESS_VM_READ, False, TempHandle) For xn = 1 To 256 dat2 = dat2 & " " Next xn nTemp = ReadProcessMemory(hwndWinamp, MPointer, dat2, 256, temp) temp = CloseHandle(hwndWinamp) ShowTitle = dat2 I was on the right track, I just didnt know it, you see, I was filling it with null characters by making it fixes length, so it would get to the first null and think that was the end of the string, go figure, so I filled it with spaces, the code works, works like a charm, thank you again Heiko. *bows down to you* If anyone remembers the vb command to fill a string with a character, then use that instead of my loop. |
|
|
|
|
|
#9 |
|
Junior Member
Join Date: Apr 2002
Posts: 8
|
The answer is no - documented in frontend.h :
#define IPC_GETPLAYLISTFILE 211 /* (requires Winamp 2.04+, only usable from plug-ins (not external apps)) ** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE); ** ** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index]. ** returns a pointer to it. returns NULL on error. */ notice "not external apps" - sorry bananskib |
|
|
|
|
|
#10 | |
|
Junior Member
|
LOL?
Did you actually read the post´s above? Quote:
![]() These Functions ARE the solution, they work... Ok, I write one for C... *sighs* ![]() Perhaps someone updates the frontend.h? Or the FAQ Page? I´m sure the other "only usable from within winamp´plugin´s" API SendMessages are also usable from external app´s since we are able to freely read/write in winamp´s process memory from an external app too. Anyone who got how OpenProcess, ReadProcessMemory and WriteProcessMemory work, should be able to port it to the other IPC_´s . Heiko S. |
|
|
|
|
|
|
#11 |
|
Junior Member
|
I´m not very used to C too, but this Code works.
code: Maybe someone wants to rewrite it, to make it look nicer ![]() Heiko S. |
|
|
|
|
|
#12 |
|
Junior Member
Join Date: Oct 2001
Posts: 6
|
Hello Gourou, will you post some project sample with your code ?
Tks |
|
|
|
|
|
#13 |
|
Senior Member
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
|
sure, hell, why not, gimme a min to get a sample cobbled together..
|
|
|
|
|
|
#14 |
|
Senior Member
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
|
here, it works fine for me, if it doesnt work correctly for you, then message me
|
|
|
|
|
|
#15 |
|
Senior Member
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
|
bloody hell, cant edit my own upload, that sux, so here's an update, I fixed a bug, it wasnt noticeable, but it was an error, and I dont like errors, even if they get passed by ok. BTW, this is just source code, I didnt bother to compile it
|
|
|
|
|
|
#16 |
|
Junior Member
|
Excellent code!
I know I shouldn't be replying to a post that's 3 months old, but I can't help it. This is an excellent example of being able to pull the current song title/filename from WinAmp, which is exactly what I wanted to do. Even better, it's native VB.
*praise to the NSDN* |
|
|
|
|
|
#17 |
|
Junior Member
|
/me wonders how many vb coders are out there =)
np |
|
|
|
|
|
#18 |
|
Senior Member
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
|
more than you think...
|
|
|
|
|
|
#19 |
|
Junior Member
Join Date: Jul 2002
Posts: 5
|
This thread has made my life 100% better, since now i can get the song names!! No more sleepless nights, yeah!!
I'm a VB coder 2!
|
|
|
|
|
|
#20 |
|
Junior Member
Join Date: Aug 2001
Location: austria
Posts: 42
|
vbcoder
![]() i'm going to reactivate this post since i have a problem i surely get the right title returned but when i want to return some more text afterwards it doesn't work. i guess that's because of the Space(256) does anyone have a clue how to just return a normal string instead of this special string? or how to terminate the string so that i can add normal text after it? heres my code: [quote]Public Function ShowFile() As String On Error Resume Next hWndWinamp = FindWindow("Winamp v1.x", vbNullString) TrackPos = SendMessage(hWndWinamp, WM_USER, 0, 125) MPointer = SendMessage(hWndWinamp, WM_USER, TrackPos, 211) '212 is Title temp = GetWindowThreadProcessId(hWndWinamp, TempHandle) hwndWinampP = OpenProcess(PROCESS_VM_READ, False, TempHandle) Data = Space(256) nTemp = ReadProcessMemory(hwndWinampP, MPointer, Data, 256, temp) pTemp = CloseHandle(hwndWinampP) ShowFile = Trim(Data) End Function[/code] thanks! |
|
|
|
|
|
#21 |
|
Junior Member
|
Sorry, other question:
Is there any WinampAPI in Winamp3 ? I wanted to port this to 3...but didn´t find anything... Heiko S. |
|
|
|
|
|
#22 |
|
Major Dude
Join Date: Jan 2001
Posts: 1,670
|
|
|
|
|
|
|
#23 | |
|
Junior Member
Join Date: Oct 2002
Location: Montreal ,Canada
Posts: 11
|
[QUOTE]Originally posted by quentin
vbcoder ![]() i'm going to reactivate this post since i have a problem i surely get the right title returned but when i want to return some more text afterwards it doesn't work. i guess that's because of the Space(256) does anyone have a clue how to just return a normal string instead of this special string? or how to terminate the string so that i can add normal text after it? heres my code: Quote:
code: |
|
|
|
|
|
|
#24 | |
|
Junior Member
Join Date: Aug 2001
Location: austria
Posts: 42
|
Quote:
i love you ![]() yeah that worked fine ![]() thanks for your help!
|
|
|
|
|
|
|
#25 |
|
Junior Member
Join Date: Oct 2002
Location: Montreal ,Canada
Posts: 11
|
your welcome!You could also use it if your populating a listbox... This was originally a function which I grabbed from Gourou's project but I made it into a sub with a variable for a Listbox. I'm using this in my latest app which works great. My thanks to Gourou for coming up with this neat stuff. I was able to reduce my initial code considerably because of it. Happy coding! ![]() code: |
|
|
|
|
|
#26 |
|
Junior Member
|
You people are beautiful. The DAY I come back to working with the API for VB, you resurrect this post.
Currently, I'm working on a special project that I'll talk about when it's done. It's a stand-alone VB app that communicates with WinAMP (of course)... but it takes a whole new twist. I hope it's well received. |
|
|
|
|
|
#27 | |
|
Junior Member
Join Date: Oct 2002
Location: Montreal ,Canada
Posts: 11
|
Quote:
![]() My web counter is surely proof that that there was a need for such a thing. Funny but of all people I would have thought Nullsoft would have come out with something like this long ago. I mean a front end that you could easily use with your full album folders. Sure there are a few plugins out there that'll let you see the album covers while listening to your tunes but I think most people want a little more interaction than this no? I did... Anyway I'm sure with the huge hard drives coming out on the market nowadays a whole bunch of people are going to start realizing that it's wwwwway more efficient to keep your music collection on your pc than all over the place. I've got over 550 CD'S neatly stored on two separate HD and would never ever go back to listening to my cd's the old way. I don't really feel comfortable about mentioning this here but anyway if you want to try it out here's the link. It's free btw... unless you use it commercially of course http://pages.globetrotter.net/bakery...me_jukebox.htm If you wanta share ideas you can write me at bakerywizard@globetrotter.net Cheers and thanks again to all the forum gurus for not abandoning us... Winamp 2 lovers that is! ![]()
|
|
|
|
|
|
|
#28 |
|
Junior Member
|
That's an excellent idea. Although, it's nowhere close to what I'm doing.
I've decided not to release my app. I would, but I've gotten a second wind on things I can do with it, and unfortunatly, it's becomming more multi-purpose than just WinAMP. When I reach version 2.0, that's when I'll release it as a plugin. Yeah, WinAMP 2 still rocks! I'll never replace it. It'll be one of those things that you've had on your computer for like 11 years... like Temple of Abshai. |
|
|
|
|
|
#29 |
|
Junior Member
|
Back from the dead....
Looks like it's been a few months since anyone's dug this one up from the dead... it's about time to do it again, eh?
I'm working on a class to interact with WinAmp 2.x in VB.NET. I haven't run into any problems so far, so I figured it was about time to tackle the current file issue. Using Gourou's code, I can get the title in VB6 without any issues. However, I'm having a hell of a time rolling it up to .NET. The current issue (I'm sure there's more to follow) is with the OpenProcess API call. Up until that call, I've got VB6 and VB.NET on the same page. However, I can't get the .NET code to return the same value as the VB6 code. I've got the API registered as "Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal dwProcessId As Integer) As Integer". I attempted using GetProcessById in the System.Diagnostics.Process class too, no dice. Any ideas? Anyone tried this yet? Thanks for any assistance... syph |
|
|
|
|
|
#30 |
|
Junior Member
Join Date: Oct 2003
Posts: 9
|
Big Thank You for HeikoSS & Gourou!
A nice VB wrapper for using your methods & a hack to use restricted stringbuffers,can be found at http://forums.winamp.com/showthread....hreadid=157836 |
|
|
|
|
|
#31 | |
|
Junior Member
Join Date: Mar 2004
Location: Pretoria
Posts: 4
|
Quote:
Here is my C code, using MFC, I used a dialog box just to test: code: |
|
|
|
|
|
|
#32 |
|
Junior Member
Join Date: Mar 2004
Posts: 2
|
Urgent!!! How to get filename in fullpath
Urgent!!! How to get filename in fullpath.
Thank. |
|
|
|
|
|
#33 |
|
Junior Member
Join Date: Mar 2004
Location: Pretoria
Posts: 4
|
In wa_ipc.h you'll find
code: But "(not external apps)" is not true my app can get it. Thus for the fullpath use code: in the above code. |
|
|
|
|
|
#34 |
|
Junior Member
Join Date: Mar 2004
Posts: 9
|
Ok, now im gonna have to reveal my n00bness here, and while i doubt i will get an answer, im gonna ask anyway...
Im looking for a DLL for use with mIRC (must follow this format) code: that will allow me to control winamp's volume, along with play and stop. I take it this is possible (everything is), but not being a C coder, im not sure how. If anyone has any ideas, or can point me in the direction of code samples that i may understand (are nicely commented), it would be great.... |
|
|
|
|
|
#35 |
|
Junior Member
Join Date: Mar 2004
Location: Pretoria
Posts: 4
|
If I understand you correctly, the DLL "plugs-in" to mIRC?
If so, you use the same code listed above in your DLL. If you want a DLL that already does this, I think you have to write one. Which doesn't answer your question ![]() Search this forum, you'll find clues on how to do it. |
|
|
|
|
|
#36 |
|
Junior Member
Join Date: Jan 2007
Location: Caen, France
Posts: 4
|
hi!
i'm trying to get the filename of the current playing song in winamp from an external application written in C# (.NET 2.0) I'm doing the same things that are your C or Vb code but it doesn't work. The openProcess method alway return me zero, so i can't read in winamp memory. Anybody have a sample code in C# ? i can post my code here if somebody can help... |
|
|
|
|
|
#37 |
|
Member
Join Date: Sep 2006
Posts: 89
|
Can you post a DllImport you are using for openProcess?
|
|
|
|
|
|
#38 |
|
Junior Member
Join Date: Jan 2007
Location: Caen, France
Posts: 4
|
i've seen your WACC lib and download it. It work fine :-)
but why use a bind method with path of winamp ? can we get this path from registry ? is bind necessary for all winamp interaction or only for some (which used command line to control winamp?) ? by the way, when i get songpath from your WACC lib, i use it with taglib dll (http://developer.novell.com/wiki/index.php/TagLib_Sharp) to read all ID3 stuff (and other tag format for vorbis / ape...) If i put the songpath in hard code (like String songPath ="c:\\mp3\\toto.mp3" all is ok, i can read the id3 tags. But if i use your WACC lib to get the current winamp song played (the same toto.mp3), the taglib constructor return null. I've compared the two string (the hard coded and the one return from your lib), all is the same (after a substring to kill \0 at end of string return by WACC). So what's wrong with String return by your WACC? here is my getCurrentSongPath method code: here is how i get tag with taglib code: Last edited by fdeshayes; 17th January 2007 at 20:26. |
|
|
|
|
|
#39 | |||
|
Member
Join Date: Sep 2006
Posts: 89
|
Quote:
Quote:
Quote:
![]() A string returned by GetItemPath (and all other strings that are read from the winamp's memory space) is not terminated properly. I have fixed the problem so you have to wait for the next release planned in this weekend. You will not have to use the following line anymore and taglib will work as expected. code: If you don't want to wait, you can fix the library yourself. Just replace this line: Dim RetStr As String = Marshal.PtrToStringAnsi(returnVal, MaxStrLen) with this one: Dim RetStr As String = Marshal.PtrToStringAnsi(returnVal) It's in clsWacc.vb in ReadRemoteString function. By the way. Next version will be able to read information from tags, so stay tuned. |
|||
|
|
|
|
|
#40 |
|
Junior Member
Join Date: Jan 2007
Location: Caen, France
Posts: 4
|
thanks for this explication.
For your bind, maybe you can use system method FindWindow with the classname of winamp : "Winamp v1.x". This classname doesn't change, contrary to the path of winamp.exe here is an exemple in C#. I've not VB. code: i've not VB so i must wait until next released. Can you said approximatly when will be the next released or maybe can you send me only the fresh .dll (even in beta, i only use cWinamp.Playlist.Position and cWinamp.Playlist.GetItemPath()) ? thanks for your work! |
|
|
|
![]() |
|
|||||||
| Thread Tools | Search this Thread |
| Display Modes | |
|
|