public override void Unload() { base.Unload(); try { ProcessFunctions.CloseMemory(this.Handle); } catch { } this.authorizationToken = string.Empty; this.authorizationTokenExpiration = 0; this.updateAuthorizationTokenTimer.Stop(); this.updateSpotifyTrackTimer.Stop(); this.Handle = IntPtr.Zero; this.processId = 0; this.processIdLast = 0; }
private void SetUpSpotifyHandles() { if (this.processId <= 0 || this.processId != this.processIdLast) { int someOtherProcessId = ProcessFunctions.GetProcessId(this.exeName); this.processId = ProcessFunctions.GetParentProcessId(someOtherProcessId, this.exeName); if (this.processId > 0) { ProcessFunctions.ModuleInfo moduleInfo = ProcessFunctions.GetModuleInfo(this.processId, this.moduleName); if ((int)moduleInfo.BaseOfDll > 0) { this.Handle = ProcessFunctions.OpenProcess(this.processId, Enumerations.ProcessAccess.VMAll); this.processIdLast = this.processId; this.moduleBaseAddress = (int)moduleInfo.BaseOfDll; this.moduleLength = (int)moduleInfo.SizeOfImage; } else { this.ResetSnipSinceSpotifyIsNotRunning(); } } else { this.ResetSnipSinceSpotifyIsNotRunning(); } } // Quick check to test if Spotify is running. There is a better solution for this but this will hold everything over for now. // It also makes a complaint because process is never actually used. try { Process process = Process.GetProcessById(this.processId); } catch { this.ResetSnipSinceSpotifyIsNotRunning(); } }
private void UpdateSpotifyTrackTimer_Elapsed(object sender, ElapsedEventArgs e) { // Locate and detect Spotify and get handles this.SetUpSpotifyHandles(); // If the process ID is greater than 0 then we found the process if (this.processId > 0) { // The track ID is 22 bytes long byte[] trackIdInBytes = new byte[22]; // We can use this to determine if Spotify is playing or not. // If Spotify is not playing the titlebar will be "Spotify". Otherwise it // will contain the artist and track title. string windowTitle = ProcessFunctions.GetProcessWindowTitle(this.processId); byte[] searchBytes = Encoding.Default.GetBytes(this.searchString); int addressOfTrackId = ProcessFunctions.FindInMemory(this.processId, this.moduleBaseAddress, this.moduleLength, searchBytes); // 14 is the offset where the trackId begins, trackId is 22 chars long trackIdInBytes = ProcessFunctions.ReadMemory(this.Handle, (IntPtr)addressOfTrackId + 14, 22); if (windowTitle == "Spotify Premium" || windowTitle == "Spotify Free" || windowTitle == "Spotify") { // Because we search for this first there's a brief moment on startup where it may display // that no track is playing before it states that Spotify is not running. this.ResetSnipSinceSpotifyIsNotPlaying(); } else { string trackId = Encoding.Default.GetString(trackIdInBytes); // Only update if the title has changed or the user updates how the output format should look if (trackId != this.LastTitle || Globals.RewriteUpdatedOutputFormat) { Globals.RewriteUpdatedOutputFormat = false; string json = string.Empty; if (Globals.CacheSpotifyMetadata) { json = this.ReadCachedJson(trackId); } else { json = this.DownloadJson( string.Format( CultureInfo.InvariantCulture, "https://api.spotify.com/v1/tracks/{0}", trackId), SpotifyAddressContactType.API); } // This shouldn't happen... but you never know. if (!string.IsNullOrEmpty(json)) { dynamic jsonSummary = SimpleJson.DeserializeObject(json); // If there are multiple artists we want to join all of them together for display string artists = string.Empty; foreach (dynamic artist in jsonSummary.artists) { artists += artist.name.ToString() + ", "; } artists = artists.Substring(0, artists.LastIndexOf(',')); // Removes last comma TextHandler.UpdateText( jsonSummary.name.ToString(), artists, jsonSummary.album.name.ToString(), jsonSummary.id.ToString(), jsonSummary.ToString()); if (Globals.SaveAlbumArtwork) { this.DownloadSpotifyAlbumArtwork(jsonSummary.album); } // Set the last title to the track id as these are unique values that only change when the track changes this.LastTitle = trackId; } } } } }