Search code examples
c#winformswindows-identity

How to copy file from a specific folder to a shared folder in C#?


I am trying to copy existing file from a specific folder to a shared folder. So this is the code:

if (!System.IO.File.Exists(fullPath))
            {
                using (WindowsIdentity.GetCurrent().Impersonate())
                {

                    try
                    {

                        image.Save(fullPath);

                        System.Security.AccessControl.DirectorySecurity sec = System.IO.Directory.GetAccessControl(originalDocumentFolderPath);
                        FileSystemAccessRule accRule = new FileSystemAccessRule(originalDocumentFolderPath, FileSystemRights.FullControl, AccessControlType.Allow);
                        sec.AddAccessRule(accRule);
                        string sharedFolderPath = "\\" + Path.Combine(Environment.MachineName, "Users");
                        sharedFolderPath = Path.Combine(sharedFolderPath, username);
                        sharedFolderPath = Path.Combine(sharedFolderPath, "Desktop");
                        sharedFolderPath = Path.Combine(sharedFolderPath, "SharedFolder");
                        System.IO.File.Copy(originalDocumentFolderPath, sharedFolderPath);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }

            }

And I get this error:

System.Security.Principal.IdentityNotMappedException: 'Some or all identity references could not be translated.'

at this line:

 sec.AddAccessRule(accRule);

What am I doing wrong? If you need more data, please let me know...

EDIT:

Also, the final goal is that this should actually save files into a shared folder on a specific computer in LAN network, but I am currently trying to save it in the shared folder, on the same computer, where program runs.

EDIT 2:

So I tried what suggested by @PaulKaram but I still getting the next error:

enter image description here

From the picture, it can be seen the folder in the Documents where I firstly save image. That goes without problems. When i try to copy it on the specific shared folder on a Desktop, the error above (access denied) arises for the folder already created in Documents.


Solution

  • The error Some or all identity references could not be translated means that the identity/account you're using is not found. Taking a deeper look, we can see that you have a problem with this line:

    FileSystemAccessRule accRule = new FileSystemAccessRule(originalDocumentFolderPath, FileSystemRights.FullControl, AccessControlType.Allow);
    

    Take a look at the FileSystemAccessRule constructor that you're using. Here's the signature:

    public FileSystemAccessRule (string identity, System.Security.AccessControl.FileSystemRights fileSystemRights, System.Security.AccessControl.AccessControlType type);
    

    The first argument that should be sent is the identity, as taken from the documentation:

    The name of a user account.

    I am not sure what you're sending there in originalDocumentFolderPath.
    Assuming username hold the identity you're impersonating, that line should be changed to:

    FileSystemAccessRule accRule = new FileSystemAccessRule(username, FileSystemRights.FullControl, AccessControlType.Allow);
    

    Two other things that you should be aware of:

    First of all, you're working with a shared folder on a network, therefore you need to fix this line:

    string sharedFolderPath = "\\" + Path.Combine(Environment.MachineName, "Users");
    

    into this:

    string sharedFolderPath = "\\\\" + Path.Combine(Environment.MachineName, "Users");
    

    When you're working with a network folder, you need double back slash at the start, and since in C# a back slash escapes characters, you'll need to write it as \\\\.

    Second, you should also note, that you're trying to copy the file and giving it the folder name as destination. To fix this you should add at the end of combining the path of the shared folder this:

    sharedFolderPath = Path.Combine(sharedFolderPath, "file.extension");
    

    At the end, here's your full code that should work as intended:

    if (!System.IO.File.Exists(fullPath))
    {
        using (WindowsIdentity.GetCurrent().Impersonate())
        {
            try
            {
                image.Save(fullPath);
                System.Security.AccessControl.DirectorySecurity sec = System.IO.Directory.GetAccessControl(originalDocumentFolderPath);
                FileSystemAccessRule accRule = new FileSystemAccessRule(username, FileSystemRights.FullControl, AccessControlType.Allow);
                sec.AddAccessRule(accRule);
                string sharedFolderPath = "\\\\" + Path.Combine(Environment.MachineName, "Users");
                sharedFolderPath = Path.Combine(sharedFolderPath, username);
                sharedFolderPath = Path.Combine(sharedFolderPath, "Desktop");
                sharedFolderPath = Path.Combine(sharedFolderPath, "SharedFolder");
                sharedFolderPath = Path.Combine(sharedFolderPath, "file.extension");
                System.IO.File.Copy(originalDocumentFolderPath, sharedFolderPath);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }