I would like to use the LaunchUriForResultAsync to launch my other app and get some results from it. But I want to launch the other app in full screen and if that's not possible maybe just launch it in a bigger size.
When I launch another app using LaunchUriForResultAsync, the modal app launches in 500x500 size. I would need something bigger than that because I need to create a data entry app that requires more space which multiple applications can launch. I tried to set the DesiredRemainingView and PreferredLaunchWindowingMode to FullScreen. It didn't make my other app launch in full screen.
Is there a way I can use LaunchUriForResultAsync to launch my other app in full screen?
If the device is in Tablet Mode, you can use ViewSizePreference.SizeNone and the app will be launched in full screen:
var options = new Windows.System.LauncherOptions();
options.DesiredRemainingView = Windows.UI.ViewManagement.ViewSizePreference.UseNone;
await Windows.System.Launcher.LaunchUriAsync(uri, options);
I think part of the confusion here is that the size preference defines the space your current app desires, not the size you want for the launched app. Because the target app can have its own preferences.
This solution does not work if Tablet Mode is disabled, then you would have to go with a solution as Rob Caplan suggested.
It is not possible to control the size of the window launched for results. In current versions of Windows this size is hard coded to 500x500. Providing a way to allow an app to control this is being investigated for future a future update.
Since you control both apps you could write a custom system to manage the communication rather than use LaunchUriForResultAsync. AppA and AppB can each define their own protocols (appa: and appb:). AppA can LaunchUriAsync appb: to do whatever it needs, then AppB can LaunchUriAsync appa: to deliver the results. Pass AppA's return URL as an argument to appb: and this can be called from multiple apps.
The trickiest part may be to manage the modality. It's easy to disable AppA's page while it's waiting, but harder to link AppB's window to AppA's after the initial launch. Off the top of my head I'd just relaunch appb: and make sure appb: can track and handle multiple launches sanely.
This is more or less what LaunchUriForResultAsync does for you.
Related
We have a simple launcher.cmd script that sets up some prerequisites (network shares, configuration files etc.), depending on command-line arguments, and then starts a third-party application.
It also launches a custom splash screen (Windows Forms application), but that doesn't have any functionality beyond the splash screen. The external application also contains a plugin that we have written.
Imagine something like this:
set appEnvironment=%1
MyCustomSplashScreen\MyCustomSplashScreen.exe %appEnvironment%
net use X: /delete /yes
net use X: \\someserver\%appEnvironment%
copy Configuration\%appEnvironment%.config ExternalApp\ExternalApp.MyPlugin.config
start ExternalApp\ExternalApp.exe
It is invoked like this:
launcher.cmd Production
The challenge we are facing is that some users pin ExternalApp.exe (the actual application, after launcher.cmd and the splash screen have terminated) to the taskbar. The taskbar shortcut then launches ExternalApp.exe directly and not our launcher script - so all kinds of strange things can happen.
As we have control over the plugin, it would be possible to move some of the logic directly into ExternalApp.exe, but that wouldn't solve the issue of losing the environment parameter. The best solution I can come up with would be different ways of making sure the application can only be launched via the launcher script, essentially making it useless for the user to pin the application to the taskbar.
However, I have thought about being a little more creative. I am planning to do the following:
Move the launcher.cmd logic into MyCustomSplashScreen.exe
In MyCustomSplashScreen.exe, start ExternalApp.exe and make it a docked child window (cf. Docking Window inside another Window ).
Instead of using a parameter, create copies (or links) of MyCustomSplashScreen.exe that reflect the environment, e.g. Launch_Production.exe, Launch_Staging.exe etc.
The consequence would be that only MyCustomSplashScreen would appear on the taskbar and be pinnable. Pinning the application would result in the application specific to that environment (e.g. Launch_Staging.exe) being pinned, just what the user expects.
I am quite confident that this would work. But maybe there is a simpler solution? What I'm looking for is some way to make only my launcher application on the taskbar and not the application it launches.
I found similar questions here and here where it was suggested to manipulate the pinning process itself. Maybe that's a better solution? I'm just not sure if my plugin has enough control over ExternalApp.exe to implement this, so would need to test it.
The solution from Control path to pinned exe in Windows taskbar and start menu works just fine.
I put something like this into my plugin and it does exactly what I want:
private static void SetTaskbarRelaunchCommand(string environment)
{
// WARNING, once RelaunchCommand has been set it can't be changed for any given appID.
// Workaround: delete all links here related to our app.
// %AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\ImplicitAppShortcuts
// %AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar
// Source: https://stackoverflow.com/a/28388958/33236
const string appID = "MyAppID";
string path = $#"C:\Launcher.exe {environment}";
IntPtr windowHandle = Process.GetCurrentProcess().MainWindowHandle;
var propGuid = new Guid("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}");
var id = new PropertyKey(propGuid, 5); // System.AppUserModel.ID
var relaunchCommand = new PropertyKey(propGuid, 2); // System.AppUserModel.RelaunchCommand
var relaunchDisplayNameResource = new PropertyKey(propGuid, 4); // System.AppUserModel.RelaunchDisplayNameResource
WindowProperties.SetWindowProperty(windowHandle, id, appID);
WindowProperties.SetWindowProperty(windowHandle, relaunchCommand, path);
WindowProperties.SetWindowProperty(windowHandle, relaunchDisplayNameResource, $"My App {environment}");
}
It seems like the original version of the Windows API CodePack published by Microsoft in 2009 is no longer officially available. Instead there are a dozen inofficial NuGet packages that (claim to) contain the original library, as well as some where bugs have been fixed.
I ended up using this NuGet package as it seems to be actively maintained.
Of course I am in the fortunate situation that I could manipulate the behavior of the external application through my plugin. Without this, there probably is no other solution than running the application as a docked child window.
UPDATE: It seems like there is another way to achieve thisn when you cannot control the application you're launching. You simply set the System.AppUserModel.Id for the launched application's window. More details here.
I wasn't successful in setting the RelaunchCommand and the RelaunchDisplayNameResource on the newest Windows 10 update. But i have found another possibility to set that the Launcher is pinned to the taskbar: Pinning to the taskbar a "chained process"
I have an app that needs to create a pop up to notify the user of something, even when the app is closed. I would like it to be fullscreen, but if that's not possible, a pop up that takes up most of the screen will do. I don't know how to make part of the app run in the background on Android and iOS to check if it's time for the pop up. I also don't know how to go about making the actual pop up. Any help would be greatly appreciated!
Side notes: I am using a cross platform Xamarin.Forms app. I have a main page that the user can set the time they want the pop up to appear, and I save this to the Application.Current.Properties dictionary for data persistence.
Background tasks on mobile has quite a lot of limitations. Which is logical. The user would not like if some app will always run in background and collect user data, drain the battery or affect overal performance of the the mobile device. Therefore for there are strict set of rules every developer must follow when creating a background tasks.
You best bet would be to use local notifications, there is a well documented open source library that you can use for this. There will be no pop-ups but notifications which you could customize according to OS guides.
I'd like to make my own custom program run on windows 10 in replacement of the start screen and logon screen.
Is there any way I can do this? I've currently replaced the accessibility program (accessible from the logon screen) with a command prompt, if I accidentally lock myself out (it has happened once!).
I recall seeing a particular Winlogon.exe. Is this my starting point? Am I able to replace the program that windows runs with my own?
Also, wrapping up, If I manage to replace this program, can I logon to windows in my program? I'm writing it in c#.
Old post, but still relevant...
I don't know if you can, or should replace it, but you could write an overlaying app to cover it and do it's own thing, if you can use a little windows command-line magic combined with node.js. More of a work-around, but then you won't chance destroying any os-specific functionality, and it seems to be universal from Vista on up (to my knowledge at least). Here is how you can get your starting point to run a GUI app on the logon screen.
Node-Windows - Run GUI app on Logon screen
You can use this technique to run any app in any language that you can open it's window from a command-line.
There will be a brief period where the normal logon screen will be visible before your app starts, but this will let you do it.
Whatever language you use for your logon GUI, you will need to send simulated key input to the real logon screen, possibly mouse-clicks-- but you can likely use simulated tabs to get to the right logon. Likely MS has API's for C# as well as a variety of related dialects to programmatically logon to the desktop in a more elegant fashion than this last part, however.
Your app will be running as the SYSTEM user (unless you specify otherwise), therefore it will be running with the highest authority-- so you can basically do anything that is possible from there. Permissions won't stop you. Be careful with this.
I'm building a console app which will connect to different computers in the network and take browser screenshots of a webpage.
Using Selenium 2.47.1 to set up server & nodes. The console app runs in the PC which is set up as selenium hub.
The screenshot is fine in firefox,chrome,ie from the hub computer.
The screenshot is also fine in firefox in remote pc.
But with IE it returns a black image.
Both the hub and node computers run on windows 7 64-bit, have IE11. I am using the 64bit IEDriver in both PCs.
The node computer is not locked.
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;
static void Main(string[] args)
{
IWebDriver NewDriver = null;
using (NewDriver = new RemoteWebDriver(new Uri("http://172.165.10.111/wd/hub"), DesiredCapabilities.InternetExplorer()))
{
if (NewDriver != null)
{
NewDriver.Navigate().GoToUrl("http://www.google.com");
NewDriver.Manage().Window.Size = new Size(1804, 1096);
Screenshot ss = ((ITakesScreenshot)NewDriver).GetScreenshot();
ICapabilities capabilities = ((RemoteWebDriver)NewDriver).Capabilities;
ss.SaveAsFile(#"C:\Path\123.png", ImageFormat.Png);
NewDriver.Quit();
}
}
}
It's because your screen is locked, or a screensaver is running.
You will need to turn off your screensaver and configure windows to never lock itself when not in use. To turn off your screensaver:
Click the Start button.
Click Control Panel.
In the search box, type screen saver.
Click Turn screen saver on or off.
Then modify your screensaver settings. Make sure you have unchecked "On resume, display logon screen".
While you're in the control panel it's probably worth checking the power options and making sure the machine isn't going to sleep or powering down after a set period of time as well.
You will also want to use VNC or remote assist to access the GUI. If you RDP in it will lock the screen for the local user who is currently logged in and again it will lock the screen when you disconnect.
Finally don't use the 64-bit IE driver, you should be using the 32Bit one. Nobody runs the 64Bit version of IE (even if they have a 64Bit capable machine).
****** Edit
Adding a bit more info from a credible and reputable source ******
Below is a link to a post on the Selenium users forum where Jim Evans (the developer who wrote the IEDriver binaries) explains this:
http://selenium.10932.n7.nabble.com/IE-Screenshots-are-black-when-not-connected-via-Remote-Desktop-to-the-VM-hosting-an-IE-Node-td37004.html
This quote in particular about taking screenshots when you have disconnected from a RDP instance:
It's a known limitation. There is no known workaround. Complain to
Microsoft. They're the ones that make the PrintWindow API (which is
the proper API to use when grabbing screen captures) behave that way.
Either that, or if you discover a way to make it work, you're welcome
to submit a patch.
He explains how the screenshot code works in more detail on his blog here:
http://jimevansmusic.blogspot.co.uk/2014/09/screenshots-sendkeys-and-sixty-four.html
Specifically:
The IE driver takes screenshots using the PrintWindow API function.
PrintWindow can only take a screenshot of the visible portion of any
given window, which means that in order to get a full-page screenshot
(as required by the WebDriver API), the window must be sized large
enough to display the entire page without scroll bars. However,
Windows does not allow the window to be resized larger than the
visible screen resolution. When we ask IE to resize itself, a
WM_GETMINMAXINFO message is sent on a resize event so the IE can
figure how large a window can be. By intercepting that message with a
hook, and modifying the max values, we can trick IE into thinking that
a window can be sized greater than the screen resolution would
otherwise allow.
It looks like this might be a known issue with configuration:
https://code.google.com/p/selenium/issues/detail?id=3536
From what #ShubhasmitGupta mentioned above, it does look like the IE driver hands out black-screen screenshots when the desktop is locked (I'm assuming this has something to do with DWM/Explorer not rendering windows).
There's a workaround involving not locking the targeted computer when connecting to it via RDP. Essentially, you create a disconnect.bat file with the following contents:
tscon rdp-tcp#0 /dest:console
I'm not sure exactly when that's supposed to be run, but the concept is to prevent the test computer from being locked when connecting via Remote Desktop. If that helps, great; I haven't been able to test the workaround myself and figure out how to set it up. Maybe someone else can write a more concise answer.
Open up the Service Control Manager -- You can do WindowsKey+R (run) and type services.msc and hit <ENTER> and it'll start up.
Find the service and right click it and choose properties from the context menu.
Allow Service to Interact With Desktop
Now, select the Log On tab.
You want to make sure the checkbox is selected for "Allow service to interact with the desktop".
You can see it in the image below.
Note: I don't have that service so I just picked another one in the sample picture.
you may want to try removing below line
//NewDriver.Manage().Window.Size = new Size(1804, 1096);
maximize your browser instead.
NewDriver.Manage().Window.Maximize();
I have had a sneaky suspicion that IE has been rendering with DirectX for some time and this article certainly seems to indicate that this is the case... which would explain why you'd have problems as GDI based screen grabs won't work with DirectX surfaces.
I'm saying this is an absolute... just a hunch
I had the same issue a while back, and though I don't completely understand the problem it was basically that the process executing selenium was running under a system account and thus the IE gui was visible only in session 0, whereas session 1 was showing only a black screen.
The solution which worked for me was to create a local user account on the remote host, keep that user permanently signed in and unlocked so that they have an interactive desktop available, then run your selenium app/tests as that user. I know that is not ideal, but as we had dozens of old boxes lying around, it didn't hurt to use one as a dedicated test server. Hope that helps somewhat!
Sorry, not enough rep to add this as a comment.
Perhaps an interesting hint...
...working with Selenium 2.47.x and 2.52.0 Jenkins, RDP and IE 11 in mode IE 7 (setting by website) on the server Win 2008. Additional to this, I have to screens connected to my PC.
If I am disconnected from the Win Server (not logged off) I have two situations:
The JAVA prog on the Server produces black boxes or real screenshoots. The difference is just one marker in RDP options in the display part on the local RDP configuration of my client (Win 7).
I have not an english spoken display so I hope the translation may ok.
The configuration detail is: "using all monitors by remote session"
If this marker is set, I get real screen shoots. If this one is not set I have black boxes. I can't explain why, but it works in this way...
Windows would sometimes cause black screens because the machine/desktop was not in use.
Is it possible to run applications on the Windows Desktop? I mean... that it can only be seen in the system tray, and it should be able to run alongside the desktop.
I have no idea how to code it, please help me. I'm kind of new to these things, I am supposed to create something like a "Stardock Fence".
I have seen some examples, but they seem buggy, any strong alternative I could use?
Process.Start() can be used to start a windows application/console app from another win application. There are parameters that allow you to optionally hide the UI as well.
You want your application's windows to be always-on-bottom. In other words, your UI will always appear to be beneath any other open window and just above the Desktop's icons.
To accomplish that, see these related questions.
Once you have a window always on the bottom of the z-order, you'll probably want to remove the non-client window chrome (titlebar/min/max/close buttons) so that your UI can look like a more integrated part of the Desktop. There's plenty of examples around; Googling is left as an exercise for the reader.
Not entirely sure what you mean by background. I expect you mean a Windows Service which is a project type in visual studio, or you might (less likely) mean running a background thread.
Actually, if you want it in the system-tray, you don't want it entirely in the background.
If it was to be fully "in the background", then your best bet is to have it as a service.
System tray icons need a window, but you can just make it non-visible and non-taskbar and that's fine.
A common combo is a service that does the actual heavy-lifting, and a hidden-window application with a systray icon that reports on the service's status (possibly making that same window visible when further interaction is needed).
You want to run your application in the background? Is it on a windows machine? If so then you want to look into running your application as a windows service. Here's an msdn link:
Introduction to Windows Services
There's examples in the article I think - if not it's a good starting point. You can configure services to start automatically on startup of the machine etc. Your application will then run in the background.
Basically you craete your application as normal and then host it in a windows service rather than say a console app or a winforms app.