How can I open a file I've added to my Windows

2019-07-04 13:02发布

问题:

I want to load a PDF file in response to a Tapped event.

I added the file to my project (Add > Existing Item), set "Build Action" to "Content" and "Copy to Output Directory" to "Copy if newer"

I'm thinking the code I need may be something like this:

async Task LoadTutorial()
{
    await Launcher.LaunchUriAsync(new Uri("what should be here to access the output folder?"));
}

If I'm right, what do I need to pass as the Uri? Otherwise, how is this accomplished?

UPDATE

On a related note, to add an image to the XAML using the suggested scheme, I thought this would work:

<Image Source="ms-appx:///assets/axXAndSpaceLogo.jpg"></Image>

...but it doesn't.

UPDATE 2

Trying this to open the PDF file (which is located in the root of the project, not in a subfolder):

async private void OpenTutorial()
{
    IStorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
    IStorageFile file = await folder.GetFileAsync("ms-appx:///PlatypusTutorial.pdf");
    await Launcher.LaunchFileAsync(file);
}

...resulted in this runtime exception, thrown on the first line above:

UPDATE 3

And with this, adapted from the link provided:

var uri = new System.Uri("ms-appx:///ClayShannonResume.pdf");
var file = Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);
await Launcher.LaunchFileAsync(file);

...I get the compile time errors:

The best overloaded method match for 'Windows.System.Launcher.LaunchFileAsync(Windows.Storage.IStorageFile)' has some invalid arguments

-and:

Argument 1: cannot convert from 'Windows.Foundation.IAsyncOperation' to 'Windows.Storage.IStorageFile'

...on the last line.

UPDATE 4

According to page 76 of "Pro Windows 8 Programming" by Lecrenski, Netherlands, Sanders, and Ashely, this should work:

<Image Source="Assets/axXAndSpaceLogo.jpg" Stretch="None"></Image>

...(IOW, the "ms-appx:///" jazz is unnecessary), and it more or less does. In my particular case, with my (large) image, I had to do this:

<Image Source="Assets/axXAndSpaceLogo.jpg" Width="120" Height="80" HorizontalAlignment="Left"></Image>

Without the width and height settings, the image displayed bigger than a rhinoceros, and hugging the right side of the flyout.

UPDATE 5

I find that this works to open a PDF file ("PlatypusTut.pdf" has been added to the project, with "Build Action" set to "Content" and "Copy to Output Diretory" set to "Copy if newer"):

IStorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
IStorageFile file = await folder.GetFileAsync("PlatypusTut.pdf");
bool success = await Launcher.LaunchFileAsync(file);
if (!success)
{
    MessageDialog dlgDone = new MessageDialog("Unable to open the Tutorial at this time. Try again later.");
    await dlgDone.ShowAsync();
}

...but I wonder if this will only work at design-time, locally. Will this work when installed on user's machines, too? IOW, is it enough to simply pass "PlatypusTut.pdf" to GetFileAsync()?

回答1:

Use the ms-appx protocol (e.g. ms-appx:///assets/image.png )to reference items in the apps package. See How to load file resources (XAML)

UPDATE:

Use GetFileFromApplicationUriAsync with ms-appx to find the file in the app package. If the file is marked as content and included in the app package then it will be available once deployed and not just from in the debugger. ms-appx:///PlatypusTut.pdf will find the PlatypusTut.pdf in the root of the app package.

StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///PlatypusTut.pdf"));
await Launcher.LaunchFileAsync(file);


回答2:

We did it that way:

public async Task OpenResearchAsync(string path)
{
    if (path.ToLower().StartsWith("http://"))
    {
        await Launcher.LaunchUriAsync(new Uri(path));
    }
    else
    {
        IStorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
        IStorageFile file = await folder.GetFileAsync(path);
        await Launcher.LaunchFileAsync(file);
    }
}