Sending keystroke to active application not working in Xamarin.Mac - xamarin

I'm trying to send keystrokes to the active application using Visual Studio Mac. I followed this answer: SendKeys for Xamarin.Mac
using (var eventSource = new CGEventSource(CGEventSourceStateID.HidSystem))
{
var eventString = "1234";
foreach (var eventChar in eventString)
{
ushort key;
if (eventChar == ' ')
key = (ushort)NSKey.Space;
else
key = (ushort)(NSKey)Enum.Parse(typeof(NSKey), eventChar.ToString().ToUpper());
using (var keyEvent = new CGEvent(eventSource, key, true))
{
CGEvent.Post(keyEvent, CGEventTapLocation.HID);
}
using (var keyEvent = new CGEvent(eventSource, key, false))
{
CGEvent.Post(keyEvent, CGEventTapLocation.HID);
}
}
}
Basically there's no real magic following other samples in other languages, however the keystrokes are just ignored.
Is there anything additional to think of, like sandboxing or something else? I'm running my application in Debug mode.
I tried already sending the events from the main UI thread as well as from a background thread. However, the keystrokes are just ignored.

Related

Where is the list of device driver images stored in ETW?

I am trying to programatically get the list of device drives from an ETW with the great TraceProcessing Library which is used by WPA.
using ITraceProcessor processor = TraceProcessor.Create(myEtlFile, new
TraceProcessorSettings
{
AllowLostEvents = true,
AllowTimeInversion = true,
});
myProcesses = processor.UseProcesses();
foreach (var process in myProcesses.Result.Processes)
{
foreach (var dll in process.Images)
{
// get dll.Path, dll.FileVersion, dll.ProductVersion, dll.ProductName, dll.FileVersionNumber, dll.FileDescription
}
}
This works for every process except the Kernel (System(4)). Why do I have only 3 dlls in the System process? I would expect the driver files in the System process there as well. In CPU sampling the image is there so it looks like everything is right there.
This would be very useful to check for driver versions if the data is present. But so far I was not able to find it. Am I missing something here?
Happy to hear you enjoy using the TraceProcessor library!
Device drivers are logged against the "Idle (0)" process by ETW, here is an example:
using var tp = TraceProcessor.Create(#"trace.etl");
var processes = tp.UseProcesses();
tp.Process();
var idleProcess = processes.Result.Processes.FirstOrDefault(x => x.Id == 0);
foreach (var image in idleProcess?.Images)
{
Console.WriteLine(image.Path);
}

Windows Application Driver, error "Could not find any recognizable digits." when connecting to session (driver)

I know how to launch a windows application using the filepath to launch it and that works (working example below). I am writing tests and they work too but my question is this: If the application is running already, how do I create my "session" (often called "driver") for the currently running application?
I have read this article that explains how you would connect a new session to Cortana which is already running. It's a great example but my app is an exe that has been launched and is not part of windows and I'm getting the error "Could not find any recognizable digits.".
What am I doing wrong?
WORKING CODE THAT LAUNCHES THE APP AND CREATES THE "session":
private const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
protected static WindowsDriver<RemoteWebElement> session;
public static void Setup(TestContext context)
{
// Launch app and populate session
if (session == null)
{
// Create a new sessio
DesiredCapabilities appCapabilities = new DesiredCapabilities();
appCapabilities.SetCapability("app", filepath /*The exeecutable's filepath on c drive*/);
//LaunchWPF app and wpf session
session = new WindowsDriver<RemoteWebElement>(new Uri(WindowsApplicationDriverUrl), appCapabilities);
session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
}
}
PROBLEM CODE :
[TestMethod()]
public void Common_CreateSession_ForAlreadyRunningmyApp()
{
string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
IntPtr myAppTopLevelWindowHandle = new IntPtr();
foreach (Process clsProcess in Process.GetProcesses())
{
if (clsProcess.ProcessName.Contains("MyApp.Client.Shell"))
{
myAppTopLevelWindowHandle = clsProcess.Handle;
}
}
DesiredCapabilities appCapabilities = new DesiredCapabilities();
appCapabilities.SetCapability("appTopLevelWindow", myAppTopLevelWindowHandle);
//Create session for app that's already running (THIS LINE FAILS, ERROR: : 'Could not find any recognizable digits.')
session = new WindowsDriver<RemoteWebElement>(new Uri(WindowsApplicationDriverUrl), appCapabilities);
session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
}
}
There's now an answer on github here. You can see on github I have made 3 tweaks to the answer given by moonkey124, 2 of them were obvious (my aplication name and a little sleep command), 1 of them was to adapt the answer to a WPF application under test...

How to start the app that is associated to the IBackgroundTask I've created in UWP Windows 10

I implemented an IBackgroundTask on Universal Windows 10 and it works like a charm but the problem is that i want to start the app that is associated to that background task if some action occurs. The code is simple:
public sealed class AdvertisementWatcherTask : IBackgroundTask
{
private IBackgroundTaskInstance backgroundTaskInstance;
public void Run(IBackgroundTaskInstance taskInstance)
{
backgroundTaskInstance = taskInstance;
var details = taskInstance.TriggerDetails as BluetoothLEAdvertisementWatcherTriggerDetails;
if (details != null)
{
//Do things
}
}
}
I've seen that you can create a ToastNotification like that:
Windows.Data.Xml.Dom.XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);
Windows.Data.Xml.Dom.XmlNodeList elements = toastXml.GetElementsByTagName("text");
foreach (IXmlNode node in elements)
{
node.InnerText = taskInstance.Task.Name+ " remember to uninstall task if not debugging";
}
ToastNotification notification = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier().Show(notification);
The notification toast works good. It creates and prompts a notification and if you click it, the app that created this background task starts. This is the behaviour that I want but I want to start the app without having to click any notification. Is there any way to achieve this? Thank you.
TL;DR: I want to start the app that created the background task at some point of the code.
You can not programmatically launch URI or open app from background task. You can however display a reminder or toast notification to let user open your app.

Geofence is not being triggered in the background in windows phone 8.1

I'm trying to implement geofencing in Windows phone 8.1. First I wanted to create a sample Project to understand how it Works, but i couldnt make it works. What I'm trying to achieve is basically, I'll set the coordinates and close the app by pressing back button and it will trigger a toast notification when the phone is in the area of interest.
I've created a blank Windows phone(silverlight) 8.1 Project(geofence_test_01) and added a Windows RT Component Project(BackgroundTask) into the same solution. Added a reference for BackgroundTask in the geofence_test_01 Project.
ID_CAP_LOCATION is enabled in the app manifest.
MainPage.xaml has only one button to start geofencing.
<Button Name="btnStart" Content="Start" Click="btnStart_Click"/>
In btnSave_Click, I call a method which creates the geofence and registers the background task.
private void btnStart_Click(object sender, RoutedEventArgs e)
{
Init_BackgroundGeofence();
registerBackgroundTask();
}
private async Task Init_BackgroundGeofence()
{
//----------------- Crating Geofence ---------------
var geofenceMonitor = GeofenceMonitor.Current;
var geoId = "building9";
var positionBuilding9 = new BasicGeoposition()
{
Latitude = 47.6397,
Longitude = -122.1289
};
var geofence = new Geofence(geoId, new Geocircle(positionBuilding9, 100),
MonitoredGeofenceStates.Entered | MonitoredGeofenceStates.Exited,
false, TimeSpan.FromSeconds(10));
geofenceMonitor.Geofences.Add(geofence);
}
private async Task registerBackgroundTask()
{
//----------------- Register Background Task ---------------
var backgroundAccessStatus =
await BackgroundExecutionManager.RequestAccessAsync();
var geofenceTaskBuilder = new BackgroundTaskBuilder
{
Name = "GeofenceBackgroundTask",
TaskEntryPoint = "BackgroundTask.GeofenceBackgroundTask"
};
var trigger = new LocationTrigger(LocationTriggerType.Geofence);
geofenceTaskBuilder.SetTrigger(trigger);
var geofenceTask = geofenceTaskBuilder.Register();
}
And finally, in BackgroundTask, I've the following code:
namespace BackgroundTask
{
public sealed class GeofenceBackGroundTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
var geofenceMonitor = GeofenceMonitor.Current;
var geoReports = geofenceMonitor.ReadReports();
var geoId = "building9";
foreach (var geofenceStateChangeReport in geoReports)
{
var id = geofenceStateChangeReport.Geofence.Id;
var newState = geofenceStateChangeReport.NewState;
if (id == geoId && newState == GeofenceState.Entered)
{
//------ Call NotifyUser method when Entered -------
notifyUser();
}
}
}
private void notifyUser()
{
var toastTemplate = ToastTemplateType.ToastText02;
var toastXML = ToastNotificationManager.GetTemplateContent(toastTemplate);
var textElements = toastXML.GetElementsByTagName("text");
textElements[0].AppendChild(toastXML.CreateTextNode("You are in!"));
var toast = new ToastNotification(toastXML);
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
}
}
I get no error when building and deploying this in the emulator. I set a breakpoint in the backgroundTask but I've not seen that part of code is called yet. It never hits the breakpoint. I test it by using Additional Tools of the emulator, in Location tab, by clicking somewhere in my geofence area on the map, waiting for a while, but it never hits the breakpoint. Hope somebody can tell me what i am missing here...
I've checked these following links to build this application:
http://www.jayway.com/2014/04/22/windows-phone-8-1-for-developers-geolocation-and-geofencing/
Geofence in the Background Windows Phone 8.1 (WinRT)
Toast notification & Geofence Windows Phone 8.1
http://java.dzone.com/articles/geofencing-windows-phone-81
Thanks
You can download the project here:
https://drive.google.com/file/d/0B8Q_biJCWl4-QndYczR0cjNhNlE/view?usp=sharing
---- Some clues
Thanks to Romasz, I've checked the Lifecycle events and i see "no background tasks" even after registerBackgroundTask() is executed.... Apparently there is something wrong/missing in registerBackgroundTask() method.
I've tried to build my sample (it was easier for me to build a new one) basing on your code and it seems to be working. You can take a look at it at my GitHub.
There are couple of things that may have gone wrong in your case:
remember to add capabilities in WMAppManifest file (IS_CAP_LOCATION) and Package.appxmanifest (Location)
check the names (of namespaces, classes and so on) in BackgroundTask
check if your BackgroundTask project is Windows Runtime Componenet and is added to your main project as a reference
I know you have done some of this things already, but take a look at my sample, try to run it and maybe try to build your own from the very beginning.
Did you add your background task in the Package.appxmanifest under Declarations with the correct supported task types (Namely Location)?

Is there a way to check if a user has really rated your app?

I'm writing a WP7 application and I have code to ask the user for a marketplace review every five runs with an exponential back off so it is less annoying. If the user clicks 'ok' on my "would you like to review" message box, I launch the review task and I store that the user has reviewed the application so I don't ask again.
var marketplaceReviewTask = new MarketplaceReviewTask();
marketplaceReviewTask.Show();
IsolatedStorageSettings.ApplicationSettings["HasReviewed"] = true;
However, while it's likely they did rate the app, I'm actually not a 100% sure they did. Is there a way to check if the current user really has written a review? Does the MarketplaceReviewTask() have a returnvalue? I haven't been able to find anything that indicates I can listen for it.
No, MarketplaceReviewTask does not have any events which return a value. A case with most of the Launcher tasks. Chooser tasks have events to collect the information. Like #willmel said in the comment, it does look like an invasion of privacy.
You can create a check which will check locally if user has rated the application earlier or not. Take a look at following code:
public void reviewfunction()
{
//For Windows phone 8 app
var settings = IsolatedStorageSettings.ApplicationSettings;
//For windows phone 8.1 app or universal app use the following line of code
//var settings = Windows.Storage.ApplicationData.Current.LocalSettings;
//set the app name
string Appname = "My app";
if (!settings.Contains("review"))
{
settings.Add("review", 1);
settings.Add("rcheck", 0);
}
else
{
int no = Convert.ToInt32(settings["review"]);
int check = Convert.ToInt32(settings["rcheck"]);
no++;
if ((no == 4 || no == 7 || no % 10 == 0) && check == 0)
{
settings["review"] = no;
MessageBoxResult mm = MessageBox.Show("Thank you for using this application.\nWould you like to give some time to rate and review this application to help us improve", Appname, MessageBoxButton.OKCancel);
if (mm == MessageBoxResult.OK)
{
settings["rcheck"] = 1;
MarketplaceReviewTask rr = new MarketplaceReviewTask();
rr.Show();
}
}
else
{
settings["review"] = no;
}
}
}
Hope this helps you. Source code can be downloaded from here.

Resources