【问题标题】:Setting ProcessStartInfo.WorkingDirectory to an UNC Path将 ProcessStartInfo.WorkingDirectory 设置为 UNC 路径
【发布时间】:2010-04-06 17:01:23
【问题描述】:

我有一个在 VB.net 中编写的实用程序,它作为计划任务运行。它在内部调用另一个可执行文件,并且必须访问映射的驱动器。显然,Windows 在用户未登录时访问映射驱动器的计划任务存在问题,即使将身份验证凭据提供给任务本身也是如此。好的,好的。

为了解决这个问题,我刚刚将 UNC 路径传递给我的应用程序。

process.StartInfo.FileName = 'name of executable'
process.StartInfo.WorkingDirectory = '\\unc path\'
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
process.StartInfo.Arguments = 'arguments to executable'
process.Start()

这与我对映射驱动器使用的实现相同,但是使用 UNC 路径时,进程的行为不像 UNC 路径是工作目录。

将 ProcessStartInfo.WorkingDirectory 设置为 UNC 路径是否存在任何已知问题?如果没有,我做错了什么?

【问题讨论】:

    标签: c# .net vb.net process.start


    【解决方案1】:

    当用户未登录时,映射驱动器的问题在于它们不存在。驱动器仅映射并可供当前登录的用户使用。如果没有人登录,则不会映射任何驱动器。

    作为一种解决方法,您可以通过 CMD 运行,调用 PUSHD,它将您的 UNC 映射到幕后的驱动器,然后执行您的代码。我已经从我的 system32 复制了 tree.com 文件并将其作为“tree4.com”放在我的文件服务器上,并且此代码按预期工作(我还重定向标准输出,因此我可以看到调用的结果,但那是没必要)

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    
        Using P As New Process()
            'Launch a standard hidden command window
            P.StartInfo.FileName = "cmd.exe"
            P.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
            P.StartInfo.CreateNoWindow = True
    
            'Needed to redirect standard error/output/input
            P.StartInfo.UseShellExecute = False
    
            P.StartInfo.RedirectStandardInput = True
            P.StartInfo.RedirectStandardOutput = True
    
            'Add handler for when data is received
            AddHandler P.OutputDataReceived, AddressOf SDR
    
            'Start the process
            P.Start()
    
            'Begin async data reading
            P.BeginOutputReadLine()
    
            '"Map" our drive
            P.StandardInput.WriteLine("pushd \\file-server\File-Server")
    
            'Call our command, you could pass args here if you wanted
            P.StandardInput.WriteLine("tree2.com  c:\3ea7025b247d0dfb7731a50bf2632f")
    
            'Once our command is done CMD.EXE will still be sitting around so manually exit
            P.StandardInput.WriteLine("exit")
            P.WaitForExit()
        End Using
    
        Me.Close()
    End Sub
    Private Sub SDR(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
        Trace.WriteLine(e.Data)
    End Sub
    

    【讨论】:

      【解决方案2】:

      我遇到了这个问题,接受的解决方案对我来说有点复杂。我所做的是采用 UNC 路径并将其内容复制到 [Path.GetTempDir()]\[Guid.NewGuid().ToString()],然后将其用作 process.StartInfo.WorkingDirectory 的工作目录。将此功能包装在一个名为“Environment”的类中,该类将实现 IDisposable 并在 dispose 中清理您创建的临时目录。像这样(忽略设置参考):

       using (var env = new ProcessEnvironment(settings))
                      {
                          filePath = Path.Combine(env.WorkingDirectory, settings.ApplicationEXE);
                          var psi = new ProcessStartInfo
                          {
                              UseShellExecute = false,
                              FileName = filePath,
                              WorkingDirectory = env.WorkingDirectory,
                              Arguments = (args != null && args.Length > 0 ? String.Join(" ", args) : null)
                          };
      
                          var proc = Process.Start(psi);
      
                          if (env.ExecutingFromTempDir || settings.WaitForExit)
                              proc.WaitForExit();
                      }
      

      ProcessEnvironment 看起来像:

       class ProcessEnvironment : IDisposable
          {
              private Settings itsSettings;
              private string itsTempDestDirectory;
              public string WorkingDirectory { get; set; }
              public bool ExecutingFromTempDir { get { return !String.IsNullOrEmpty(itsTempDestDirectory); } }
      
              public ProcessEnvironment(Settings settings)
              {
                  this.itsSettings = settings;
      
                  WorkingDirectory = GetWorkingDirectory();
              }
      
              private string GetWorkingDirectory()
              {
                  var dirInfo = new DirectoryInfo(itsSettings.StartupFolder);
      
                  if (!IsUncDrive(dirInfo))
                      return itsSettings.StartupFolder;
      
                  return CreateWorkingDirectory(dirInfo);
              }
      
              private string CreateWorkingDirectory(DirectoryInfo dirInfo)
              {
                  var srcPath = dirInfo.FullName;
                  itsTempDestDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
                  Directory.CreateDirectory(itsTempDestDirectory);
      
                  //Now Create all of the directories
                  foreach (string dirPath in Directory.GetDirectories(srcPath, "*", SearchOption.AllDirectories))
                      Directory.CreateDirectory(dirPath.Replace(srcPath, itsTempDestDirectory));
      
                  //Copy all the files & Replaces any files with the same name
                  foreach (string newPath in Directory.GetFiles(srcPath, "*.*", SearchOption.AllDirectories))
                      File.Copy(newPath, newPath.Replace(srcPath, itsTempDestDirectory), true);
      
                  return itsTempDestDirectory;
              }
      
              private bool IsUncDrive(DirectoryInfo dirInfo)
              {
                  Uri uri = null;
                  if (!Uri.TryCreate(dirInfo.FullName, UriKind.Absolute, out uri))
                  {
                      return false;
                  }
                  return uri.IsUnc;
              }
      
      
      
              public void Dispose()
              {
                  try
                  {
                      if (ExecutingFromTempDir)
                          Directory.Delete(itsTempDestDirectory, true);
      
                  }
                  catch (Exception ex)
                  {  //do nothing - if we can't delete then we can't do it
                      Console.WriteLine("Failed in Dispose: " + ex);
                  }
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多