It is currently November 4th, 2024, 6:05 am

Windows Notification Toaster

Skins that control functions in Windows or Rainmeter
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Windows Notification Toaster

Post by kyriakos876 »

Just came home and tried your suggestion. I like it!
I will keep adding stuff on this powershell script from now on. :thumbup:
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Windows Notification Toaster

Post by kyriakos876 »

khanhas wrote: November 6th, 2018, 6:34 am Since you uses Powershell to trigger notification, I think you can use PowershellRM
...
I'm going to assume that you made the plugin as the github name matches yours in this forum so let me ask,
Are you escaping the reserved characters using the builtin escape function that is native to C++ in windows 10 libraries or are you doing like I did in the lua with a function? If it's the second, are you using the same characters I did? (as shown at the end of the first post)
User avatar
jsmorley
Developer
Posts: 22898
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Windows Notification Toaster

Post by jsmorley »

I would note that {6D809377-6AF0-444B-8957-A3773F02200E} is not an AppUserModelID for Rainmeter, Rainmeter doesn't have an AppUserModelID. That is the GUID for FOLDERID_ProgramFilesX64, which defaults to C:\Program Files. Note as well that this won't work on a 32bit Windows OS, or if Rainmeter is installed as 32bit on a 64bit system, or if Rainmeter is installed in "portable" mode.

https://docs.microsoft.com/en-us/windows/desktop/shell/knownfolderid
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Windows Notification Toaster

Post by kyriakos876 »

jsmorley wrote: November 6th, 2018, 1:54 pm I would note that {6D809377-6AF0-444B-8957-A3773F02200E} is not an AppUserModelID for Rainmeter, Rainmeter doesn't have an AppUserModelID. That is the GUID for FOLDERID_ProgramFilesX64, which defaults to C:\Program Files. Note as well that this won't work on a 32bit Windows OS, or if Rainmeter is installed as 32bit on a 64bit system, or if Rainmeter is installed in "portable" mode.

https://docs.microsoft.com/en-us/windows/desktop/shell/knownfolderid
Oh I thought you couldn't raise a notification at all if the app doesn't have an AppUserModelID because of this

https://msdn.microsoft.com/en-us/library/windows/desktop/hh802762(v=vs.85).aspx
This topic shows you how to create a shortcut for your app, assign it an AppUserModelID, and install it in the Start screen. We strongly recommend that you do this in the Windows Installer rather than in your app's code. Without a valid shortcut installed in the Start screen or in All Programs, you cannot raise a toast notification from a desktop app.
so I assumed it was the AppUserModelID
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Windows Notification Toaster

Post by kyriakos876 »

Hey khanhas, sorry if I'm being annoying, but I'm trying to make your EncodeVar function return null if a variable is empty or if it's not defined at all (with your code it returns the name of the variable between ##)... I tried this:

Code: Select all

function EncodeVar {
  param([string]$name)
  $variableValue = $RmAPI.VariableStr($name)
  If (-not ([string]::IsNullOrWhitespace($variableValue))) {
  return "$null"
  }
  else {
  return [System.Web.HttpUtility]::HtmlEncode($variableValue)
  }
}
But I doesn't seem to be working... any idea why?

Also, if something is changed in the .ps1 script's code I have to refresh the to re-parse the script file... any idea how can I change the code and be able to apply the changes without refreshing the skin?
-Thanks in advance.
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Windows Notification Toaster

Post by kyriakos876 »

https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/notification-listener

Any chance we can implement this into Rainmeter?
Check whether the listener is supported
If your app supports older versions of Windows 10, you need to use the ApiInformation class to check whether the listener is supported. If the listener isn't supported, avoid executing any calls to the listener APIs.

Code: Select all

if (ApiInformation.IsTypePresent("Windows.UI.Notifications.Management.UserNotificationListener"))
{
    // Listener supported!
}
 
else
{
    // Older version of Windows, no Listener
}

Requesting access to the listener

Code: Select all


// Get the listener
UserNotificationListener listener = UserNotificationListener.Current;
 
// And request access to the user's notifications (must be called from UI thread)
UserNotificationListenerAccessStatus accessStatus = await listener.RequestAccessAsync();
 
switch (accessStatus)
{
    // This means the user has granted access.
    case UserNotificationListenerAccessStatus.Allowed:
 
        // Yay! Proceed as normal
        break;
 
    // This means the user has denied access.
    // Any further calls to RequestAccessAsync will instantly
    // return Denied. The user must go to the Windows settings
    // and manually allow access.
    case UserNotificationListenerAccessStatus.Denied:
 
        // Show UI explaining that listener features will not
        // work until user allows access.
        break;
 
    // This means the user closed the prompt without
    // selecting either allow or deny. Further calls to
    // RequestAccessAsync will show the dialog again.
    case UserNotificationListenerAccessStatus.Unspecified:
 
        // Show UI that allows the user to bring up the prompt again
        break;
}

It's either that or writting the registry.

As well as assigning an AppUserModelID
User avatar
khanhas
Posts: 40
Joined: October 26th, 2016, 5:00 pm

Re: Windows Notification Toaster

Post by khanhas »

kyriakos876 wrote: November 6th, 2018, 5:58 pm Hey khanhas, sorry if I'm being annoying, but I'm trying to make your EncodeVar function return null if a variable is empty or if it's not defined at all (with your code it returns the name of the variable between ##)
Since Rainmeter API of plugins doesn't expose get variable and measure value function, I have to use ReplaceVariables which requires to use same syntax in Rainmeter INI (#variableName#, [measureName] as input to get their value. If variable or measure don't exist, ReplaceVariables just simply return the input string.
I did a quick fix and published it in 0.3.2, download and install new version here: https://github.com/khanhas/PowershellRM/releases
From now, you can check against $null to know variable exist or not:

Code: Select all

function EncodeVar {
  param([string]$name)
  $variableValue = $RmAPI.VariableStr($name)
  If ($null -eq $variableValue) {
    return $null
  }

  return [System.Web.HttpUtility]::HtmlEncode($variableValue)
}
Thank you, btw.
kyriakos876 wrote: November 6th, 2018, 5:58 pm Also, if something is changed in the .ps1 script's code I have to refresh the to re-parse the script file... any idea how can I change the code and be able to apply the changes without refreshing the skin?
Sorry, it's not possible. I wonder why you need it
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Windows Notification Toaster

Post by kyriakos876 »

khanhas wrote: November 7th, 2018, 5:29 pm Since Rainmeter API of plugins doesn't expose get variable and measure value function, I have to use ReplaceVariables which requires to use same syntax in Rainmeter INI (#variableName#, [measureName] as input to get their value. If variable or measure don't exist, ReplaceVariables just simply return the input string.
I did a quick fix and published it in 0.3.2, download and install new version here: https://github.com/khanhas/PowershellRM/releases
From now, you can check against $null to know variable exist or not:

Code: Select all

function EncodeVar {
  param([string]$name)
  $variableValue = $RmAPI.VariableStr($name)
  If ($null -eq $variableValue) {
    return $null
  }

  return [System.Web.HttpUtility]::HtmlEncode($variableValue)
}
Thank you, btw.


Sorry, it's not possible. I wonder why you need it
Thanks for the null addition.

I want to do that because in the notification you can have more than one buttons. But to do that you need to write a line in the XML. If you write the line but don't define the arguments, a blank button box is displayed. Thus I check if for example "NotificationButtonName5" is defined. If it is I write the line for the button5. But this works only if I refresh the skin after re-doting the powershell script. I hope you understand what I mean.
User avatar
khanhas
Posts: 40
Joined: October 26th, 2016, 5:00 pm

Re: Windows Notification Toaster

Post by khanhas »

So make a function, probably is similar as EncodeVar, that null-check Rainmeter variable then return `<action ...></action>` code block as string if variable is available. Else returns a blank string or $null

Then use it in $ToastTemplate:

Code: Select all


...
<actions>
    <action content="$ButtonNameVar" arguments="$ButtonActionVar" activationType="protocol"/>
    $Button2
    $Button3
</actions>
User avatar
khanhas
Posts: 40
Joined: October 26th, 2016, 5:00 pm

Re: Windows Notification Toaster

Post by khanhas »

About Listener API you posted earlier, you actually can use it Powershell:

Code: Select all

[Windows.UI.Notifications.Management.UserNotificationListener, Windows.UI.Notifications, ContentType = WindowsRuntime]

$listener = [Windows.UI.Notifications.Management.UserNotificationListener]::Current
$accessStatus = $listener.GetAccessStatus()

switch($accessStatus)
{
  "Allowed" { 
    $RmAPI.Log("Yay! Proceed as normal") 
  }
  "Denied" {
    $RmAPI.Log("Access denied")
  }
  "Unspecified" {
    $RmAPI.Log("Do something, idk")
  }
}