I have some problems writing to a mapped network drive (P:) in Windows 7 from my Delphi program. When I try, for example, ForceDirectories('P:\test\folder')
, I get an error (path not found).
I have tried typing in the UNC path in the code (ForceDirectories('\\computername\share\test\folder')
) and that works. However, ExpandUNCFileName('P:\')
does not seem to work; it returns 'P:\'.
On Windows XP, ExpandUNCFileName('P:\')
returns the UNC path.
How do I get the UNC path in Delphi on Windows 7, or otherwise write to a mapped network drive?
Upon further investigation, it is as if I'm missing some kind of initialization in Windows. I have another application (app2) that uses a TcxShellComboBox
(a DevExpress component). After having navigated to P: in that combobox, in app2, calls to ExpandUNCFileName
work correctly in the first application. Same with FileExists
on files under P:, returns False before navigating to P: in app2, returns true after and until computer restart.
According to Microsoft KB Article, if User Account Control is enabled, and if you map a network drive from Windows Explorer (non-elevated), then elevated programs won't have access to that drive. Quote:
If a user is logged on to Windows Vista or to Windows 7, and if User Account Control is enabled, a program that uses the user’s filtered access token and a program that uses the user’s full administrator access token can run at the same time. Because LSA created the access tokens during two separate logon sessions, the access tokens contain separate logon IDs.
When network shares are mapped, they are linked to the current logon session for the current process access token. This means that, if a user uses the command prompt (Cmd.exe) together with the filtered access token to map a network share, the network share is not mapped for processes that run with the full administrator access token.
Since you mentioned in comments that you run Delphi "As Administrator" (elevated), this is your problem.
Solutions:
Don't run Delphi elevated if you don't need to. If you do need an elevation in your software, separate it into two parts (elevated and non-elevated), and access mapped network drive from the first part. Then access the other part using an elevated COM object, or simply by executing a separate executable.
Map a network drive from an elevated network prompt, so the mapped network drive will be available to elevated user:
a. Open elevated command prompt (run "cmd.exe" as Administrator)
b. Type net use p: \\computername\share\test\folder