jordanlytle / SmbAbstraction

Implements the System.IO.Abstractions interfaces for interacting with the filesystem, and adds support for interacting with UNC or SMB paths
MIT License
6 stars 8 forks source link

Enumerating files and directories yields no results #13

Closed ChristianEder closed 4 years ago

ChristianEder commented 4 years ago

I am using SmbAbstraction to access files located in a (currently local on my machine) shared windows folder.

While reading and writing files using the path to the file works fine, I fail when trying to enumerate all files in a folder. The following code returns an empty list:

var clientFactory = new SmbAbstraction.SMB2ClientFactory();
var credentialProvider = new SmbAbstraction.SMBCredentialProvider();
credentialProvider.AddSMBCredential(new SmbAbstraction.SMBCredential("MyMachineName", "my user name", "my password", "smb://MyMachineName/shared_folder_name", credentialProvider));
var dir = new SmbAbstraction.SMBDirectory(clientFactory, credentialProvider, new SmbAbstraction.SMBFileSystem(clientFactory, credentialProvider), uint.MaxValue);
var files = dir.EnumerateFileSystemEntries("smb://MyMachineName/shared_folder_name").ToList();

What am I doing wrong? The user used in the snippet has full access to the shared folder. Any ideas, @jordanlytle , @Jo0 ?

Thanks in advance - your library seems to be the only real option when trying to access smb shares from .NET Core using SMB 2.1 - much appreciated!

Jo0 commented 4 years ago

I tested your code and experienced the same thing.

The one thing that stood out to me is that you are trying to create a new SMBDirectory with a new instance of SMBFileSystem

However, by just creating an instance of SMBFileSystem and utilizing IDirectory of that instance I was able to get the list of files from both a share path and not a share path.

var clientFactory = new SmbAbstraction.SMB2ClientFactory();
var credentialProvider = new SmbAbstraction.SMBCredentialProvider();
credentialProvider.AddSMBCredential(new SmbAbstraction.SMBCredential("MyMachineName", "my user name", "my password", "smb://MyMachineName/shared_folder_name", credentialProvider));
var smbFileSystem = new SmbAbstraction.SMBFileSystem(clientFactory, credentialProvider);
var fileSystemEntires = smbFileSystem.Directory.EnumerateFileSystemEntries("smb://MyMachineName/shared_folder_name").ToList();

The intention of the library was to wrap operations on network shares with System.IO.Abstractions as an intuitive way to operate against networks shares without breaking interoperability with non share paths.

So the entrypoint for every operation should be derived from an instance of IFileSystem or in our case SMBFileSystem

I did end up stepping through SMBDirectory.EnumerateFileSystem() with your code, and nothing was out of place.

Comparing your snippet to my snippet. credentials, relativeSharePath, and all other variables were the same when stepping through both. The only difference is that

fileStore.QueryDirectory(out List<QueryDirectoryFileInformation> queryDirectoryFileInformation, handle, searchPattern, FileInformationClass.FileDirectoryInformation);

is returning out an empty queryDirectoryFileInformation for a new SMBDirectory() vs a populated queryDirectoryFileInformation for a SMBFileSystem.Directory

From the looks of it, everything you wrote should still be valid, but I'm not sure why your snippet is returning an empty list. As a connection is established, we are able to send commands to the host, and all NTStatus along the way checked out.

I'm sorry I couldn't resolve this issue with your specific snippet, but I hope that my snippet works for you in your scenario.

ChristianEder commented 4 years ago

Your version works just as well for me - thanks for the fast response! I also tried this on my machine, and this way the files are found.

Weird - I also stepped through the code, even tried to directly instantiate and use the classes involved from the SmbLibrary package, but still ended up getting no files.

But as long as this way it works, I'm fine :-)

Thanks again!