简体   繁体   English

是否可以从控制台应用程序发送 Toast 通知?

[英]Is it possible to send Toast notification from console application?

Is it possible to send Toast notifications from console application using ToastNotificationManager ?是否可以使用ToastNotificationManager从控制台应用程序发送 Toast 通知?

I know that it is possible to send Toast notifications from Windows Universal app:我知道可以从 Windows 通用应用程序发送 Toast 通知:

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

*doc - Toast stored in XML string *doc - Toast 存储在 XML 字符串中

To use ToastNotificaionManager I need Windows.UI.Notifications library which I can't reference in console application project.要使用 ToastNotificaionManager,我需要无法在控制台应用程序项目中引用的Windows.UI.Notifications库。

The library I mentionet before is actualy used by WinRT.我之前提到的库实际上是由 WinRT 使用的。 Is it possible to use WinRT APIs in Windows console application ?是否可以在 Windows 控制台应用程序中使用 WinRT API?

At first you need to declare that your program will be using winRT libraries:首先,您需要声明您的程序将使用 winRT 库:

  1. Right-click on your yourProject, select Unload Project右键单击您的项目,选择卸载项目
  2. Right-click on your yourProject(unavailable) and click Edit yourProject.csproj右键单击 yourProject(不可用)并单击Edit yourProject.csproj
  3. Add a new property group: <targetplatformversion>8.0</targetplatformversion>添加新的属性组: <targetplatformversion>8.0</targetplatformversion>
  4. Reload project重新加载项目
  5. Add reference Windows from Windows > CoreWindows > Core添加参考Windows
    在此处输入图片说明

Now you need to add this code:现在您需要添加以下代码:

using Windows.UI.Notifications;

and you will be able to send notifications using this code:您将能够使用此代码发送通知:

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

Reference: How to call WinRT APIs in Windows 8 from C# Desktop Applications - WinRT Diagram参考: 如何从 C# 桌面应用程序调用 Windows 8 中的 WinRT API - WinRT 图

I ran into some problems here with Evaldas B's Code I was missing a string.我在 Evaldas B 的代码中遇到了一些问题,我缺少一个字符串。 (Where It Says Need String Here) (这里说需要字符串的地方)

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

warning I am kind of new to C# so my code probably sucks- but it does work and is pretty simplistic and that's more than I can say for most solutions I have found警告我是 C# 的新手,所以我的代码可能很糟糕 - 但它确实有效并且非常简单,而且对于我找到的大多数解决方案来说,这比我能说的要多

Also I was having a hell of a time getting the xml document to read.另外,我在阅读 xml 文档时遇到了很多麻烦。 I was fighting with System.xml (I think) and Windows.Data.Dom.Xml (also not completely sure).我正在与 System.xml (我认为)和 Windows.Data.Dom.Xml (也不完全确定)作斗争。 In the end I settled on making them hard coded strings for my example file and used a switch statement to switch between them.最后,我决定为我的示例文件制作硬编码字符串,并使用 switch 语句在它们之间切换。 I have found a ton of people, looking for the solution that I have come up with, on stack overflow.我找到了很多人,在堆栈溢出时寻找我提出的解决方案。 It seems use of the toast notification system with console or background applications would be super useful, and the documentation that surrounds the toast notification system with windows applications all suggest that it needs to be used with an application.似乎将 toast 通知系统与控制台或后台应用程序一起使用会非常有用,并且围绕具有 Windows 应用程序的 toast 通知系统的文档都表明它需要与应用程序一起使用。 The Action Center is super useful for notifications vrs the NotificationTray/NotifyIcon route.操作中心对于通知和 NotificationTray/NotifyIcon 路由非常有用。 I have not found a full solution anywhere else on the web.我还没有在网络上的其他任何地方找到完整的解决方案。 Here is example code.这是示例代码。

/*
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);


        }
    }
}

1) For a toast notification to appear using a console or Desktop application, your application must have a shortcut on the start menu. 1) 要使用控制台或桌面应用程序显示 Toast 通知,您的应用程序必须在开始菜单上有一个快捷方式。

2) For an application to have a shortcut icon(not tile icon) in the start menu of Windows, your app must have an AppId. 2) 要使应用程序在 Windows 的开始菜单中具有快捷方式图标(而非磁贴图标),您的应用程序必须具有 AppId。 To create a short cut for you you application create a new class named ShellHelpers.cs and Paste this code in it.要为您创建快捷方式,您的应用程序创建一个名为 ShellHelpers.cs 的新类并将此代码粘贴到其中。

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"));
        }
    }
}
}

Code for creating a shortcut(This code can be added to the same class where you will be showing the toast)用于创建快捷方式的代码(此代码可以添加到您将显示吐司的同一类中)

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));
    }

Now you can create an show a toast现在您可以创建一个展示祝酒词

// 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);

The APP_ID can be any string. APP_ID 可以是任何字符串。 In my case it was "NotificationTest.KEY" Note: Dont modify the ShellHelper class.就我而言,它是“NotificationTest.KEY” 注意:不要修改 ShellHelper 类。 Edit : Follow Evaldas B's answer first then apply this solution.编辑:首先遵循 Evaldas B 的回答,然后应用此解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 可以从非 UWP C# 应用程序在 Windows 10 中发送 Toast 通知吗? - Possible to send Toast Notification in Windows 10 from a non-UWP C# app? C# 是否可以从后台进程的控制台应用程序发送 Toast / BalloonTip? - C# Is it possible to send Toast / BalloonTip from Console App that a Background Process? 如何从 C# 控制台应用程序发送通知 - How to send notification from C# Console application 如何从应用程序外部获取Toast通知? - How can i get my Toast Notification from outside the application? 是否可以通过一个应用程序使用不同的ListeningConnectionStrings发送通知? - Is it possible to send a notification with different listeningConnectionStrings with one application? C#Console Toast停止显示通知 - C# Console Toast Stops Displaying Notification 从Toast Notification打开文件 - Opening a file from Toast Notification 一次将模板通知发送到图块和烤面包 - Send template-notification to tile and toast once 在每个星期五的特定时间发送通知(吐司) - Send Notification (Toast) every friday at specific time 从控制台应用程序向WindowsForm应用程序发送字符串 - Send a string from Console Application to WindowsForm application
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM