我有一个Windows服务,用于更新网络上的一些文件,这些文件被映射为驱动器“Z:\”。当我以管理员身份从VS运行代码时,我能够在映射的驱动器上复制该文件,但是当从在管理员帐户下运行的服务运行时,同样的事情会失败。 映射驱动器是从运行服务的同一帐户创建的。有点令人费解的是,为什么它从VS运行而不是从服务运行。 使用UNC比使用网络驱动器更好。 在论坛下面有一个解决方法 http://support.microsoft.com/default.aspx?scid=kb;en-us;827421#appliesto 但是它使用了UNC未映射的驱动器。
答案 0 :(得分:3)
我建议UNC是一个更好的主意。
如果在登录时映射了映射的驱动器怎么办?服务可以在用户甚至没有登录的情况下运行,因此可能永远不会创建映射。
答案 1 :(得分:3)
我们也经历过这种情况,虽然我不能告诉你为什么我们的决议有效,但我可以告诉你什么有用。
在代码中映射驱动器。不要仅仅因为您使用相同的帐户而依赖于映射的驱动器。
根据我们看到的行为,这就是GUESS在我们的情况下发生的事情,以及你身上发生的事情。
我们遇到问题的服务使用了在登录脚本中映射的驱动器。如果我们让机器以服务使用的同一用户身份登录,那么它可以工作,但如果没有,它将无法工作。基于此,我猜测驱动器根本没有映射,因为服务没有真正“登录”。
用代码映射驱动器修复它。
作为旁注,您也可以直接引用UNC路径,但我们也有权限问题。映射驱动器,传入用户名和密码对我们来说效果更好。
我们的代码:
public static class NetworkDrives
{
public static bool MapDrive(string DriveLetter, string Path, string Username, string Password)
{
bool ReturnValue = false;
if(System.IO.Directory.Exists(DriveLetter + ":\\"))
{
DisconnectDrive(DriveLetter);
}
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "net.exe";
p.StartInfo.Arguments = " use " + DriveLetter + ": " + '"' + Path + '"' + " " + Password + " /user:" + Username;
p.Start();
p.WaitForExit();
string ErrorMessage = p.StandardError.ReadToEnd();
string OuputMessage = p.StandardOutput.ReadToEnd();
if (ErrorMessage.Length > 0)
{
throw new Exception("Error:" + ErrorMessage);
}
else
{
ReturnValue = true;
}
return ReturnValue;
}
public static bool DisconnectDrive(string DriveLetter)
{
bool ReturnValue = false;
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "net.exe";
p.StartInfo.Arguments = " use " + DriveLetter + ": /DELETE";
p.Start();
p.WaitForExit();
string ErrorMessage = p.StandardError.ReadToEnd();
string OuputMessage = p.StandardOutput.ReadToEnd();
if (ErrorMessage.Length > 0)
{
throw new Exception("Error:" + ErrorMessage);
}
else
{
ReturnValue = true;
}
return ReturnValue;
}
}
使用上面的类,您可以随意映射和断开驱动器。如果这是一项服务,我建议您在需要之前映射驱动器,并在需要后立即断开驱动器。
答案 2 :(得分:0)
我努力解决同样的问题(约3天)。似乎它与NTFS和文件级权限更相关。如果您使用共享位置而不是驱动器,那就更好了。