【问题标题】:Compile a Visual Studio C# project for two TargetPlatformVersion为两个 TargetPlatformVersion 编译一个 Visual Studio C# 项目
【发布时间】:2015-04-01 12:34:28
【问题描述】:

我开发了一个 .NET windows 应用程序,它可以在 Windows 7 和 8.1 上运行。然后我添加了 Windows 8 附带的 Toast 通知功能(来自这个问题:How can I use the Windows.UI namespace from a regular (Non-Store) Win32 .NET application?)。 这也有效,我只需要添加:

<PropertyGroup> <TargetPlatformVersion>8.0</TargetPlatformVersion> </PropertyGroup>

到项目文件。

当我从 Windows 8.1 SDK C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\Windows.winmd 引用 Windows.winmd 文件时,可执行文件不再在 Windows 7 上启动!我双击,就是这样。没有错误,没有消息。

由于我没有在网上找到任何解决方案,所以我的问题出现了:我如何做到这两点:向我的用户提供 toast 功能并制作相同的 .exe 在 Windows 7 上运行

提前谢谢你!

编辑 事实证明,尽管 TargetPlatformVersion 设置为 8.0,但可执行文件仍然在 Windows 7 上启动,但在程序尝试加载 Windows 8 库时立即崩溃:

An unhandled exception of type 'System.TypeLoadException' occurred in ToastTester.exe. Additional information: Could not find Windows Runtime type 'Windows.UI.Notifications.ToastNotificationManager'.

在线Application.Run(new Form1());

在第 9 行的 Form1.cs 中,我有 using Windows.UI.Notifications;

在运行时避免此异常的最佳方法是什么,即使预计此可执行文件将在 Windows 7 等 Windows.UI.Notifications 命名空间绝对不可用的环境中运行?

【问题讨论】:

  • 我刚刚尝试过,如果我按照您的建议重新定位应用程序并添加对 Windows.winmd 的引用,编译后的 exe 仍然在 Windows 7 上为我运行。如果我尝试从 Windows.UI.Notifications 命名空间访问任何内容,它将在 Windows 8 上运行,但在 Windows 7 上会因错误而崩溃。
  • 它是什么类型的应用程序?我使用 WPF 应用程序进行了测试。

标签: c# winforms visual-studio-2013 windows-8 windows-7


【解决方案1】:

我设计了自己的解决方法,以便能够支持 Windows 8 toast,同时防止在 Windows 7 上运行时由于缺少库而导致应用程序崩溃。注意:我使用的是单例设计模式(成员 INSTANCE),但你总是可以这样做。

ShellLink.cs is taken from here

Win8Toaster.cs:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;

namespace ToastManager
{
    class Win8Toaster
    {
        public const string APPUSERMODELID = "YourCompany.YourApplicationName";
        public static string ShortcutLocation;
        public static ToastNotifier ToastNotifier;

        private static Win8Toaster _INSTANCE = null;
        public static Win8Toaster INSTANCE
        {
            get
            {
                if (_INSTANCE == null)
                {
                    _INSTANCE = new Win8Toaster();
                }
                return _INSTANCE;
            }
        }

        public Win8Toaster()
        {
            ShortcutLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Microsoft\Windows\Start Menu\Programs\YourCompany\YourApplication.lnk");
            //We need a start menu shortcut (a ShellLink object) to show toasts.
            if (!File.Exists(ShortcutLocation))
            {
                string directory = Path.GetDirectoryName(ShortcutLocation);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }
                using (ShellLink shortcut = new ShellLink())
                {
                    shortcut.TargetPath = System.Reflection.Assembly.GetEntryAssembly().Location;
                    shortcut.Arguments = "";
                    shortcut.AppUserModelID = APPUSERMODELID;
                    shortcut.Save(ShortcutLocation);
                }
            }
            ToastNotifier = ToastNotificationManager.CreateToastNotifier(APPUSERMODELID);
        }

        public void ShowToast(ToastContent Content)
        {
            XmlDocument ToastContent = new XmlDocument();
            ToastContent.LoadXml("<toast><visual><binding template=\"ToastImageAndText02\"><image id=\"1\" src=\"file:///" + Content.ImagePath + "\"/><text id=\"1\">" + Content.Text1 + "</text><text id=\"2\">" + Content.Text2 + "</text></binding></visual></toast>");
            ToastNotification thisToast = new ToastNotification(ToastContent);
            ToastNotifier.Show(thisToast);
        }                
    }
}

Toaster.cs

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace ToastManager
{
    public static class Toaster
    {
        private static Win8Toaster ActiveToaster;
        public static bool Win8ToasterAvailable = true;
        public static void ShowToast(ToastContent Content)
        {
            if (Win8ToasterAvailable)
            {
                if (ActiveToaster == null)
                {
                    if (Environment.OSVersion.Version.Major > 6 || Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 2)
                    {
                        try
                        {
                            ActiveToaster = Win8Toaster.INSTANCE;
                        }
                        catch (Exception ex)
                        {
                            Win8ToasterAvailable = false;
                        }
                    }
                    else
                    {
                        Win8ToasterAvailable = false;
                    }
                }
                ActiveToaster.ShowToast(Content);
            }
            else
            {
                //Use alternative notifications because Windows 8 Toasts are not available
            }
        }
    }
    //I also wrote my own toast content structure:
    public class ToastContent
    {

        public string ImagePath, Text1, Text2;
        public ToastContent(string ImagePath, string Text1, string Text2)
        {
            this.ImagePath = ImagePath;
            this.Text1 = Text1;
            this.Text2 = Text2;
        }
    }
}

现在你已经有了必要的类,下面是如何使用它(很简单吧?):

ToastManager.Toaster.ShowToast(new ToastManager.ToastContent(@"..\path\toyour\image.png", "Your Application Name", "Time: " + DateTime.Now.ToLongTimeString()));

如果您使用的是 Windows 7,此示例显示带有当前系统时间的 Toast 通知。

设计建议:

我使用 WinForms 设计了一个通知窗口,它看起来类似于 Windows 8 中的通知窗口,并模拟了相同的功能,只是用我自己的表单。或者,您也可以实现托盘图标并显示一些通知气泡。

【讨论】:

  • 第一次捕获System.TypeLoadException,然后设置一个布尔标志,表示烤面包机功能不存在并且下次不调用它?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多