Windows.System.User events not being raised in UWP - c#

I am trying to have some logic when Windows user is being changed while my UWP app is running and for that in my OnLaunchApplicationAsync method I have:
var userWatcher = Windows.System.User.CreateWatcher();
userWatcher.AuthenticationStatusChanged += AuthenticationStatusChanged;
and I also have
private void AuthenticationStatusChanged(Windows.System.UserWatcher sender, Windows.System.UserChangedEventArgs args)
{
// Some logic
}
But the problem is that when I log off with my current user and sign in with another one, the expected event is not being raised.
I have also tried out userWatcher.Updated for updating user data as well as userWatcher.AuthenticationStatusChanging with the same result.
Am I doing this in a wrong way?

You need to start the watcher, otherwise these events are not fired.

Related

Is there an ExecuteWhenThisThreadIsIdle method?

I've run into this several times. My app receives some event (e.g. WndProc) and needs to return quickly. The code that needs to run takes some time, and does not need to be executed before returning from the event handler.
My current solution is to start a timer for a short time, and in the Tick event - run that code.
But that seems like the wrong tool for this case, and is prone to some errors (like running the code more than once, for example).
So, is there any ExecuteWhenThisThreadIsIdle scheme?
EDIT
A C#/.NET solution would be best, but a framework specific solution would be welcome too. Mainly Winforms. (But also WPF, UWP, Xamarin.Forms, ...)
The code needs to run on the same thread as the event handler. (Usually the UI thread.)
In WinForms, you can subscribe to Application.Idle.
For example ...
private bool _wndProcEventHooked = false;
protected override void WndProc(ref Message m) {
// Run your code here
}
private void Application_Idle(Object sender, EventArgs e) {
if (!this._wndProcEventHooked) {
// Hook your wndProc event here.
this._wndProcEventHooked = true;
}
}
In WPF this can be done using DispatcherTimer:
var timer = new DispatcherTimer
(
TimeSpan.FromMinutes(10),
DispatcherPriority.ApplicationIdle,// Or DispatcherPriority.SystemIdle
(s, e) => MessageBox.Show("Timer"),
Application.Current.Dispatcher
);

C# Trouble with event handlers on dieing threads

First of all my Main is STAThread and i am not able to change this without facing problems with the rest of my code.
So, I am currently using Rapi2 To pull and push files between my Pda and Computer. Now since there is quite a bit of number crunching i would like to do this on a separate thread. First wat i do is create an RemoteDeviceManager and then make an Event Handler for when a device connects.
public void Initialize()
{
_deviceManager = new RemoteDeviceManager();
_deviceManager.DeviceConnected += DeviceConnected;
}
As you can see when my device connects it triggers DeviceConnected.
This is the class that i end up pulling and pushing a database and do some number work.
private void DeviceConnected(object sender, RemoteDeviceConnectEventArgs e)
{
if (e.Device == null) return;
... (unimportant code)
}
Now the problem here is that i would want to run the code inside DeviceConnected in a new thread but i am unable to access e inside the new thread since it was initialized outside that thread
So now wat i tried was make a new thread before calling Initialize.
public Watcher()
{
_dataThread = new Thread(Initialize);
_dataThread.IsBackground = true;
_dataThread.Name = "Data Thread";
_dataThread.SetApartmentState(ApartmentState.MTA);
_dataThread.Start();
}
But the thread dies and thus never fires my event handler.
I tried many different ways to make it work or keep my thread alive but without any success. I hope someone here is able to give me some hints.

AppDomain.CurrentDomain.DomainUnload not be raised in Console app

I have an assembly that when accessed spins up a single thread to process items placed on a queue. In that assembly I attach a handler to the DomainUnload event:
AppDomain.CurrentDomain.DomainUnload += new EventHandler(CurrentDomain_DomainUnload);
That handler joins the thread to the main thread so that all items on the queue can complete processing before the application terminates.
The problem that I am experiencing is that the DomainUnload event is not getting fired when the console application terminates. Any ideas why this would be?
Using .NET 3.5 and C#
Unfortunately for you, this event is not raised in the default AppDomain, only in app domains created within the default one.
From the MSDN documentation:
This event is never raised in the
default application domain.
You'll need to subscribe the event for the specific domain. You also can't rely on the domain get unloaded at termination time. Remove the comment from this code to see that:
using System;
using System.Reflection;
class Program {
static void Main(string[] args) {
var ad = AppDomain.CreateDomain("test");
ad.DomainUnload += ad_DomainUnload;
//AppDomain.Unload(ad);
Console.ReadLine();
}
static void ad_DomainUnload(object sender, EventArgs e) {
Console.WriteLine("unloaded, press Enter");
Console.ReadLine();
}
}

Silverlight 4 Clipboard Security Exception "access is not allowed"?

I'm new in Silverlight and i am doing some tests. With my current test I try to display in real time the current Clipboard content. But there is a weird behaviors with this code :
namespace SilverlightTest
{
public partial class MainPage : UserControl
{
private Timer _timer;
public MainPage()
{
InitializeComponent();
var dispatcher_timer = new DispatcherTimer {Interval = new TimeSpan(0, 0, 0, 5)};
dispatcher_timer.Tick += new EventHandler(timer_Callback);
dispatcher_timer.Start();
}
private void timer_Callback(object state, EventArgs eventArgs)
{
current_clip_board.Content = Clipboard.GetText();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
current_clip_board.Content = Clipboard.GetText();
}
}
}
The button Event and the timer Event are suppose to do exactly the same action.
But it doesn't ! The Button works fine and set the clipboard text into the label but the timer throw an exception :
Clipboard access is not allowed
The question is : why ? :)
Thanks.
PS : I would bet on a thread problem :p
Clipboard access, in a partial trust (in-browser) Silverlight application (the scenario you're likely referring to above), is restricted. The GetText property is accessible only in scenarios that the Silverlight runtime determines were initiated by the user. Your example is perfect -- by a button click for example. A dispatch timer however is not user initiated, so the property throws an exception (this is especially important within the context of a in-browser application, which could be a big security hole if you could create a Silverlight application that just ran silently in the browser, watching the user's clipboard updates without their knowledge).
See this clipboard documentation for more details.
Just trigger Clipboard.ContainsText() instead of Text. The method ContainsText is allowed!
Have you tried this:
private void timer_Callback(object state, EventArgs eventArgs)
{
Dispatcher.Invoke(new System.Threading.ThreadStart(delegate()
{
current_clip_board.Content = Clipboard.GetText();
}
}
edit
After a quick search, it appears that Clipboard is only available in response to a user action see here and here.
In partial trust (the default mode for
browser-hosted Silverlight-based
applications), Silverlight also
restricts clipboard access to its two
key APIs GetText and SetText. These
APIs can only be invoked from within a
context that is determined by the
Silverlight runtime to be in response
to a user-initiated action. For
example, clipboard access is valid
from within a handler for a Click or
KeyDown event. In contrast, clipboard
access is not valid from a handler for
Loaded or from a constructor, and
access attempts throw exceptions.
If your only option is to use a timer, then don't do it at all. The clipboad is a shared resource, and you're going to raise "cannot open clipboard" errors in other programs as they try to access the clipboard. i.e. user copies something from WinWord, WinWord tries to open the clipboard, but can't, because you've got it locked while you're examining it.
Hello this works for me but only in IE Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() => HtmlPage.Window.Eval("window.clipboardData.setData('Text','testtestest')"));
just use getData method

Get Windows Server shutdown reason in C#

Is it possible to get shutdown reason in Windows Server 2008 immediately after user choose the reason in dialog window? For the shutdown event I'm using SystemEvents.SessionEnding.
I want to write windows service, which will send e-mail about this event.
Or is there any other way in windows server to send e-mails about shutdown/restart event with getting the reason entered by user? Also, I want to notify about power source change (electic line/battery), but this I have already solved by Kernel32.dll > GetSystemPowerStatus.
You can get the shutdown reason inspecting the EventLog.
I assembled a quick demo on Windows Forms that you can adapt to your Windows service.
I've added a EventLog component to the Form and configured it properly. The snippet below shows the code generated in InitializeComponent() for the settings I've maid through the designer.
this.eventLog1.EnableRaisingEvents = true;
this.eventLog1.Log = "System";
this.eventLog1.Source = "USER32";
this.eventLog1.SynchronizingObject = this;
this.eventLog1.EntryWritten += new System.Diagnostics.EntryWrittenEventHandler(this.eventLog1_EntryWritten);
On the event handler, you'll have something along the following lines:
private void eventLog1_EntryWritten(object sender, System.Diagnostics.EntryWrittenEventArgs e)
{
EventLogEntry entry = e.Entry;
if (e.Entry.EventID == 1074)
{
File.AppendAllText(#"c:\message.txt", entry.Message);
}
}
Take a look at your event log to see the appropriate EventIds to filter out.
The compiler will warn you about EventID being deprecated and telling you that you should use InstanceId, but in the quick tests I've done here, it didn't write to my log file and I think we already have enough information to put you on track.
sure it's possible.
in case you want to get that comboBox value in real-time, you will need to run a Thread monitor on that process to raise an event when that value change.

Categories