如何从 UWP 应用程序将文件写入 Hololens

How to write file to Hololens from UWP app

我正在使用 Unity 为 HoloLens 2 开发 UWP 应用程序。我想写入日志文件(记录用户交互),然后检索该文件。我不希望用户必须 select 文件位置。

以下代码适用于桌面 UWP 应用(来自相同代码和相同 Unity 项目的输出)。它在 HoloLens 上不起作用,而是抛出“未经授权”的异常。如何写入 HoloLens 上的文件?以后在哪里可以找到该文件?

public class Logger : MonoBehaviour
{
    StreamWriter logFileWriter;

    // Start is called before the first frame update
    void Start()
    {
        string fileName = "mydatalog.csv";

        // Creates a file in the default location:
        //      "build\bin\x64\Release\AppX" on Desktop
        this.logFileWriter = new StreamWriter(fileName);
    }

    void Update()
    {
        string record = // Stuff here...

        if (this.logFileWriter != null)
        {
            this.logFileWriter.WriteLine(record);
        }
    }
}

您为什么不尝试设置要写入 Application.persistentDataPath 的文件路径?在 Unity's docs 中,它表示 Windows 应用程序的路径指向

%userprofile%\AppData\Local\Packages\<productname>\LocalState

这就是您稍后在桌面上查找文件的路径。

当我使用 Hololens 时,我曾经在那里写持久化数据。之后,通过桌面上的 Hololens 门户,我可以导航到我编写的那个文件。

我没有使用过 Hololens 2,但我认为这个过程不会有很大不同。

无需使用文件选择器即可通过代码访问 HoloLens 设备中的文档文件夹。这是我创建的用于读取文件的帮助文件,我没有测试过写入但应该类似。

Within visual studio you may see the section within #if WINDOWS_UWP gray out, to fix this change from Assembly-CSharp to Assembly-CSharp.Player (How to Change It)

using UnityEngine;
using System.IO;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class FileHelper : MonoBehaviour
{
    public static string path;

    private void Start()
    {
        path = Application.streamingAssetsPath;

#if WINDOWS_UWP
        Task pathTask = new Task(
            async () =>
            {
                try
                {
                    var folders = await Windows.Storage.KnownFolders.DocumentsLibrary.GetFoldersAsync();

                    if (folders != null && folders.Count > 0) FileHelper.path = folders[0].Path.Substring(0, folders[0].Path.LastIndexOfAny(new char[2] { '/', '\' }));
                }
                catch (Exception e)
                {
                    Debug.LogError("Failed to locate documents folder!");
                }
            });

        pathTask.Start();
#endif
    }

    public static string ReadFile(string filename)
    {
        string content = string.Empty;

        if (System.IO.File.Exists(Path.Combine(path, filename)))
        {
            try
            {
                StreamReader reader = new StreamReader(Path.Combine(path, filename));
                if (reader == null) return string.Empty;
                content = reader.ReadToEnd();

                reader.Close();
            }
            catch (Exception) { }
        }

        return content;
    }
}

这不会单独工作,因为您必须在构建时编辑包清单文件以包含访问文档文件夹的正确权限。要在 MRTK 构建 window 中完成此操作,您首先要单击“构建 Unity 项目”。

在构建 APPX 包之前构建项目后,我们必须编辑清单文件,该文件位于:

你的Project/Temp/StagingArea/Package.appxmanifest

使用 Visual Studio 代码之类的代码编辑器打开文件,我们必须添加 docuentsLibrary 的功能,并包括我们将用作扩展名的文件类型。要添加扩展,您必须将它放在应用程序选择中的 VisualElements 结束标记下。您可以根据需要添加任意数量的文件类型,目前我包括“.json”和“.data”文件。

这是在添加功能和 filetpye 说明符之前我将编辑的 mainifest 文件部分:(第 16 行到第 35 行)

  <Applications>
    <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="ARIVE.App">
      <uap:VisualElements DisplayName="HoloLens File Reader" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="Template_3D" BackgroundColor="transparent">
        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
        <uap:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="#FFFFFF" />
        <uap:InitialRotationPreference>
          <uap:Rotation Preference="landscape" />
          <uap:Rotation Preference="landscapeFlipped" />
          <uap:Rotation Preference="portrait" />
          <uap:Rotation Preference="portraitFlipped" />
        </uap:InitialRotationPreference>
      </uap:VisualElements>
    </Application>
  </Applications>
  <Capabilities>
    <uap2:Capability Name="spatialPerception" />
    <DeviceCapability Name="microphone" />
    <DeviceCapability Name="location" />
    <DeviceCapability Name="gazeinput" />
  </Capabilities>

这是更新后的版本:(第 16 行到第 47 行)

  <Applications>
    <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="ARIVE.App">
      <uap:VisualElements DisplayName="HoloLens File Reader" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="Template_3D" BackgroundColor="transparent">
        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
        <uap:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="#FFFFFF" />
        <uap:InitialRotationPreference>
          <uap:Rotation Preference="landscape" />
          <uap:Rotation Preference="landscapeFlipped" />
          <uap:Rotation Preference="portrait" />
          <uap:Rotation Preference="portraitFlipped" />
        </uap:InitialRotationPreference>
      </uap:VisualElements>

      <Extensions>
        <uap:Extension Category="windows.fileTypeAssociation">
          <uap:FileTypeAssociation Name="waypoint">
            <uap:DisplayName>waypoint list</uap:DisplayName>
            <uap:SupportedFileTypes>
              <uap:FileType>.json</uap:FileType>
              <uap:FileType>.data</uap:FileType>
            </uap:SupportedFileTypes>
          </uap:FileTypeAssociation>
        </uap:Extension>
      </Extensions>

    </Application>
  </Applications>
  <Capabilities>

    <uap:Capability Name="documentsLibrary" />

    <uap2:Capability Name="spatialPerception" />
    <DeviceCapability Name="microphone" />
    <DeviceCapability Name="location" />
    <DeviceCapability Name="gazeinput" />
  </Capabilities>

现在您已经更新了清单,您可以返回到 Unity 并单击 MRTK 构建中的 'Build APPX' 按钮 window。