是否可以使用 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?
答案 0 :(得分:15)
首先,您需要声明您的程序将使用winRT库:
1.右键单击您的项目,选择卸载项目
2.右键单击youProject(不可用),然后单击编辑yourProject.csproj
3.添加新的属性组:<targetplatformversion>8.0</targetplatformversion>
4.重新加载项目
5.从 Windows&gt;添加参考 Windows 。芯强>
现在您需要添加以下代码:
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的答案然后应用此解决方案。