microsoft / AppModelSamples

Sample code for AppModel features
MIT License
200 stars 102 forks source link

UWP Notification Listener: Object reference not set to an instance of an object when trying to save app logo #21

Open NeoTechni opened 3 years ago

NeoTechni commented 3 years ago

I am trying to save the logo as a file

             RandomAccessStreamReference stream = app.AppInfo.DisplayInfo.GetLogo(new Size(64, 64));
             IAsyncOperation<IRandomAccessStreamWithContentType> streamOperation = stream.OpenReadAsync();

I get an error on the second line: Object reference not set to an instance of an object.

The full code

            string appPackageName = notif.AppInfo.Id;
            string appDisplayName = notif.AppInfo.DisplayInfo.DisplayName;
            string Path = (Directory.GetCurrentDirectory() + "\\assets").Replace("\\\\", "\\");
            string Filename = Path + "\\" + appPackageName + ".png";

            if(!Directory.Exists(Path)){
                Directory.CreateDirectory(Path);
            }
         if (!File.Exists(Filename)) {
                RandomAccessStreamReference stream = notif.AppInfo.DisplayInfo.GetLogo(new Size(128, 128));
                IAsyncOperation<IRandomAccessStreamWithContentType> streamOperation = stream.OpenReadAsync();
                Task<IRandomAccessStreamWithContentType> streamTask = streamOperation.AsTask();
                streamTask.Wait();
                IRandomAccessStreamWithContentType content = streamTask.Result;

                FileStream TheFile = File.Create(Filename);
                content.AsStream().Seek(0, SeekOrigin.Begin);
                content.AsStream().CopyTo(TheFile);
                TheFile.Dispose();
            }
NeoTechni commented 3 years ago

How the hell do you save a picture? I am pulling my hair out at this SIX HOURS LATER!

Everything I try, Windows finds a way to screw up. From reading the directory saved by another app from the registry (permission errors trying to read HKEY_CURRENT_USER) To deciding the path I eventually managed to wrangle from HKEY_LOCAL_MACHINE doesn't exist, even though I'm looking at it And I gave up and decided to save the files to the temp directory, and then tell the other program to just copy them to it's own directory, and the temp files aren't even being created! Oh and it makes you put everything in Task.Run cause "synchronous commands shouldn't be run from the UI threat", screw off and just let me do it!

  private static async System.Threading.Tasks.Task ProcessNotification(Windows.UI.Notifications.UserNotification notif){
        NotificationBinding toastBinding = notif.Notification.Visual.GetBinding(KnownNotificationBindings.ToastGeneric);
        if (toastBinding != null) {
            string appPackageName = notif.AppInfo.Id;
            string appDisplayName = notif.AppInfo.DisplayInfo.DisplayName;
            if(appPackageName.Length > 0 && appDisplayName.Length > 0) {
                string Filename = ChkDir(BitPixelDir, "win." + appPackageName + ".png");
                string TempFile = ChkDir(Path.GetTempPath(), "win." + appPackageName + ".png");

                IReadOnlyList<AdaptiveNotificationText> textElements = toastBinding.GetTextElements();// And then get the text elements from the toast binding
                string titleText = textElements.FirstOrDefault()?.Text;// Treat the first text element as the title text
                // We'll treat all subsequent text elements as body text, joining them together via newlines.
                string bodyText = string.Join("\n", textElements.Skip(1).Select(t => t.Text));

                Debug.WriteLine(appPackageName + "|" + appDisplayName + "|" + notif.CreationTime + "|" + titleText + "|" + bodyText);
                Debug.WriteLine("LAST NOTI: " + MainPage.LastNotification + " PATH: " + Filename + " TEMP: " + TempFile);

                if (!File.Exists(Filename) && !File.Exists(TempFile)) {
                    //if(IsDirectoryWritable(Path)){
                        RandomAccessStreamReference stream = notif.AppInfo.DisplayInfo.GetLogo(new Size(128, 128));
                        if(!(stream is null) && Directory.Exists(BitPixelDir)){
                            IAsyncOperation<IRandomAccessStreamWithContentType> streamOperation = stream.OpenReadAsync();
                            Task<IRandomAccessStreamWithContentType> streamTask = streamOperation.AsTask();
                            streamTask.Wait();
                            IRandomAccessStreamWithContentType content = streamTask.Result;
                            await Task.Run(() => {
                                try{
                                    FileStream TheFile = File.Create(TempFile);
                                    content.AsStream().Seek(0, SeekOrigin.Begin);
                                    content.AsStream().CopyTo(TheFile);
                                    TheFile.Dispose();
                                } catch (Exception E) {
                                    Debug.WriteLine(TempFile + " could not be created: '" + E.ToString() + "'");
                                }
                            });
                        }
                    //} else {
                    //    Debug.WriteLine(Path + " can't be accessed");
                    //}
                }
            }
        }
    }