UNCパスにProcessStartInfo.WorkingDirectoryを設定します
-
24-09-2019 - |
質問
私はスケジュールされたタスクとして実行することをVB.netで書かれていることの有用性を有します。これは、内部的に別の実行可能ファイルを呼び出し、それがマップされたドライブにアクセスする必要があります。どうやら窓は、ユーザーが認証資格情報は、タスク自体に供給されている場合でも、ログオンしていないときにマップされたドライブにアクセスしてスケジュールされたタスクに問題があります。 [OK]を、細かいます。
を回避するために、この私はちょうど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パスを使用して、マッピングされたドライブで使用されるのと同じ実装であり、プロセスが動作していない。
UNCパスにProcessStartInfo.WorkingDirectoryを設定する既知の問題はありますか?ない場合は、私が間違って何をやってんだ?
解決
ユーザーがログインしていませんマップされたドライブとあなたの問題は、彼らが存在しないということです。ドライブのみがマッピングされ、現在ログインしているユーザーにご利用いただけます。誰がログインされていない場合、ドライブがマップされていません。
あなたはCMD、舞台裏ドライブにUNCをマッピングして、あなたのコードを実行しますコールPUSHDを介して実行することができます回避策として。私は、コールの結果が、その者を見ることができるように(私も標準出力をリダイレクトしています私の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
他のヒント
私はこの問題に出くわしましたし、受け入れられた解決策は、私にとっては少し複雑です。私がやったことはUNCパスを取り、[Path.GetTempDir()]\[Guid.NewGuid().ToString()]
への内容をコピーしてprocess.StartInfo.WorkingDirectory
のための私の作業ディレクトリとしてそれを使用することでした。 IDisposableインターを実装し、処分に作成した一時ディレクトリをクリーンアップします「環境」というクラスでこの機能をラップします。このような何か(設定参照を無視する):
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);
}
}
}