 |
|
 |
Hi,
I am a newbie to all of this. I want to do something similar to what you have done here, except not with WinAmp. But I started coding my own version before I ever saw this. I am using Windows Messages to contact an application which I wrote from an ASP.Net program. It works great in Visual Web Developer, but when I put it on the IIS, the Messages are no longer sent.
You say that you coded yours the way you did so that you wouldn't have to give IIS access to the desktop. Before I do something drastic and recode my WebForm to act like yours, I would like to see mine work. So can you please let me know how to give IIS permission to send Windows Messages? Also, how big a security risk is it to allow this?
Thanks
|
|
|
|
 |
|
 |
Allowing IIS to interact with desktop:
Control Panel -> Administrative Tools -> Services -> World Wide Web Publishing Service -> right click -> Properties -> Log On -> Allow service to interact with desktop -> OK
Restart IIS.
|
|
|
|
 |
|
 |
/* Code: C#
* User: Stefan Vahldieck
* Date: 31.01.2007
* Time: 22:05
*/
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace test
{
///
/// Description of WinAmpDemoSDK.
///
public static class WinAmpDemoSDK
{
public static IntPtr hWnd = FindWindow("Winamp v1.x", null);
public static Process WinAmpProcess = Process.GetProcessesByName("Winamp")[0];
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow( [MarshalAs(UnmanagedType.LPTStr)] string lpClassName, [MarshalAs(UnmanagedType.LPTStr)] string lpWindowName );
[DllImport("user32")]
public static extern int GetWindowThreadProcessId( IntPtr hWnd, IntPtr ProcessId );
[ DllImport( "Kernel32.dll" ) ]
public static extern bool ReadProcessMemory( IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, UInt32 nSize, ref UInt32 lpNumberOfBytesRead );
[DllImport( "Kernel32.dll", SetLastError = true ) ]
public static extern IntPtr OpenProcess( UInt32 dwDesiredAccess, bool bInheritHandle, UInt32 dwProcessId );
[DllImport("KERNEL32.DLL")]
public static extern int CloseHandle(int handle);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage( IntPtr hwnd, int wMsg, int wParam, uint lParam );
private static string readStringFromWinampMemory( int winampMemoryAddress )
{
string str = "";
// Prozess zum lesen öffnen
IntPtr handle = OpenProcess( 0x0010, false, (uint)WinAmpProcess.Id );
byte[] buff = new byte[500];
UInt32 ret = new UInt32();
IntPtr pos = new IntPtr( winampMemoryAddress );
if( ReadProcessMemory( handle, pos, buff, 500, ref ret ) )
{
System.Text.Encoding encoding = System.Text.Encoding.Default;
str = encoding.GetString( buff );
}
return str;
}
public static string[] getPlaylist()
{
int len = SendMessage( hWnd, (int)WA_IPC.WM_WA_IPC, 0, (uint)WA_IPC.IPC_GETLISTLENGTH );
string[] listNames = new string[len];
for( int i = 0; i |
|
|
|
 |
|
 |
I put together a similar project in VB6 a while back to accomplish the same goal. I stumbled across this by accident, but now feel inclinded to upgrade mine to .NET. Thanks for sharing this demo. It's clean and easy to follow!
|
|
|
|
 |
|
 |
Is there any possibility of getting direct instructions on how to get this working using visual studio?
|
|
|
|
 |
|
 |
This worked for me.
Put all 3 project directories in a single directory. Create a virtual web share off of the Winamp project folder calling it Winamp. Launch the solution file in Winamp Service directory.
|
|
|
|
 |
|
 |
hello all,
i am not sure if this forum is appropriate for my question, but heres hoping!
i read the article and thought it might be ok to post here.
i am working on a client server architecture in C++. the server sterams an audio file to the client. now, this is the part i need help with:
i want the client to open up winamp and send the stream to winamp to play. there are a lot of things i need clarification on! where do i start?
in a nutshell, is it even possible to do this? ie, send a stream to winamp. i have read that it is... but i would really appreciate any advice on how to do this. would also appreciate any links you guys know of where i can read up on it. i totally don't know how to do this or where to start, so absolutely any introductory material would be welcome.
thanks a lot! i am a beginner, so please bear with me! i can send command and user messages now, but i dont' know how to sedn a stream to winamp and tell it to play it!
drew.
|
|
|
|
 |
|
 |
Is there anyway to retrieve the actual file name for the currently playing file? So far, I've only found articles that allow for the retrieval of the name of the file, but that's from the ID3 tags. Aside from searching and reading all the ID3 tags in an entire music library, is there anyway to get the file name of the file?
Thanks,
Chris
|
|
|
|
 |
|
 |
Ah well, I can't even get the Findwindow function to work in asp.net let alone running this thing. Anyone successfully done this in VB for Asp.net? Can you mail me? Thank you very much.
|
|
|
|
 |
|
 |
Using VB.NET you should not use "MarshallAs" attribute, if that is of any help
Greetz
Niels Penneman
|
|
|
|
 |
|
 |
Here is some working code
HWND FindWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName
);
In C# .NET this function is referenced as follows:
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
And in VB .NET:
Private Declare Auto Function FindWindow Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
greetz
Niels Penneman
|
|
|
|
 |
|
 |
[SocketException (0x274d): Det gick inte att göra en anslutning eftersom måldatorn aktivt nekade det]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +264
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +877
WinampController.winampcontroller.Status() in c:\work\winampcontroller\winampcontroller.cs:139
Winamp._default.BindCurrentSettings() in c:\work\website\www-ffc\winamp\default.aspx.cs:46
Winamp._default.Page_Load(Object sender, EventArgs e) in c:\work\website\www-ffc\winamp\default.aspx.cs:34
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +731
Where is the problem??
|
|
|
|
 |
|
 |
Hi!
First of all, thank you for your idea!
It works fine for me, but two things are weird:
1.
this piece of code does not work for me correctly:
// try
// {
// m_windowName = ConfigurationSettings.AppSettings["WindowClassName"];
// }
// catch(NullReferenceException)
// {
// m_windowName = "Winamp v1.x";
// }
replacing it with
// m_windowName = "Winamp v1.x";
it works perfectly !?
2.
i created a DataGrid with ButtonColumns, but only ButtonColumns of the type "LinkButton" work.
"PushButton" does not work (but looks better - any ideas?)
|
|
|
|
 |
|
 |
Whenever I try to run this, I get:
Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.
Source Error:
Line 39: "Passport" and "None"
Line 40: -->
Line 41:
Line 42:
Line 43: <!-- APPLICATION-LEVEL TRACE LOGGING
Source File: c:\inetpub\wwwroot\Winamp\web.config Line: 41
What am I not doing right??
|
|
|
|
 |
|
 |
Jesse3647 wrote:
What am I not doing right??
This error can be caused by a virtual directory not being configured as an application in IIS. Just make the winamp directory an application in the IIS manager.
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
 |
|
 |
I think the problem can be resolved if you modify your machine.config file. The service is looking for an app setting for the TCP port number. You must add the value to the cofig file. I had the same problem until I added this key. Once you do that, you should be able to start the service.
|
|
|
|
 |
|
 |
I've ported the code to VB.NET, but am having problems with the AppendToPlayList method. Winamp opens its 'Open File(s)' dialog, instead of adding the song to the playlist. I'm guessing that there's some truncation going on, since the dialog opens to the appropriate directory (e.g. if I pass "C:\mp3\Billy Bragg\Don't Try This At Home\Accident Waiting To Happen.mp3", the dialog opens to the "" folder). I've included the appropriate code. Any suggestions on what I'm doing wrong would be appreciated. C. <DllImport("user32.dll", EntryPoint:="FindWindow", SetLastError:=True, CharSet:=CharSet.Auto)> _ Public Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As Integer ' End Function <StructLayout(LayoutKind.Sequential)> _ Public Structure COPYDATASTRUCT Public dwData As Integer 'Specifies data to be passed to the receiving application Public cbData As Integer 'Specifies the size, in bytes, of the data pointed to by the lpData member <MarshalAs(UnmanagedType.LPStr)> Public lpData As String 'Pointer to data to be passed to the receiving application. This member can be NULL End Structure 'COPYDATASTRUCT
<DllImport("kernel32.dll", EntryPoint:="lstrcpy", SetLastError:=True, CharSet:=CharSet.Auto)> _ Public Shared Function lstrcpy(ByVal lpString1 As String, ByVal lpString2 As String) As Integer ' End Function <DllImport("user32.dll", CharSet:=CharSet.Auto)> _ Public Shared Function SendMessage(ByVal InPtr As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As COPYDATASTRUCT) As Integer ' End Function <DllImport("user32.dll", CharSet:=CharSet.Auto)> _ Public Shared Function SendMessageA(ByVal IntPtr As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer ' End Function Public Sub AppendToPlayList(ByVal filename As String) Dim hwnd As Integer = FindWindow(m_windowName, vbNullString) Dim cds As COPYDATASTRUCT cds.dwData = 100 cds.lpData = lstrcpy(filename, filename) cds.cbData = Len(filename) + 1 Dim retval As Integer = SendMessage(hwnd, &H4A, 0&, cds) End Sub
|
|
|
|
 |
|
 |
Just tested it and worked like a charm.
Only my way to declare the functions is different. Check it out.
Private Declare Auto Function FindWindow Lib "user32" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As IntPtr
Private Declare Auto Function GetWindowText Lib "user32" ( _
ByVal hwnd As IntPtr, _
ByVal lpString As String, _
ByVal cch As Integer) As Integer
Private Declare Auto Function SendMessageA Lib "user32" ( _
ByVal hwnd As IntPtr, _
ByVal wMsg As Integer, _
ByVal wParam As Integer, _
ByVal lParam As Integer) As Integer
Private Declare Auto Function SendMessage Lib "user32" ( _
ByVal hwnd As IntPtr, _
ByVal wMsg As Integer, _
ByVal wParam As Integer, _
ByRef lParam As COPYDATASTRUCT) As Integer
_
Structure COPYDATASTRUCT
Public dwData As IntPtr
Public cbData As Integer
Public lpData As String
End Structure
Public Sub AppendToPlayList(ByVal filename As String)
Dim cds As COPYDATASTRUCT
cds.dwData = New System.IntPtr(100)
cds.lpData = filename
cds.cbData = filename.Length + 1
SendMessage(hwnd, &H4A, 0, cds)
End Sub
|
|
|
|
 |
|
 |
Hi Dan,
First of all, thanks for a great article / code sample ! I've tried to get it running at home, but haven't had any success at all. First, I installed the website and the service at my development server, but could not get winamp to play anything. Then I thought "well, the website doesn't seem to get the same WinampController as the service has (or something like that) - maybe I should try it locally first". And so I did - with the almost same result. I can open the website, add files to the "playlist", and press play. But nothing happens. Then I tried to add a file to my winamp instance manually, press play and then stop (on winamp) and then play on the web, that worked. So the message is sent to the winamp-instance, but the playlist-things aren't quite working. But thats fine, I'll find out why. However, that doesn't work on the server, and I just can't figure why.
I've been working quite a lot with VS6.0 (C++) but not very much with VS.NET - so maybe I'm missing some important project setting here. Anyway - here is my setup : One workspace (solution) with all three project in it. "References" in Winamp (the web) and in WinampService are OK - as far as I can tell - since the WinampController-reference "points" to the dll from the WinampController project. But are there any differences when moving the final files to the server ? Are paths coded into the .exe /web application, or do I have to install / register the WinampController.dll somehow ? I did install the service, of course.
Sigh... I can't see a way out. Frustrating that it works (kind of) locally - but not on the server where it should
Well, I hope you have some kind of advice, because this is really what I need. Thanks for doing all the hard work
And finally - I after reading the article text several times, I still don't quite understand why the service is there. First I thought it would relay messages between the website (the controller, really) and the winamp instance, but that is done directly from the controller. Maybe I just don't understand what kind of object the winampcontroller really is.
Anyway, thanks in advance for any help or advice - and happy new year to you !
/Jan
|
|
|
|
 |
|
 |
Now it works... all that was wrong was
public winampcontroller()
{
try
{
m_windowName = ConfigurationSettings.AppSettings["WindowClassName"];
}
catch(NullReferenceException)
{
m_windowName = "Winamp v1.x";
}
}
- which never left m_windowName with anything but null.
- this is NOT a signature !
|
|
|
|
 |
|
 |
System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it
Why this machine refuses to let me hear winamp?
The code above is the one that I see in your program...
This is the correction or only the proplem?
anyway...great idea
|
|
|
|
 |
|
 |
If u re using XP have u tried turning off the windows firewall.
|
|
|
|
 |
|
 |
Hi Dan:
Your article has nice idea,but whats the need of windows service here?Couldn't you directly use your wrapped class in your asp.net project?I think its useless here!
<html>Mazy</html>
"And the carpet needs a haircut, and the spotlight looks like a prison break
And the telephone's out of cigarettes, and the balcony is on the make
And the piano has been drinking, the piano has been drinking...not me...not me-Tom Waits
|
|
|
|
 |
|
 |
Your right, you could do without the windows service (as i said in the article), but you would have to set IIS up to be able to interact with the desktop, we did not want to do that.
|
|
|
|
 |
|
 |
but you would have to set IIS up to be able to interact with the desktop
<<
How do we do that?
|
|
|
|
 |