5

È possibile inviare notifiche Toast dall'applicazione console utilizzando ToastNotificationManager?È possibile inviare notifiche Toast dall'applicazione console?

So che è possibile inviare notifiche Toast da Windows universale app:

var toast = new ToastNotification(doc); 
ToastNotificationManager.CreateToastNotifier().Show(toast); 

* doc - Toast memorizzato nella stringa XML

Per utilizzare ToastNotificaionManager ho bisogno Windows.UI.Notifications libreria che non posso fare riferimento nel progetto di applicazione della console.

La libreria di cui sopra è utilizzata da WinRT. È possibile utilizzare le API WinRT nell'applicazione console di Windows?

+0

Un'applicazione console non ha una GUI, quindi un Toast non ha significato, no? – ManoDestra

+0

Un brindisi a cosa? Sembra che tu abbia risposto alla tua stessa domanda. –

+0

Le notifiche hanno un sacco di applicazioni e in questo caso ne ho davvero bisogno –

risposta

11

In un primo momento è necessario dichiarare che il programma prevede di utilizzare le librerie WinRT:
1. Fare clic destro sul vostro ProgettoUtente, selezionare Scarica progetto
2. Fare clic destro sul vostro YouProject (non disponibili) e fare clic su Modifica yourProject.csproj
3. Aggiungere un nuovo gruppo di proprietà: <targetplatformversion>8.0</targetplatformversion>
4. progetto Reload
5. Aggiungere referece di Windows da di Windows> Nucleo
enter image description here

Ora è necessario aggiungere questo codice:

using Windows.UI.Notifications; 

e si sarà in grado di inviare notifiche utilizzando questo codice:

var toast = new ToastNotification(doc); 
ToastNotificationManager.CreateToastNotifier().Show(toast); 

Riferimento: How to call WinRT APIs in Windows 8 from C# Desktop Applications - WinRT Diagram

+0

Dopo la modifica, la mia applicazione console non si avvia con errore di riferimento: Impossibile caricare il file o l'assembly 'System.Runtime, Versione = 4.0.20.0, Culture = neutro, PublicKeyToken = b03f5f7f11d50a3a' – Jamby

3

I incontrato alcuni problemi qui con il codice di Evaldas B mi mancava una stringa. (dove si dice bisogno String Qui)

.CreateToastNotifier(<needed a string here>).Show(toast);

avvertimento Sono sorta di nuovo in C# quindi il mio codice probabilmente sucks- ma funziona ed è piuttosto semplicistica e che è più che posso dire per la maggior parte soluzioni che ho trovato

Inoltre stavo passando un po 'di tempo a leggere il documento xml. Stavo combattendo con System.xml (credo) e Windows.Data.Dom.Xml (anche non completamente sicuro). Alla fine ho deciso di renderli stringhe codificate per il mio file di esempio e ho usato un'istruzione switch per passare da una all'altra. Ho trovato un sacco di persone, cercando la soluzione che ho trovato, in overflow dello stack. Sembra che l'utilizzo del sistema di notifica del brindisi con console o applicazioni in background sia estremamente utile e la documentazione che circonda il sistema di notifica del brindisi con le applicazioni Windows suggerisce che è necessario utilizzarlo con un'applicazione. Il Centro operativo è molto utile per le notifiche sulla rotta NotificationTray/NotifyIcon. Non ho trovato una soluzione completa da nessun'altra parte sul web. Ecco il codice di esempio.

/* 
At first you need to declare that your program will be using winRT libraries: 
1. Right click on your yourProject, select Unload Project 
2. Right click on your youProject(unavailable) and click Edit yourProject.csproj 
3. Add a new property group:<TargetPlatformVersion>8.0</TargetPlatformVersion> 
4. Reload project 
5. Add referece Windows from Windows > Core 
*/ 
using System; 
using Windows.Data.Xml.Dom; 
using Windows.Storage; 
using Windows.Storage.Streams; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Windows.UI.Notifications; 

namespace ConsoleApplication6 
{ 
    public class NewToastNotification 
    { 
     public NewToastNotification(string input, int type) 
     { 
      string NotificationTextThing = input; 
      string Toast = ""; 
      switch (type) 
      { 
       case 1: 
        { 
         //Basic Toast 
         Toast = "<toast><visual><binding template=\"ToastImageAndText01\"><text id = \"1\" >"; 
         Toast += NotificationTextThing; 
         Toast += "</text></binding></visual></toast>"; 
         break; 
        } 
       default: 
        { 
         Toast = "<toast><visual><binding template=\"ToastImageAndText01\"><text id = \"1\" >"; 
         Toast += "Default Text String"; 
         Toast += "</text></binding></visual></toast>"; 
         break; 
        } 
      } 
      XmlDocument tileXml = new XmlDocument(); 
      tileXml.LoadXml(Toast); 
      var toast = new ToastNotification(tileXml); 
      ToastNotificationManager.CreateToastNotifier("New Toast Thing").Show(toast); 
     } 
} 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      NewToastNotification Window = new NewToastNotification("Yes",1); 


     } 
    } 
} 
+0

Qualcuno ha una risposta a questo? Quale dovrebbe essere l'ID dell'applicazione passato alla chiamata CreateToastNotifier? Come trovare l'ID dell'applicazione? Ho provato molte varianti possibili guardando il manifest di app universale ma non ha funzionato. Il brindisi viene visualizzato, va bene, ma quando faccio clic su un pulsante all'interno dell'app universale non è avviato. In realtà nel mio caso l'app universale è l'app desktop bridge universale, WPF racchiusa nel contenitore UWP. – Alex

0

1) Per una notifica brindisi appaia utilizzando una console o un'applicazione desktop, l'applicazione deve avere un collegamento nel menu di avvio.

2) Per un'applicazione con un'icona di collegamento (non icona a forma di piastrella) nel menu di avvio di Windows, l'app deve avere un AppId. Per creare una scorciatoia per te, l'applicazione crea una nuova classe chiamata ShellHelpers.cs e incolla questo codice al suo interno.

using System; 
using System.Runtime.InteropServices; 
using System.Text; 
using Microsoft.WindowsAPICodePack.Shell.PropertySystem; 
using MS.WindowsAPICodePack.Internal; 

namespace DesktopToastsSample.ShellHelpers 
{ 
    internal enum STGM : long 
    { 
     STGM_READ = 0x00000000L, 
    STGM_WRITE = 0x00000001L, 
    STGM_READWRITE = 0x00000002L, 
    STGM_SHARE_DENY_NONE = 0x00000040L, 
    STGM_SHARE_DENY_READ = 0x00000030L, 
    STGM_SHARE_DENY_WRITE = 0x00000020L, 
    STGM_SHARE_EXCLUSIVE = 0x00000010L, 
    STGM_PRIORITY = 0x00040000L, 
    STGM_CREATE = 0x00001000L, 
    STGM_CONVERT = 0x00020000L, 
    STGM_FAILIFTHERE = 0x00000000L, 
    STGM_DIRECT = 0x00000000L, 
    STGM_TRANSACTED = 0x00010000L, 
    STGM_NOSCRATCH = 0x00100000L, 
    STGM_NOSNAPSHOT = 0x00200000L, 
    STGM_SIMPLE = 0x08000000L, 
    STGM_DIRECT_SWMR = 0x00400000L, 
    STGM_DELETEONRELEASE = 0x04000000L, 
} 

internal static class ShellIIDGuid 
{ 
    internal const string IShellLinkW = "000214F9-0000-0000-C000-000000000046"; 
    internal const string CShellLink = "00021401-0000-0000-C000-000000000046"; 
    internal const string IPersistFile = "0000010b-0000-0000-C000-000000000046"; 
    internal const string IPropertyStore = "886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99"; 
} 

[ComImport, 
Guid(ShellIIDGuid.IShellLinkW), 
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
internal interface IShellLinkW 
{ 
    UInt32 GetPath(
     [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, 
     int cchMaxPath, 
     //ref _WIN32_FIND_DATAW pfd, 
     IntPtr pfd, 
     uint fFlags); 
    UInt32 GetIDList(out IntPtr ppidl); 
    UInt32 SetIDList(IntPtr pidl); 
    UInt32 GetDescription(
     [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, 
     int cchMaxName); 
    UInt32 SetDescription(
     [MarshalAs(UnmanagedType.LPWStr)] string pszName); 
    UInt32 GetWorkingDirectory(
     [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, 
     int cchMaxPath 
     ); 
    UInt32 SetWorkingDirectory(
     [MarshalAs(UnmanagedType.LPWStr)] string pszDir); 
    UInt32 GetArguments(
     [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, 
     int cchMaxPath); 
    UInt32 SetArguments(
     [MarshalAs(UnmanagedType.LPWStr)] string pszArgs); 
    UInt32 GetHotKey(out short wHotKey); 
    UInt32 SetHotKey(short wHotKey); 
    UInt32 GetShowCmd(out uint iShowCmd); 
    UInt32 SetShowCmd(uint iShowCmd); 
    UInt32 GetIconLocation(
     [Out(), MarshalAs(UnmanagedType.LPWStr)] out StringBuilder pszIconPath, 
     int cchIconPath, 
     out int iIcon); 
    UInt32 SetIconLocation(
     [MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, 
     int iIcon); 
    UInt32 SetRelativePath(
     [MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, 
     uint dwReserved); 
    UInt32 Resolve(IntPtr hwnd, uint fFlags); 
    UInt32 SetPath(
     [MarshalAs(UnmanagedType.LPWStr)] string pszFile); 
} 

[ComImport, 
Guid(ShellIIDGuid.IPersistFile), 
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
internal interface IPersistFile 
{ 
    UInt32 GetCurFile(
     [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile 
    ); 
    UInt32 IsDirty(); 
    UInt32 Load(
     [MarshalAs(UnmanagedType.LPWStr)] string pszFileName, 
     [MarshalAs(UnmanagedType.U4)] STGM dwMode); 
    UInt32 Save(
     [MarshalAs(UnmanagedType.LPWStr)] string pszFileName, 
     bool fRemember); 
    UInt32 SaveCompleted(
     [MarshalAs(UnmanagedType.LPWStr)] string pszFileName); 
} 
[ComImport] 
[Guid(ShellIIDGuid.IPropertyStore)] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
interface IPropertyStore 
{ 
    UInt32 GetCount([Out] out uint propertyCount); 
    UInt32 GetAt([In] uint propertyIndex, out PropertyKey key); 
    UInt32 GetValue([In] ref PropertyKey key, [Out] PropVariant pv); 
    UInt32 SetValue([In] ref PropertyKey key, [In] PropVariant pv); 
    UInt32 Commit(); 
} 


[ComImport, 
Guid(ShellIIDGuid.CShellLink), 
ClassInterface(ClassInterfaceType.None)] 
internal class CShellLink { } 

public static class ErrorHelper 
{ 
    public static void VerifySucceeded(UInt32 hresult) 
    { 
     if (hresult > 1) 
     { 
      throw new Exception("Failed with HRESULT: " + hresult.ToString("X")); 
     } 
    } 
} 
} 

codice per la creazione di un collegamento (Questo codice può essere aggiunto alla stessa classe in cui si sarà in mostra il brindisi)

public bool TryCreateShortcut() 
    { 
     String shortcutPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Microsoft\\Windows\\Start Menu\\Programs\\FixSus Toasts Sample .lnk"; 
     if (!File.Exists(shortcutPath)) 
     { 
      InstallShortcut(shortcutPath); 
      return true; 
     } 
     return false; 
    } 

    private void InstallShortcut(String shortcutPath) 
    { 
     // Find the path to the current executable 
     String exePath = Process.GetCurrentProcess().MainModule.FileName; 
     IShellLinkW newShortcut = (IShellLinkW)new CShellLink(); 

     // Create a shortcut to the exe 
     DesktopToastsSample.ShellHelpers.ErrorHelper.VerifySucceeded(newShortcut.SetPath(exePath)); 
     DesktopToastsSample.ShellHelpers.ErrorHelper.VerifySucceeded(newShortcut.SetArguments("")); 

     // Open the shortcut property store, set the AppUserModelId property 
     IPropertyStore newShortcutProperties = (IPropertyStore)newShortcut; 

     using (PropVariant appId = new PropVariant(APP_ID)) 
     { 
      DesktopToastsSample.ShellHelpers.ErrorHelper.VerifySucceeded(newShortcutProperties.SetValue(SystemProperties.System.AppUserModel.ID, appId)); 
      DesktopToastsSample.ShellHelpers.ErrorHelper.VerifySucceeded(newShortcutProperties.Commit()); 
     } 

     // Commit the shortcut to disk 
     IPersistFile newShortcutSave = (IPersistFile)newShortcut; 

     DesktopToastsSample.ShellHelpers.ErrorHelper.VerifySucceeded(newShortcutSave.Save(shortcutPath, true)); 
    } 

Ora è possibile creare uno spettacolo un brindisi

// Get a toast XML template 
     XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastImageAndText04); 

     // Fill in the text elements 
     XmlNodeList stringElements = toastXml.GetElementsByTagName("text"); 
     stringElements[1].AppendChild(toastXml.CreateTextNode("Message" + newMessage)); 


     // Specify the absolute path to an image 
     string codeWebFolderPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\")); 
     String imagePath = "file:///" + Path.GetFullPath(codeWebFolderPath+ "Resources\\FixSus.png"); 
     XmlNodeList imageElements = toastXml.GetElementsByTagName("image"); 
     imageElements[0].Attributes.GetNamedItem("src").NodeValue = imagePath; 

     // Create the toast and attach event listeners 
     ToastNotification toast = new ToastNotification(toastXml); 

     toast.Activated += ToastActivated; 
     toast.Dismissed += ToastDismissed; 
     toast.Failed += ToastFailed; 

     // Show the toast. Be sure to specify the AppUserModelId on your application's shortcut! 
     ToastNotificationManager.CreateToastNotifier(APP_ID).Show(toast); 

L'APP_ID può essere una stringa qualunque. Nel mio caso era "NotificationTest.KEY" Nota: non modificare la classe ShellHelper. Modifica: seguire prima la risposta di Evaldas B quindi applicare questa soluzione.