Force WPF application to maximize on Windows startup - c#

I have a WPF app that installed on Windows 10 Pro via ClickOnce and uses MahApps.Metro.
It is set to launch on Windows boot with a non-admin account that has no password. Tablet mode is enabled.
I want the application pop up full screen to create kiosk-like experience, however the app starts minimized when launching on boot. To clarify, the WindowState is Maximized, but Windows does not show it, instead it shows the start screen. It launches fullscreen maximized when launching manually.
Here is some code, however I guess this is more of a configuration problem than code problem:
This is how I set the launch on boot:
RegistryKey rkApp = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
string startPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs)
+ #"\Publisher\AppName.appref-ms";
rkApp.SetValue("AppName", startPath);
This is MainWindow.xaml
<Controls:MetroWindow x:Class="AppName.MainWindow"
IgnoreTaskbarOnMaximize="True" ShowTitleBar="False" WindowStyle="None" WindowState="Maximized">
...
</Controls:MetroWindow>

Take a look at Kiosk Mode for Windows 10.
From Set up a device for anyone to use (kiosk mode):
A single-use device is easy to set up in Windows 10 for desktop
editions (Pro, Enterprise, and Education). For a kiosk device to run a
Universal Windows app, use the assigned access feature. For a kiosk
device (Windows 10 Enterprise or Education) to run a Classic Windows
application, use Shell Launcher to set a custom user interface as the
shell.
From Assigned access (Industry 8.1):
Administrators can use assigned access to restrict a user account to
access a single application. You can use assigned access to set up
single-function devices, such as restaurant menus or displays at trade
shows.
The following table identifies the type of application that can be used on each Windows 10 edition to create a kiosk device.
A Universal Windows app is built on the Universal Windows Platform
(UWP), which was first introduced in Windows 8 as the Windows Runtime.
A Classic Windows application uses the Classic Windows Platform (CWP)
(e.g., COM, Win32, WPF, WinForms, etc.) and is typically launched
using an .EXE or .DLL file.

You can do this in the MainWindow.xaml.cs by adding a windowstate of maximized.
public MainWindow()
{
InitializeComponent();
this.WindowState = WindowState.Maximized;
}

The solution (hack) was to open any other window (e.g. powershell) on startup using Task Scheduler, and after another window is open, we can call Alt+Tab in a powershell script using.
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.SendKeys]::SendWait("%{TAB}")

Set the Window state in the ContentRendered event handler:
protected override void OnStartup(StartupEventArgs e)
{
Application.Current.MainWindow.ContentRendered += (s, a) =>
Application.Current.MainWindow.WindowState = WindowState.Maximized;
}

Related

Send keyboard strokes to an RemoteApp application within an Remote Desktop session with Winforms C#

I want to send keyboard keys to an RemoteApp application. I am using C# with the Windows API.
The code example works when I am using Windows 10 Desktop with an RemoteApp application. The application appears in the foreground and the shortcut code CTRL + SHIFT + O is executed in the application.
When I start the same application on a Windows Server 2012 / 2016 Remote Desktop server in an RDS session it will set the window to the foreground but the application is not receiving the shortcut.
On a Windows 2019 Server with Remote Desktop it works great, however with versions 2012 and 2016 it doesn’t work.
I’ve also tried the following:
SendMessage and PostMessage with the handle and WM_KEYDOWN / WM_KEYUP.
Class.WinAPI.PostMessage(handle,WM_KEYDOWN,0x11,0);
Class.WinAPI.PostMessage(handle,WM_KEYDOWN,0x10,0);
Class.WinAPI.PostMessage(handle,WM_KEYDOWN,0x4F,0);
Class.WinAPI.PostMessage(handle,WM_KEYUP,0x11,0);
Class.WinAPI.PostMessage(handle,WM_KEYUP,0x10,0);
Class.WinAPI.PostMessage(handle,WM_KEYUP,0x4F,0);
foreach (KeyValuePair<IntPtr, string> window in OpenWindowGetter.GetOpenWindows())
{
IntPtr handle = window.Key;
string title = window.Value;
if (title.ToLower().Contains(“ApplicationName”))
{
Class.WinAPI.SetForegroundWindow(handle);
Thread.Sleep(1);
SendKeys.SendWait("^+O");
Thread.Sleep(1);
SendKeys.Flush();
}
}

How to call the default browser in the Hololens app

I want to create an app that calls the Hololens default browser. I used the following code, but whenever I call this function, the Application will crash. If this code is not suitable for UWP, how can I call HoloLens' default browser in an app?
The version of the software I am using is:
1.Unity 2018 3.11f
2.Mixed Reality Toolkit v2.0.0 RC1
3.Visual Studio 2017
public void OpenAnlagenWiKi_URL()
{
string tempUrl = string.Format("{0}", AnlagenWiKi_Link.text);
Application.OpenURL(tempUrl);
}
I hope to successfully call HoloLens' default browser in the app.
It's a bit tricky. Any Hololens application is actually UWP process.
First of all, you need to switch it into the background mode by calling AppResourceGroupInfo.StartSuspendAsync. The details are here.
When the app would go into background, you should call open process
System.Diagnostics.Process.Start("http://google.com");

PrintVisual won't print unless run as Administrator

I currently have a WPF C# application that basically loads a XAML Window control, stuff information in it, and then call PrintVisual();
On Windows 10, this operation works normally for standard user (Limited permission). However on Windows 7, PrintVisual hangs and does not print unless application is elevate to run as Administrator.
All windows 7 machine has been updated to the latest version.
Here's my question; why does PrintVisual require administrator privilege to print? Do I need to use a different technique when running on Windows 7?
(Thought about Graphic.CopyFromScreen Method to bypass administrative privilege...)
Below is a code sniplet of where the problem lies.
BinLocation bl = new BinLocation(); // A Windows control object
PrintDialog dlg = new PrintDialog(); // API from System.Windows.Controls
LocalPrintServer prtSrv = new LocalPrintServer(); // API from System.Printing
PrintQueue pq = prtSrv.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local }).Where(w => w.Name.Contains("QL-500") && !w.IsOffline).FirstOrDefault();
if (pq != null) dlg.PrintQueue = pq;
bl.Show();
// Problem here with Win7 Standard user, code hangs and refuse to raise exception. using System.Windows.Media.Visual
dlg.PrintVisual(bl, "");
bl.Close();
I am currently using WPF C# project in VS2015 on Win7 x64 machine.

Windows Services for Console application in C#.net

I have made one console application for email notification in c#.
Can i convert this console application in to window service?
Thanks.
In visual studio, create a "Windows Service" project instead of a "Console Application". Look in the code that gets generated for you. There will be an OnStart() and OnStop() method. Those are the methods that will be called when your service is started and stopped. Put your code in those methods and you will have a Windows Service.
Contrary to some of the suggestions made by other answers, you probably can't do what you want using a Windows Service. It can't display the "notification" you expect because services can't display any kind of user interface.
The appropriate solution is to create a regular application that runs in the background without showing any windows. You can't do this with a console application (well, you can, but let's not overcomplicate things) because each time you run it, the console window will be displayed. But if you create a standard Windows application (either a Windows Forms or WPF application) then just don't create a window, everything will work out just fine.
You'll probably want to create and place an icon into the taskbar's notification area, which will handle displaying the notification upon the arrival of email. If you're creating a WinForms application, this can be done easily by using the NotifyIcon component.
Something like (warning, written without the aid of a compiler!):
static class Program
{
[STAThread]
static void Main()
{
// Standard infrastructure code
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Create a context menu and add item(s) to it
ContextMenu mnu = new ContextMenu();
MenuItem mnuExit = new MenuItem("E&xit");
mnu.MenuItems.Add(mnuExit);
mnuExit.Click += mnuExit_Click);
// Create the NotifyIcon
NotifyIcon ni = new NotifyIcon();
ni.Icon = new Icon(GetType(), "icon.ico");
ni.Text = "Email Notifier";
ni.ContextMenu = mnu;
ni.Visible = true;
// Run the application
Application.Run();
// Before exiting, remove the NotifyIcon from the taskbar
ni.Visible = false;
}
private static void mnuExit_Click(object Sender, EventArgs e)
{
Application.Exit();
}
}
When I go about this, I write the application in a class that does not consider its self a console application. By that I mean I dont write to the Console. I use log4net to write everything to... just log to Info. Use the console app to call the application class and in the app.config you can have an appender for console logging... so you get the console output. In the windows service this will just write to a file or not at all for the Info level logging. Its important to note the differences between a console app and a service... a service is not interactive and you can not input anything, so you app must consider this. For the windows service use the same class, but use the windows service project to start it.
ApplicationLogic: Has all the logic to run the application. Can take the arguments to make the app run the way it needs to, but does not interact with the console (can, but it would be bad design). Writes everything to logging (log4net maybe).
ConsoleApp: Is a wrapper around ApplicationLogic that can prompt the user for what ever it needs, can prompt for input and send it to ApplicationLogic. Has a log4net console appender if you need to see the output from ApplicationLogic.
WindowsService: Is a wrapper around ApplicationLogic. Has predetermined logic to keep it looping and running the Application logic. Logs to a file, no console output.

Launching a Desktop Application with a Metro-style app

Is there a way to launch a desktop application from a Metro-style app on Windows 8? I'm trying to create some simple shortcuts to desktop applications to replace the desktop icons on the start screen, which look out of place.
I just need something super simple, preferably in C#, to open an application as soon as the app loads. I'm planning on making these shortcuts for some games, photoshop, etc, not anything I've made myself. They're also just for personal use, so I can use direct paths to applications like "C:\Program Files (x86)\Steam\steamapps\common\Skyrim\TESV.exe"
If you simply want to run a desktop application like (notepad, wordpad, internet explorer etc) then go through Process Methods and ProcessStartInfo Class
try
{
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "C:\Path\To\App.exe";
p.Start();
}
// Exp 2
// Uses the ProcessStartInfo class to start new processes,
// both in a minimized mode.
void OpenWithStartInfo()
{
ProcessStartInfo startInfo = new ProcessStartInfo("IExplore.exe");
startInfo.WindowStyle = ProcessWindowStyle.Minimized;
Process.Start(startInfo);
startInfo.Arguments = "www.northwindtraders.com";
Process.Start(startInfo);
}
On Windows 8 Metro application i discovered this: How to Start a
external Program from Metro App.
All the Metro-style applications work in the highly sand boxed
environment and there is no way to directly start an external
application.
You can try to use Launcher class – depends on your need it may
provide you a feasible solution.
Check this:
Can I use Windows.System.Launcher.LauncherDefaultProgram(Uri) to invoke another metro style app?
Ref: How to launch a Desktop app from within a Metro app?
Metro IE is a special app. You cannot invoke an executable from Metro style apps.
Try this - I have not test yet but may be it will help you..
Launcher.LaunchFileAsync
// Path to the file in the app package to launch
string exeFile = #"C:\Program Files (x86)\Steam\steamapps\common\Skyrim\TESV.exe";
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(exeFile);
if (file != null)
{
// Set the option to show the picker
var options = new Windows.System.LauncherOptions();
options.DisplayApplicationPicker = true;
// Launch the retrieved file
bool success = await Windows.System.Launcher.LaunchFileAsync(file, options);
if (success)
{
// File launched
}
else
{
// File launch failed
}
}
I found a solution which is suitable for me. I just made an empty textfile in my app and called it launcher.yourappyouwanttostart and then executed it with
Windows.System.Launcher.LaunchFileAsync("launcher.yourappyouwanttostart");
On the first startup it asks you for the assocation for this file and then you choose the exe file you want to run and from now on every time you execute this file, your app will be started.
I haven't actually tried if it works and it's not really a beautiful solution, but I guess Metro-style apps can launch a URI.
You could then create a desktop-program that is registered for a custom URI scheme that would then do the actual program launching.
What you can do is host external WCF service on your computer with separate installation and connect to it from metro style application using localhost. Then you can do pretty much anything including Process.Start.
I love simple things, so my solution was to use this:
Process.Start("explorer", "shell:AppsFolder\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe!App")
This will start the "new" Sticky Notes coming with Anniversary Update to Windows 10, but it works with all other "Metro" apps I tested.
To find the name of the metro app, from Windows Explorer you have to find it in shell:appsfolder using the AppUserModelId column.

Categories