public static Song GetCurrentSong() { if (!Spotify.IsRunning()) { return(null); } IntPtr hWnd = GetSpotify(); int length = Win32.GetWindowTextLength(hWnd); StringBuilder sb = new StringBuilder(length + 1); Win32.GetWindowText(hWnd, sb, sb.Capacity); string title = sb.ToString(); if (!string.IsNullOrWhiteSpace(title) && title != "Spotify") { // Unfortunately we don't have a great way to get the title from Spotify // so we need to do some gymnastics. // Music played from an artist's page is usually in the format "artist - song" // while music played from a playlist is often in the format "artist - song - album" // unfortunately this means that some songs that actually have a " - " in either the artist name // or in the song name will potentially display incorrectly var portions = title.Split(new string[] { " - " }, StringSplitOptions.None); var song = (portions.Length > 1 ? portions[1] : null); var artist = portions[0]; var album = (portions.Length > 2 ? string.Join(" ", portions.Skip(2).ToArray()) : null); // take everything else that's left return(new Song(artist, song, album)); } return(null); }
public static string GetCurrentTrack() { if (!Spotify.IsAvailable()) { return(string.Empty); } IntPtr hWnd = GetSpotify(); int length = Win32.GetWindowTextLength(hWnd); StringBuilder sb = new StringBuilder(length + 1); Win32.GetWindowText(hWnd, sb, sb.Capacity); return(sb.ToString().Replace("Spotify", "").TrimStart(' ', '-').Trim()); }
/// <summary> /// Find a running instance of Spotify /// </summary> /// <returns>HWND of the Spotify window</returns> private static IntPtr GetSpotify() { if (DateTime.Now.Subtract(_lastGetSpotifyCall).TotalSeconds < _GET_SPOTIFY_RETURN_LAST_SEC) { return(_cachedHWnd); } _lastGetSpotifyCall = DateTime.Now; var rv = IntPtr.Zero; // Spotify have made things a little harder with their use of electron // In order to not pick up on other Electron windows, first find the process and then the window var procs = Process.GetProcessesByName("spotify"); if (Array.Exists(procs, proc => proc.Id == _cachedProcId)) { return(_cachedHWnd); } foreach (var proc in procs) { foreach (ProcessThread thread in proc.Threads) { Win32.EnumThreadWindows(thread.Id, (hWnd, lParam) => { var sb = new StringBuilder(256); // get the class name to check if it's of type Chome_WidgetWin_0 var ret = Win32.GetClassName(hWnd, sb, sb.Capacity); if (ret != 0) { if (sb.ToString() == "Chrome_WidgetWin_0") { // now check to make sure that it has a title (Spotify has a couple of windows // that it uses for specific controls, we don't want those ret = Win32.GetWindowText(hWnd, sb, sb.Capacity); if (ret != 0) { if (!string.IsNullOrWhiteSpace(sb.ToString())) { rv = hWnd; _cachedProcId = proc.Id; _cachedHWnd = hWnd; // stop the enumeration immediately return(false); } } } } return(true); }, IntPtr.Zero); if (rv != IntPtr.Zero) { return(rv); } } } // couldn't find the window return(rv); }