【发布时间】:2020-04-26 07:01:38
【问题描述】:
我们的软件需要根据用户登录的数据库映射网络驱动器。
软件首先检查驱动器是否尚未映射,如果是则跳过映射步骤。
如果驱动器未映射,或者它被映射到不同的共享(即用户之前登录到不同的数据库),那么它会清除任何现有的驱动器映射,并映射所需的驱动器。
它通过生成然后运行一个 PowerShell 脚本来做到这一点。
Remove-SmbMapping -LocalPath "R:" -Force -UpdateProfile;
Remove-PSDrive -Name "R" -Force;
net use "R" /delete /y;
$password = ConvertTo-SecureString -String "Password" -AsPlainText -Force;
$credential = New-Object System.Management.Automation.PSCredential -ArgumentList "Username", $password;
New-PSDrive -Name "R" -PSProvider "FileSystem" -Root "\\server\share" -Credential $credential -Persist;
$a = New-Object -ComObject shell.application;
$a.NameSpace( "R:" ).self.name = "FriendlyName";
前三行删除该驱动器号上的所有现有映射。从理论上讲,它们都做同样的事情,但是由于微软,哪条线实际起作用是完全随机的。只有在运行所有三行时,它才能始终如一地工作。
中间三行映射新驱动器。
最后两行将新驱动器的驱动器标签更改为比默认的 \\server\share 标签更便于用户使用的东西
重新启动后有人第一次登录时,上述脚本运行良好。新驱动器已映射,标签已更改。
但是,如果用户随后注销并登录到不同的数据库,则标签不会更改。
例如,用户首先登录到“Database A”,驱动器映射为“DatabaseAFiles”标签。一切顺利。
但如果用户随后注销并登录到“数据库 B”,则驱动器已正确映射并指向正确的共享,但标签仍显示“DatabaseAFiles”而不是“DatabaseBFiles”。
但是,如果用户重新启动其 PC 并登录到“数据库 B”,则标签将正确显示“数据库 BFiles”,但任何后续再次登录到其他数据库都不会更改标签。
Reboot
Log in to Database A, label is DatabaseAFiles
Log out and into Database B, label is still DatabaseAFiles
Reboot
Log in to Database B, label is now DatabaseBFiles
这不依赖于存在的最后两个脚本行(设置标签的两个),我实际上添加了这些以尝试解决此问题。如果这两行被删除,标签是默认的 \\server\share 标签,并且仍然没有正确更改,即
Reboot
Log in to Database A, label is \\servera\sharea
Log out and into Database B, label is still \\servera\sharea
Reboot
Log in to Database B, label is now \\serverb\shareb
无论标签如何,驱动器始终正确映射到正确的共享,并且使用它具有所有正确的目录和文件。
一切正常,只是每次重启后第一次登录后标签不正确。
脚本在创建的 PowerShell 实例中的 C# 程序中运行
using (PowerShell PowerShellInstance = PowerShell.Create())
{
PowerShellInstance.AddScript(script);
IAsyncResult result = PowerShellInstance.BeginInvoke();
while (result.IsCompleted == false)
{
Thread.Sleep(1000);
}
}
当它映射驱动器时,它不能在管理员模式下运行(驱动器不会为实际用户映射),它必须在正常模式下运行,所以有一个早点检查一下。
如果我获取脚本的副本并在 C# 程序之外的 PowerShell 会话中运行它,我会得到完全相同的结果(一切正常,但第一次登录后标签错误),所以并不是它正在运行来自 C# 程序。
问题完全可能出在文件资源管理器或 Windows 上,当然,将标签缓存在某处并重复使用它可能是问题所在。
有人对我可以尝试的事情有什么建议吗?
【问题讨论】:
-
我确实看到,一旦您创建了共享,它就永远不会被删除。它不可用,但总是在那里。在其他人之前先使用
Remove-PSDrive J。(不带引号或参数)看看是否有帮助 -
我尝试在不带引号或其他参数的情况下添加 Remove-PSDrive R,首先在其他删除行之前,但不幸的是它仍然记得名称。不过谢谢!
标签: c# powershell dictionary drive