如何使用密码在远程计算机创建文件夹及权限拒绝错误排查
解决远程创建文件夹「访问被拒绝」的问题
咱们一步步拆解你遇到的问题,核心原因和解决方案都给你理清楚:
首先,你代码里访问的\\SERVER\D$\AAA是Windows的管理员共享目录(带$的隐藏共享),这类目录默认只对目标服务器的本地管理员账号开放权限,这几乎就是你触发「访问被拒绝」报错的根源。下面是具体的解决步骤:
1. 核心:解决权限问题
方法一:模拟有权限的远程账号执行操作
如果当前运行程序的账号没有远程服务器的管理员权限,你可以通过账号模拟来临时获取权限。以下是VB.NET的实现代码:
Imports System.Security.Principal Imports System.Runtime.InteropServices ' 模拟远程服务器管理员账号的工具函数 Private Function ImpersonateRemoteAdmin(username As String, serverDomain As String, password As String) As WindowsImpersonationContext Dim tokenHandle As IntPtr = IntPtr.Zero Dim duplicateTokenHandle As IntPtr = IntPtr.Zero Try ' 获取目标账号的登录令牌 If Not LogonUser(username, serverDomain, password, 9, 0, tokenHandle) Then Throw New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()) End If ' 复制令牌用于模拟 If Not DuplicateToken(tokenHandle, 2, duplicateTokenHandle) Then Throw New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()) End If ' 创建身份上下文并返回 Dim adminIdentity As New WindowsIdentity(duplicateTokenHandle) Return adminIdentity.Impersonate() Finally ' 释放资源,避免内存泄漏 If tokenHandle <> IntPtr.Zero Then CloseHandle(tokenHandle) If duplicateTokenHandle <> IntPtr.Zero Then CloseHandle(duplicateTokenHandle) End Try End Function ' 需要引入的Windows API声明 <DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> Private Shared Function LogonUser(lpszUsername As String, lpszDomain As String, lpszPassword As String, dwLogonType As Integer, dwLogonProvider As Integer, ByRef phToken As IntPtr) As Boolean End Function <DllImport("kernel32.dll", SetLastError:=True)> Private Shared Function CloseHandle(hObject As IntPtr) As Boolean End Function <DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> Private Shared Function DuplicateToken(hToken As IntPtr, impersonationLevel As Integer, ByRef hNewToken As IntPtr) As Boolean End Function
然后把你的业务代码放在模拟上下文里执行:
Dim impersonationCtx As WindowsImpersonationContext = Nothing Try ' 替换成远程服务器的管理员账号、服务器名/域名、密码 impersonationCtx = ImpersonateRemoteAdmin("RemoteAdmin", "SERVER", "AdminPass123") ' 你的业务逻辑(已修正笔误) Dim targetDir = "\\SERVER\D$\AAA" If Not System.IO.Directory.Exists(targetDir) Then System.IO.Directory.CreateDirectory(targetDir) End If ' 补充timeNow的定义,修正变量名错误 Dim timeNow = DateTime.Now.ToString("HHmmss") Dim newFileName = $"{targetDir}\{Today.Day}-{Today.Month}-{Today.Year}-{timeNow}-{Today.Minute}.wav" System.IO.File.Copy("\\SERVER\D$\AAA\test.wav", newFileName) Finally ' 结束身份模拟,恢复原有账号权限 If impersonationCtx IsNot Nothing Then impersonationCtx.Undo() End If End Try
方法二:创建普通共享目录替代管理员共享
如果不想用管理员权限,你可以在远程服务器的D:\AAA文件夹上创建一个普通共享(不带$),比如命名为AAAShare,然后给需要访问的账号分配「读取/写入」权限。之后把代码里的路径改成\\SERVER\AAAShare,普通权限账号就能正常访问了。
2. 修复代码里的小笔误
你的代码里有几个细节错误,会导致额外问题:
tineNow应该是timeNow,需要先声明这个变量(比如用DateTime.Now.ToString("HHmmss")生成时间字符串)MyFilename1和定义的MyFilename变量名不一致,会触发编译错误- 原有的If语句可以简化成
If Not Y_N Then Directory.CreateDirectory(findDirectory),更简洁
3. 额外排查点
- 确认远程服务器防火墙允许SMB协议(默认端口445),否则会连不上共享
- 确认目标服务器D盘有足够磁盘空间
- 确认
test.wav文件存在,且操作账号对该文件有读取权限
内容的提问来源于stack exchange,提问作者Farrukh Azad
相关产品推荐
相关产品推荐

