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.
If you open a file with such a path, the program will crash when you try to import a glazing system. You can solve this problem by mapping a normal drive letter to the path that has the UNC path.
A UNC path uses double slashes or backslashes to precede the name of the computer. The path (disk and directories) within the computer are separated with a single slash or backslash, as in the following examples. Note that in the DOS/Windows example, drive letters (c:, d:, etc.) are not used in UNC names.
In Windows, if you have mapped network drives and you don't know the UNC path for them, you can start a command prompt (Start → Run → cmd.exe) and use the net use command to list your mapped drives and their UNC paths: C:\>net use New connections will be remembered.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With