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

时间:2016-06-27 19:53:16

标签: c# windows notifications win-universal-app console-application

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

我知道可以从Windows Universal app发送Toast通知:

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

* doc - 存储在XML字符串中的Toast

要使用ToastNotificaionManager,我需要 Windows.UI.Notifications 库,我无法在控制台应用程序项目中引用它。

我之前提到的库实际上是由WinRT使用的。是否可以在Windows控制台应用程序中使用WinRT API?

3 个答案:

答案 0 :(得分:15)

首先,您需要声明您的程序将使用winRT库:
1.右键单击您的项目,选择卸载项目
2.右键单击youProject(不可用),然后单击编辑yourProject.csproj
3.添加新的属性组:<targetplatformversion>8.0</targetplatformversion>
4.重新加载项目
5.从 Windows&gt;添加参考 Windows 。芯
enter image description here

现在您需要添加以下代码:

using Windows.UI.Notifications;

您将能够使用以下代码发送通知:

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

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

答案 1 :(得分:3)

我遇到了一些问题,Evaldas B的代码我错过了一个字符串。 (这里说它需要字符串)

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

警告我对C#不熟悉,所以我的代码可能很糟糕 - 但它确实有效并且相当简单,而且对于我找到的大多数解决方案而言,这比我能说的更多

此外,我还有一段时间来阅读xml文档。我正在使用System.xml(我认为)和Windows.Data.Dom.Xml(也不完全确定)。 最后,我决定为我的示例文件制作硬编码字符串,并使用switch语句在它们之间切换。 我找到了很多人,在堆栈溢出时寻找我提出的解决方案。似乎使用带有控制台或后台应用程序的Toast通知系统将非常有用,并且使用Windows应用程序围绕Toast通知系统的文档都表明它需要与应用程序一起使用。对于NotificationTray / NotifyIcon路由的通知,操作中心非常有用。我还没有在网络上的任何其他地方找到完整的解决方案。这是示例代码。

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


        }
    }
}

答案 2 :(得分:1)

1)要使用控制台或桌面应用程序显示Toast通知,您的应用程序必须在开始菜单上有一个快捷方式。

2)对于在Windows开始菜单中有快捷方式图标(而非图块图标)的应用程序,您的应用程序必须具有AppId。 要为您创建快捷方式,应用程序将创建一个名为ShellHelpers.cs的新类,并在其中粘贴此代码。

.ts

创建快捷方式的代码(此代码可以添加到您将展示吐司的同一个类中)

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

现在你可以创建一个节目祝酒

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

APP_ID可以是任何字符串。就我而言,它是“NotificationTest.KEY” 注意:不要修改ShellHelper类。 编辑:首先关注Evaldas B的答案然后应用此解决方案。