I want users to be able to open a file using my MAUI app. For example in Windows they could right-click on the file in File Explorer, choose my app in "open with" and then my app would open the file.
I have put file type associations in the Windows app manifest, and it does successfully launch my app when the file is opened by the user in File Explorer.
My problem is, how do I get notified that the reason my app was launched was because they want to open a file, and how do I get the file path?
If this was a regular UWP app and not a MAUI app, I could overload Application.OnFileActivated and handle it there. However I have not been able to find that in MAUI. link to MAUI source
Should I try to handle this by overloadng MauiWinUIApplication.OnLaunched for the Windows version of my app? Or do I have to add handlers via ConfigureLifecycleEvents? Or somewhere else?
I see that OnLaunched is being triggered when I try to open my app with the file, but a) args.UWPLaunchActivatedEventArgs.Kind is always ActivationKind.Launch and never ActivationKind.File and b) the file path doesn't appear in the LaunchActivatedEventArgs object anywhere. Obviously if nothing else I will need to get the file path somehow.
Overloading MauiWinUIApplication.OnLaunched in App.xaml.cs was the correct approach, but the args it gets are buggy (they never have ActivationKind.File and never include the path to the file). A workaround for this bug is to get the real args from another API.
protected override void OnLaunched(LaunchActivatedEventArgs buggyArgs)
{
base.OnLaunched(buggyArgs);
var goodArgs = AppInstance.GetCurrent().GetActivatedEventArgs();
switch (goodArgs.Kind)
{
case ExtendedActivationKind.File:
var data = goodArgs.Data as IFileActivatedEventArgs;
var paths = data.Files.Select(file => file.Path).ToArray();
// Do something
break;
}
}
Related
I have an ASP.NET MVC web application with a button to download an .exe file for an existing WPF application. It downloads fine, but when clicked in the browser window, it doesn't execute. How would I fix this?
[HttpGet]
public FileResult downloadFile()
{
var fileName = string.Format("MyApp.exe", DateTime.Today.Date.ToString("dd-MM-yyyy") + "_1");
var tempOutPutPath = Server.MapPath(Url.Content("~/File/")) + fileName;
byte[] finalResult = System.IO.File.ReadAllBytes(tempOutPutPath);
if (System.IO.File.Exists(tempOutPutPath))
System.IO.File.Delete(tempOutPutPath);
if (finalResult == null || !finalResult.Any())
throw new Exception(String.Format("No Files found"));
return File(finalResult, System.Net.Mime.MediaTypeNames.Application.Octet, Path.GetFileName(fileName));
}
This is a security issue, so i would say no. Imagine the disaster if links on malicous sites could download and run programs on the end users pc.
Don't know why you need it, but if you need to launch your wpf app from a browser. Then you could make a link to reference a uri scheme that points to your already installed application. You would have to add it to registry during an install routine or a one time job in your app.
Registering an Application to a URI Scheme in windows 10
Hope this helps
I think this is the closest you can get to run your application from a browser. But making it launch automatically after download is not possible.
like matcsr pointed out what you cannot force a user to execute a file in their download folder. But if what you want is to distribute your WPF app from the web then you need to setup a ClickOnce Web deployment. More info Here: Choose a ClickOnce deployment strategy
I am having a strange problem that I am unable to access files written by my c# application. My app basically does :
var file = "C:\\Users\\Public\\Documents\\something.txt";
List<string> content = new List<string> { "one thing", "two things" };
Console.WriteLine(System.IO.File.Exists(file));
System.IO.File.WriteAllLines(file, content);
Console.WriteLine(System.IO.File.Exists(file));
The first time I run the app, the output is
False
True
Yet I cannot see the written file in Windows Explorer (Windows 10). I get no exceptions attempting to write the file. The second time I run the app, the output is :
True
True
According to my application the file is being written however Windows thinks differently. As a sanity check I spun up a second app that opens a dialog using OpenFileDialog. When I run that, I am able to see my written files! Windows explorer still cannot. Attached is a screenshot of windows explorer and my openfiledialog side by side.
If I go to notepad and browse for the file I cannot see it or manually type in the name.
Its been a long week of work, there must be some dumb explanation...? Help! :-)
Screenshot - windows explorer on left, c# app open dialog on right :
https://imgur.com/a/8ZTDIe6
per #BACON 's suggestion in the comments above I discovered that after disabling the Comodo anti-virus I am able to write and see my files.
I believe the software is running my app or either only allowing IO from my app in some kind of container. I need to figure out how to grant my apps proper permissions through the anti-virus software, but that was the culprit.
We are currently working on a project in UWP where we have to start an external application to modify some documents.
We looked into the Windows.System.Launcher API but it seems that we need more than what it can offer us.
As we launched the application from a file, we use the LaunchFileAsync method, based on the example given by the MSDN :
async void DefaultLaunch()
{
// Path to the file in the app package to launch
string imageFile = #"images\test.png";
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(imageFile);
if (file != null)
{
// Launch the retrieved file
var success = await Windows.System.Launcher.LaunchFileAsync(file);
if (success)
{
// File launched
}
else
{
// File launch failed
}
}
else
{
// Could not find file
}
}
So far, the example suit us well but we also need to be warned when the user is done with the file. The best would be to be able to give the launcher a callback method.
We haven't found anything like that yet in the documentation. Is this even possible ? Do we need to use another solution ?
TL;DR : Is there a solution to open another application from a UWP app and wait for it to return a result object ?
If the external app is also a UWP app then Launcher.LaunchUriForResultsAsync is designed for this. It will launch the target app then wait for the app to call back with the results.
See Launch an app for results for a full walkthrough of how this works.
If the target app isn't a UWP app then you can implement the same thing yourself: both apps declare a protocol. The client launches the server with the server's protocol. When the server's done it notifies the caller by launching the client's protocol.
You might also want to look into App Services which allow a UWP server app to expose a REST-like service to clients on the local system.
The app process isolation model means you can't do this from a UWP app. As you just want to know when an arbitrary program has finished you could write this in traditional .net/win32 and include that in your UWP app via the desktop bridge.
I have a windows forms application with a custom file extension set up. I am able to save data to my file, and when I double-click my saved file from Windows, it launches my application.
I have not, however, been able to get the name of the file I clicked on to read in its data. Everything seems to tell me args[0] should be the exe (as I'm seeing), args[1] would be the next parameter (probably what i'm looking for; the file name I clicked on) but args.Length is always just 1, whether I open the exe directly or click on a text file that launches the exe, I never have the file name I clicked on.
Edit (resolved; ish): OK, finally have a more specific issue nailed down. My application was deployed with ClickOnce, and I set up all the file associations through the windows forms application properties. When I right-click and view the properties of my saved custom file, it says "Opens with: ClickOnce Application Deployment Support Library" and not my application name. If I change the default to open with my .exe, magically it has the correct arg values (the exe, followed by the file name I clicked on).
You can't access command line arguments for ClickOnce applications directly. To get to them, I used the following, modified a bit from here:
System.Runtime.Hosting.ActivationArguments args = AppDomain.CurrentDomain.SetupInformation.ActivationArguments;
if (args.ActivationData != null)
{
foreach (string commandLineFile in AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData)
{
MessageBox.Show(string.Format("Command Line File: {0}", commandLineFile));
}
}
This gave me the file name I clicked on. Hoorah.
I am trying to develop an app which launches a regular .exe application from metro app using launcher class. MSDN provided a sample here and a stackoverflow sample is here
The problem is that my metro gives error of "file not found" even the file is there. i have tried to place file on other drives as well but the problem persists
here is my code sample
// Path to the file in the app package to launch
string imageFile = #"E:\App.exe";
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(imageFile);
/* error in the above line .it says file not found The filename, directory name, or volume label syntax is incorrect. (Exception from HRESULT: 0x8007007B)*/
if (file != null)
{
// Launch the retrieved file
var success = await Windows.System.Launcher.LaunchFileAsync(file);
if (success)
{
// File launched
}
else
{
// File launch failed
}
}
else
{
// Could not find file
}
LaunchFileAsync is for launching a file in its default program.
http://msdn.microsoft.com/library/windows/apps/Hh701461
I am not convinced it will work with an .exe
The correct usage is something like:
LaunchFileAsync("images\\picturesofcats.png");
This then opens a picture of cats in your default image viewer.
This will not work for an .exe due to sandboxing, and because .exe has no default opener.
There are a few tricks to get around this, see: Launching a Desktop Application with a Metro-style app
Generally, you are working against the design of Windows 8 to do this, so you might want to reconsider your approach.