Search code examples
uwpsharefile-permissionssmb

How to access local network (SMB) in UWP?


I am looking for quite a long time now, but I just couldn't find any working solution for this particular issue. My goal is to create a background application for the main HoloLens application (which means it must be done in UWP), which should be able to access both, local files and local networks (SMB), so that it can map the file hierarchy in order to relay them to the main application in Unity, which would display the files in a 3D/2D manner.

Until now I tried several things, including: Regular StorageFolder/StorageFile interactions (it would be great if this one worked, as local file interactions are already implemented), SharpCifs.Smb and Xb.Net.SmbTree.

SharpCifs:

    public SmbFile GetFile ()
    {
        //smb://UserName:Password@ServerIP/ShareName/Folder/FileName.txt
        SmbFile file = new SmbFile ("smb:\\winAccName:[email protected]\\TestShare");
        file.Connect (); // Or any file action.
        return file;
    }
    // Exception User-Unhandled -- SharpCifs.Util.Sharpen.UnknownHostException: '..MSBROWSE__.<01>'

Until now I didn't succeed to do anything with everything related to SmbFile. Usually I get the error message that it is unable to connect to the IP address.

With StorageFile/Folders:

    async public void OpenFile ()
    {
        StorageFolder folder = await StorageFolder.GetFolderFromPathAsync ("\\\\ServerName.local");
        if (folder != null) CreateMessage ("Got the folder: " + folder.Name);

        StorageFile file = await folder.GetFileAsync ("abc.txt");
        CreateMessage ("Success: " + file.Path);
    }
    // Exception User-Unhandled -- System.Runtime.InteropServices.COMException: 'Error HRESULT E_FAIL has been returned from a call to a COM component.'

The latter one succeeded to get the folder, but failed to do anything with it. But that's the furthest I could get so far. I also enabled the capabilities:

<Capabilities>
    <Capability Name="internetClientServer" />
    <Capability Name="internetClient" />
    <Capability Name="privateNetworkClientServer" />
    <uap:Capability Name="sharedUserCertificates" />
    <uap:Capability Name="enterpriseAuthentication" />
    <DeviceCapability Name="proximity" />
</Capabilities>

I assume I got permission issues, and I wonder why SmbTree / SmbFile interactions require usernames and passwords all the while StorageFile/StorageFolder interactions do not ask for it (and therefore fail?). I see that the capabilities have to be added... but that can't be all that's needed. The file picker is also just a solution to solve local file permission issues, but can't be the solution for networks (a client can't allow itself to access files on the host). Plus for HoloLens I can't rely on file pickers, as it currently has none. Anyway, the picker still seemed to work, and if I could create a custom file picker, that would be an acceptable solution as well... if that's possible.

Ps: I also tried to run Visual Studio as admin. And the shared folder permissions are also set up (even for guests). The current shared folder is a local folder accessible through "A:\". File type associations are also set.

I heard quite some comments saying that SMB is not supported on UWP, yet I hear comments about people who made it work (which didn't work for me though). I also heard SMB 1 is not allowed any more. I'd be really grateful for any help, as this is certainly not my domain of expertise.

Greetings!


Solution

  • Just to answer my own question, as it seems like I resolved it, I'd like to summarize what I did (I also found out only a part of that was even necessary, but maybe that continued to work only temporarily... either way these may still give a hint):

    • In Package.appxmanifest add the Capabilities revolving arund: Internet, Private Networks, Proximity, Enterprise Authentification.
    • While there, also add Declarations: File type Associations for given files and add "Share Target". These things can be set up in the visual display, no need for code view.
    • Make sure the permissions are properly set up in the share folder and also consider guest permissions. This one is mandatory.
    • Use the proper path for: . . . StorageFolder folder = await StorageFolder.GetFolderFromPathAsync (@"\\142.24.56.10\TestShare"); OR (@"\\JOHNS-COMPUTER\TestShare");

    -> From there on you have the permissions granted based on your computer and windows account (at least I assume).

    No other things were necessary: Neither special authentification nor SMB specific libraries. It just works through the StorageFile/StorageFolder system, and the network can be navigated with the same methodology as the local file system.

    Edit: It seems like the culprit actually was the "Share Target" declaration for me. If you have 0 file type associations declared or if you did not declare "Share Target", it won't work.

    Another info: "broadFileSystemAccess" is quite useful as well, which alleviates you from the standard file type restrictions. Without this you won't be able to get non-declared files and files without extension. It has it's own rules though, read it up.

    One little hint: Visual Studio underlined it green in the xml as if there was an error, but it still worked.