I want to use the toast notification of windows 10 API and it is available in windows 10.0.17763.0 or later(https://learn.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/send-local-toast?tabs=uwp).
Therefore, I set two TFMs in my project for support windows7 also:
<TargetFrameworks>net6.0-windows7;net6.0-windows10.0.17763.0</TargetFrameworks>
My opinion is to check the OS version. In windows7 it will send the toast notification by a custom control I made. In windows10 it will send the toast notification by origin windows10 API. Here is my code:
var OSVersion = System.Environment.OSVersion;
if (OSVersion.Version.Major == 10 && OSVersion.Version.Build > 17763)
{
new ToastContentBuilder()
.AddArgument("action", "viewConversation")
.AddArgument("conversationId", 9813)
.AddText("Andrew sent you a picture")
.AddText("Check this out, The Enchantments in Washington!")
.Show();
}
else
{
//custom toast...
}
Then I met a situation, the code cannot run in earlier than windows 10.0.17763.0. that Visual Studio reports an error of ToastContentBuilder.Show() below
Finally, I found this tutorial by using the Conditional compilation:
https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/desktop-to-uwp-enhance#support-windows-xp-windows-vista-and-windows-78-install-bases
Then I tried to use the Conditional compilation and modify my code like this:
[System.Diagnostics.Conditional("Win10")]
void ShowNotificationWin10()
{
new ToastContentBuilder()
.AddArgument("action", "viewConversation")
.AddArgument("conversationId", 9813)
.AddText("Andrew sent you a picture")
.AddText("Check this out, The Enchantments in Washington!")
.Show();
}
However, the error is still here. How can I solve this?
Related
I've searched through a number of different posts to do with creating toast notifications from a Win Form however when these through I get an error when generating the toast notification.
System.Exception: Element not found. (Exception from
HRESULT:0x80070490).
I have edited the csproj file and added the following:
<PropertyGroup>
<TargetPlatformVersion>10.0.10586</TargetPlatformVersion>
</PropertyGroup>
and added the references to Windows.Data and Windows.UI and also a reference to System.Runtime.dll as per the suggestions in Windows.UI.Notifications is missing
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
using System.Windows.Forms;
using System;
namespace ToastNotify
{
class Notify
{
public void GenerateToast(string header, string content)
{
ToastTemplateType toastTemplate = ToastTemplateType.ToastImageAndText02;
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);
XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
toastTextElements[0].AppendChild(toastXml.CreateTextNode(header));
toastTextElements[1].AppendChild(toastXml.CreateTextNode(content));
XmlNodeList toastImageElements = toastXml.GetElementsByTagName("image");
((XmlElement)toastImageElements[0]).SetAttribute("src", "..\\..\\Resources\\icon.ico");
IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
((XmlElement)toastNode).SetAttribute("duration", "long");
ToastNotification toast = new ToastNotification(toastXml);
try
{
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
Any suggestions as to where I am going wrong?
You should explicitly provide applicationId for CreateToastNotifier.
Like this:
private const String APP_ID = "Microsoft.Samples.DesktopToastsSample";
...
ToastNotificationManager.CreateToastNotifier(APP_ID).Show(toast);
But I have bad news. Starting from Windows 10 1709 WinForms applications just does not show toast notifications. Before that Show(toast) was working, but now it neither throw an exception, nor show any toast notification.
I'm still figuring this out.
As noted by Prateek Shrivastava there are (new) limitations.
Have a look here https://learn.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotificationmanager.createtoastnotifier
Update:
Here is the step by step guide, to create a setup with APP_ID so notifications will work on all Windows 10 versions:
Send a local toast notification from desktop C# apps
Update:
It works again in Windows 10 1903 without setup.
Use This and make sure you are setting the Image (Icon) full path if you want to show an icon otherwise just pass null.
public static void GenerateToast(string appid, string imageFullPath, string h1, string h2, string p1)
{
var template = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastImageAndText04);
var textNodes = template.GetElementsByTagName("text");
textNodes[0].AppendChild(template.CreateTextNode(h1));
textNodes[1].AppendChild(template.CreateTextNode(h2));
textNodes[2].AppendChild(template.CreateTextNode(p1));
if (File.Exists(imageFullPath))
{
XmlNodeList toastImageElements = template.GetElementsByTagName("image");
((XmlElement)toastImageElements[0]).SetAttribute("src", imageFullPath);
}
IXmlNode toastNode = template.SelectSingleNode("/toast");
((XmlElement)toastNode).SetAttribute("duration", "long");
var notifier = ToastNotificationManager.CreateToastNotifier(appid);
var notification = new ToastNotification(template);
notifier.Show(notification);
}
I need to chime in here, because I'm working on a WinForms app (.Net Framework 4.7*) that's failing to build on a GitHub build worker because at some point, support for toast notifications was hacked in with some weird references to these WinMetadata\Windows.*.winmd files.
Woe be to anyone who has found this StackOverflow question.
You're probably targeting the .Net Framework 4.x because you're working on a Win Forms app. .Net Framework 4.8 is supported on Windows 7, and Windows 7 does not have ToastNotifications which is probably the class you're looking for. Hence the problem.
I think the only solution is the one in the updated answer that's most upvoted, which is just target the more modern UWP framework that will only work on Windows 10 and up. But you're still trying to send toast notifications from a framework that's not designed to support it. At some point in your code, you're probably doing a check if the platform you're running on is Windows 10 or newer. Not even a compiler statement, just straight up C# or VB.Net. That's not how the .Net Framework is designed to work - it's meant to be platform-agnostic.
My only advice is; setup a new build target for Windows 10+ and setup your project following the advice from Stephen. That should be the least-hackish way of making WinForms do neat Windows 10 tricks.
So far I have struggled to get MbnInterfaceManager working (see hresult from IMbnInterfaceManager::GetInterfaces when no MBN device exists), so instead I built and debugged an application with no problems from within Visual Studio 2015 that executed this WMI query in C# (see also the Win32_PerfFormattedData_Tcpip_NetworkInterface documentation):
string query = "SELECT * FROM Win32_PerfRawData_Tcpip_NetworkInterface";
ManagementObjectSearcher moSearch = new ManagementObjectSearcher(query);
ManagementObjectCollection moCollection = moSearch.Get();
But then when I deployed the application to Windows 8.1, I receive this error every time the query is executed:
System.Management.ManagementException: Invalid query
at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
Does anyone have any suggestions on how to resolve this issue? How can I deploy an application so that it is able to use queries like this?
UPDATE:
Please note that I can build and run the above code (as part of a larger WPF application) from within Visual Studio 2015 on either Windows 7 or Windows 8.1, and I can deploy the same application using ClickOnce onto Windows 7 where it runs successfully. For some reason when I deploy this application using ClickOnce onto Windows 8.1, I get that Invalid query message.
I think what I have to do is make sure that the System.Management reference is set to "Copy Local" but I'm not able to test that right now. If anyone has any better ideas please feel free to let me know.
UPDATE:
It is not possible to use System.Management.dll on Windows 8.1 in the same way it is used on Windows 7 or Windows 10.
I've found that to perform operations similar to the ones I mentioned in my question on Windows 8.1 and Windows 8 phone you need to either get a Windows 8.1 developer license or on Windows 10 set your computer to "Developer Mode" so you can use the Windows.Networking.Connectivity namespace:
string connectionProfileInfo = string.Empty;
ConnectionProfile InternetConnectionProfile = NetworkInformation.GetInternetConnectionProfile();
if (InternetConnectionProfile == null)
{
rootPage.NotifyUser("Not connected to Internet\n", NotifyType.StatusMessage);
}
else
{
connectionProfileInfo = GetConnectionProfile(InternetConnectionProfile);
OutputText.Text = connectionProfileInfo;
rootPage.NotifyUser("Success", NotifyType.StatusMessage);
}
// Which calls this function, that allows you to determine how strong the signal is and the associated bandwidth
string GetConnectionProfile(ConnectionProfile connectionProfile)
{
// ...
if (connectionProfile.GetSignalBars().HasValue)
{
connectionProfileInfo += "====================\n";
connectionProfileInfo += "Signal Bars: " + connectionProfile.GetSignalBars() + "\n";
}
// ...
}
Please note that you have to make sure your project is either a Window 8.1 PCL or a Windows 8.1 app to be able to reference the namespace.
For details please see https://code.msdn.microsoft.com/windowsapps/network-information-sample-63aaa201
UPDATE 2:
To be able to get bandwidth on Windows 7, 8.1 and 10, I ended up using this code:
private int GetMaxBandwidth()
{
int maxBandwidth = 0;
NetworkInterface[] networkIntrInterfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (var networkInterface in networkIntrInterfaces)
{
IPv4InterfaceStatistics interfaceStats = networkInterface.GetIPv4Statistics();
int bytesSentSpeed = (int)(interfaceStats.BytesSent);
int bytesReceivedSpeed = (int)(interfaceStats.BytesReceived);
if (bytesSentSpeed + bytesReceivedSpeed > maxBandwidth)
{
maxBandwidth = bytesSentSpeed + bytesReceivedSpeed;
}
}
}
I have an application that requires to control mobile broadband API.
I am struggling on correctly installing the api on my devices.
I've been follow the instructions in this document:
http://www.google.be/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=1&cad=rja&ved=0CC0QFjAA&url=http%3A%2F%2Fdownload.microsoft.com%2Fdownload%2F7%2FE%2F7%2F7E7662CF-CBEA-470B-A97E-CE7CE0D98DC2%2FMB_ManagedCode.docx&ei=kyvmUs7jE4e60QWbooHYDg&usg=AFQjCNG6yaGf4sRhdbWI99fE7tmQX8cmnA&sig2=2Fg-_DRYBIselKR19wTq2Q
and trying to combine the steps with this stackoverflow explanation
C# Read Windows Mobile Broadband connection properties
I have been able to lay a reference from visual studio to mbnapi.tlb in V7.0/lib. and I automatically now have a interop.mbnapi.tlb in my obj/debug folder.
When trying to "check the SIM is inserted and working / activated". => my code crashes on the following line
IMbnInterface[] mobileInterfaces = mbnInfMgrInterface.GetInterfaces() as IMbnInterface[];
When I run it on windows 8, mbnInfMgrInterface == null
I have already tried to install the same SDK on windows 8 as stated in the requirements of the document but the SDK is only meant for windows 7...
I have tried to register the mbnapi in windows 8 by performing
Regtlibv12 Mbnapi.tlb
no luck whatsoever...
what do I need to do to get this to work please?
anyone has some experience in this?
EDIT. on windows 7 (my development machine), I get the message "Device not ready", I think this is normal because I don't have mobile broadband on it, on windows 8 I do, but there the mobile interface manager is null => mbnInfMgrInterface == null.
thank you,
Not sure exactly what you are after, but after struggling with IMbnInterface and GetSignalStrength() (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd323166(v=vs.85).aspx) and being unsuccessful, I found that you can obtain a lot of info using WMI:
int maxBandwidth = 0;
string query = "SELECT * FROM Win32_PerfRawData_Tcpip_NetworkInterface";
ManagementObjectSearcher moSearch = new ManagementObjectSearcher(query);
ManagementObjectCollection moCollection = moSearch.Get();
foreach (ManagementObject mo in moCollection)
{
if (Convert.ToInt32(mo["CurrentBandwidth"]) > maxBandwidth)
{
// Instead of CurrentBandwidth you may want to use BytesReceivedPerSec
maxBandwidth = Convert.ToInt32(mo["CurrentBandwidth"]);
}
}
Please see answer here: Determining the network connection link speed and here is the list of properties you can obtain: https://msdn.microsoft.com/en-us/library/aa394293(VS.85).aspx
UPDATE:
Please note that I can build and debug the above code (as part of a larger WPF application) from within Visual Studio 2015 on either Windows 7 or Windows 8.1, and I can deploy the same application onto Windows 7 where it runs successfully. For some reason when I deploy this application on Windows 8.1, I get an Invalid query message.
UPDATE 2:
Please note that I found you cannot get the network info in Windows 8.1 in the same way as you do in Windows 7, in that the System.Management namespace is not available on Windows 8.1. See https://code.msdn.microsoft.com/windowsapps/network-information-sample-63aaa201
string connectionProfileInfo = string.Empty;
ConnectionProfile InternetConnectionProfile = NetworkInformation.GetInternetConnectionProfile();
if (InternetConnectionProfile == null)
{
rootPage.NotifyUser("Not connected to Internet\n", NotifyType.StatusMessage);
}
else
{
connectionProfileInfo = GetConnectionProfile(InternetConnectionProfile);
OutputText.Text = connectionProfileInfo;
rootPage.NotifyUser("Success", NotifyType.StatusMessage);
}
// Which calls this function, that allows you to determine how strong the signal is and the associated bandwidth
string GetConnectionProfile(ConnectionProfile connectionProfile)
{
// ...
if (connectionProfile.GetSignalBars().HasValue)
{
connectionProfileInfo += "====================\n";
connectionProfileInfo += "Signal Bars: " + connectionProfile.GetSignalBars() + "\n";
}
// ...
}
This is my code that throws an exception, it just randomly started today here is the photo :
Here is the whole page code and the error exception :
public frmWFDocumentDetail()
{
InitializeComponent();
NavigationInTransition navigateInTransition = new NavigationInTransition();
navigateInTransition.Backward = new TurnstileTransition { Mode = TurnstileTransitionMode.BackwardIn };
navigateInTransition.Forward = new TurnstileTransition { Mode = TurnstileTransitionMode.ForwardIn };
NavigationOutTransition navigateOutTransition = new NavigationOutTransition();
navigateOutTransition.Backward = new TurnstileTransition { Mode = TurnstileTransitionMode.BackwardOut };
navigateOutTransition.Forward = new TurnstileTransition { Mode = TurnstileTransitionMode.ForwardOut };
TransitionService.SetNavigationInTransition(this, navigateInTransition);
TransitionService.SetNavigationOutTransition(this, navigateOutTransition);
DataContext = App.ViewModel_WFDocumentDetailItems;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//**this is how you pass parameters through to a new page**//
string processID = "-1";
string processName = "";
NavigationContext.QueryString.TryGetValue("processID", out processID);
NavigationContext.QueryString.TryGetValue("processName", out processName);
App.ViewModel_WFDocumentHeaderItems.LoadData("johnny", processID);
App.ViewModel_WFDocumentDetailItems.LoadData("johnny");
}
and the access violation :
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory
is corrupt.
I have read up on it, some people say it is nvidia network manager, and some people say I must set some setting like Suppress JIT optimization , and ignore gpu memory if value isn't changed... but nothing works? Can anyone please please send me in the right direction?
As requested , the full stack
i used the setting taylorjohnl gave me "Debug -> Options and Settings -> Debugging -> General -> Enable Just My Code",and then the error went right to the piece of xaml that was a syntax error, and boom fixed it and app works again :) so violation error for me was basically a reference error, hope this can help other people as well, also use expression blend in silverlight to debug xaml in the UI
I had a similar problem which in the end was resolved by submitting crash dump to MS Tech Support. Here is their response:
The gist is that The crash is a known bug in the version 5.0 of comctl32.dll (Windows Common Controls), which ships with the Windows OS. This bug will not be fixed in version 5.0 of the common controls, because that version was for applications existing prior to Windows XP. It has since been fixed in version 6.0 of comctl32.dll, which is included with Windows XP and later. Note that both versions of comctl32.dll (5.0 and 6.0) are included with every version of Windows since Windows XP. The older one is just there for backwards compatibility purposes for very old applications.
To resolve the problem, you need to change the application to have it opt into version 6.0 of comctl32.dll. Within a Windows Forms application, this is done by calling into the Application.EnableVisualStyles method at startup of the application. If you are developing within a C# project, then you can do this by adding the call prior to your Application.Run call within your application's entry point. For example:
[STAThread]
static void Main()
{
Application.EnableVisualStyles(); //Add this line
Application.Run(new Form1());
}
If you are in a Visual Basic .Net project, you can opt into this by going to your project properties, and then selecting the "Enable Application Framework" and "Enable XP Visual Styles" checkboxes on the Application property page.
Once you do this, it should resolve this particular access violation.
what is code in the InitializeComponent()? there is some class refer to null in it, (mostly is a event handler). once it is trigger, it will report AccessViolation.
I'm targetting IOS 4.3 and 5.0 with an app built against the 5.0 SDK and would like to add support for the Twitter functionality introduced in iOS5 only when the app runs on a iOS5 device. What is the recommended way to reliably test for the availability of these OS features at runtime without having your app crash?
I know you do this using respondsToSelector in Objective-C but how is it done in C#?
With recent MonoTouch versions you can use the following code:
if (UIDevice.CurrentDevice.CheckSystemVersion (5, 0)) {
window.RootViewController = navigation;
} else {
window.AddSubview (navigation.View);
}
Otherwise you can get a string from UIDevice.CurrentDevice.SystemVersion and do some checks with your own code.
Follow up to comments, including mine...
If you want to check by feature you can do something like:
MonoTouch.Twitter.TWRequest req = new MonoTouch.Twitter.TWRequest ();
if (req.Handle == IntPtr.Zero) {
Console.WriteLine ("No Twitter support before iOS5");
}
What happens is that the selector to create the TWRequest instance will return null and the .NET object will be created in an invalid (unusable) state that you can query with the Handle property. Again YMMV, testing is key :-)