System.IO.DirectoryNotFoundException for remote folder

Posted on 2008-06-20
Last Modified: 2013-11-07
Our setup:
- computer 1: Windows 2003 running IIS 6.0
- computer 2: Windows Storage Server on a Network Attached Storage (NAS), where all data stored
                       We have shared a folder on this computer, and computer 1 has mapped this folder as the
- We are using a 3rd pary .NET control that allows users to upload files to our this folder sitting on our NAS.
The problem to solve:
 - We get an error "System.IO.DirectoryNotFoundException for remote folder", whenever it calls the function System.IO.Directory.CreateDirectory("D:\uploads\newfolder")

I think it has something to setting up the .NET security permissions in the machine.config file or web.config file, but I am have tried lots of settings and I am stuck at this point. For you information if the  data were all stored on a folder on computer 1, then everything would works just fine.

Question by:putza
LVL 53

Accepted Solution

Dhaest earned 168 total points
ID: 21831061
On a local machine, it should execute just fine if the ASP.NET process has read/write permissions both in the NTFS file system and also in IIS. If both are not in sync, then the opertaion will fail.

Assisted Solution

JuckMan earned 166 total points
ID: 21833313
This is permission issue.

In IIS 6.0 every web application runs in a "Application pool"; Find out under which application pool your web site/web application is using. Righ click on your application pool and select properties.
Click on Identity tab. Enter a domain user account, who has necessary access to the folder where you are trying to create file.

Alos note that this domain account needs to have certain privileges as well (for ex: needs to pbe part of IIS_WPG group etc;)

Assisted Solution

Dauhee earned 166 total points
ID: 21838039
The code below uses the attached code snippit. Basically you can elevate your access to a domain account with permissions for the other server. You can then revert directly after. Be warned that will need to do error handling on page to revert regardless of any error or else user has potential for continuously elevated privledges which would not be good :(

I believe this is the most resilient and scalable solution because setting password in web.config file is too open to prying eyes (identity impersonate="true") and if trying to synchronise the iusr_xxx on the other box means if its ever replaced then ya have to go "jigging" around with settings to get it going again - sure as anything, 3 years down the line nobody will be able to remember!!

You can retrieve the domain user password from an encrypted source so nothing is available for internal network sniffing or file peeking :)

The attached class for impersonation was created by somebody considerably much smarter than I alas I cannot make claim to it :)

                'set the password details
                clsImpersonate = New AliasAccount(strUserName, strPassword, gstrPDCDomain)
            Catch ex As Exception
            End Try

'copy over file here

        'undo impersonation regardless of success
        If Not IsNothing(clsImpersonate) Then
        End If
Public Class AliasAccount

    Private _username, _password, _domainname As String

    Private _tokenHandle As New IntPtr(0)

    Private _dupeTokenHandle As New IntPtr(0)

    Private _impersonatedUser As System.Security.Principal.WindowsImpersonationContext

    Public Sub New(ByVal username As String, ByVal password As String)

        Dim nameparts() As String = username.Split("\")

        If nameparts.Length > 1 Then

            _domainname = nameparts(0)

            _username = nameparts(1)


            _username = username

        End If

        _password = password

    End Sub

    Public Sub New(ByVal username As String, ByVal password As String, ByVal domainname As String)

        _username = username

        _password = password

        _domainname = domainname

    End Sub

    Public Sub BeginImpersonation()

        Const LOGON32_PROVIDER_DEFAULT As Integer = 0

        Const LOGON32_LOGON_INTERACTIVE As Integer = 2

        Const SecurityImpersonation As Integer = 2

        Dim win32ErrorNumber As Integer

        _tokenHandle = IntPtr.Zero

        _dupeTokenHandle = IntPtr.Zero

        If Not LogonUser(_username, _domainname, _password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, _tokenHandle) Then

            win32ErrorNumber = System.Runtime.InteropServices.Marshal.GetLastWin32Error()

            Throw New ImpersonationException(win32ErrorNumber, GetErrorMessage(win32ErrorNumber), _username, _domainname)

        End If

        If Not DuplicateToken(_tokenHandle, SecurityImpersonation, _dupeTokenHandle) Then

            win32ErrorNumber = System.Runtime.InteropServices.Marshal.GetLastWin32Error()


            Throw New ImpersonationException(win32ErrorNumber, "Unable to duplicate token!", _username, _domainname)

        End If

        Dim newId As New System.Security.Principal.WindowsIdentity(_dupeTokenHandle)

        _impersonatedUser = newId.Impersonate()

    End Sub

    Public Sub EndImpersonation()

        If Not _impersonatedUser Is Nothing Then


            _impersonatedUser = Nothing

            If Not System.IntPtr.op_Equality(_tokenHandle, IntPtr.Zero) Then


            End If

            If Not System.IntPtr.op_Equality(_dupeTokenHandle, IntPtr.Zero) Then


            End If

        End If

    End Sub

    Public ReadOnly Property username() As String


            Return _username

        End Get

    End Property

    Public ReadOnly Property domainname() As String


            Return _domainname

        End Get

    End Property

    Public ReadOnly Property currentWindowsUsername() As String


            Return System.Security.Principal.WindowsIdentity.GetCurrent().Name

        End Get

    End Property

#Region "Exception Class"

    Public Class ImpersonationException

        Inherits System.Exception

        Public ReadOnly win32ErrorNumber As Integer

        Public Sub New(ByVal win32ErrorNumber As Integer, ByVal msg As String, ByVal username As String, ByVal domainname As String)

            MyBase.New(String.Format("Impersonation of {1}\{0} failed! [{2}] {3}", username, domainname, win32ErrorNumber, msg))

            Me.win32ErrorNumber = win32ErrorNumber

        End Sub

    End Class

#End Region

#Region "External Declarations and Helpers"

    Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _

            ByVal lpszDomain As [String], ByVal lpszPassword As [String], _

            ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _

            ByRef phToken As IntPtr) As Boolean

    Private Declare Auto Function DuplicateToken Lib "advapi32.dll" (ByVal ExistingTokenHandle As IntPtr, _

                ByVal SECURITY_IMPERSONATION_LEVEL As Integer, _

                ByRef DuplicateTokenHandle As IntPtr) As Boolean

    Private Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Boolean

    <System.Runtime.InteropServices.DllImport("kernel32.dll")> _

    Private Shared Function FormatMessage(ByVal dwFlags As Integer, ByRef lpSource As IntPtr, _

            ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, ByRef lpBuffer As [String], _

            ByVal nSize As Integer, ByRef Arguments As IntPtr) As Integer

    End Function

    Private Function GetErrorMessage(ByVal errorCode As Integer) As String


        Dim FORMAT_MESSAGE_IGNORE_INSERTS As Integer = &H200

        Dim FORMAT_MESSAGE_FROM_SYSTEM As Integer = &H1000

        Dim messageSize As Integer = 255

        Dim lpMsgBuf As String = String.Empty


        Dim ptrlpSource As IntPtr = IntPtr.Zero

        Dim prtArguments As IntPtr = IntPtr.Zero

        Dim retVal As Integer = FormatMessage(dwFlags, ptrlpSource, errorCode, 0, lpMsgBuf, messageSize, prtArguments)

        If 0 = retVal Then

            Throw New System.Exception("Failed to format message for error code " + errorCode.ToString() + ". ")

        End If

        Return lpMsgBuf

    End Function

#End Region

End Class

Open in new window


Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from Go to that link and select download selenium in the right hand columnThat will then direct you to their download page.From that page s…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now