Question

J'ai un utilitaire que je l'ai écrit dans VB.net qui fonctionne comme des tâches planifiées. Elle appelle en interne un autre exécutable et il doit accéder à un lecteur mappé. Apparemment, Windows a des problèmes avec des tâches planifiées l'accès aux lecteurs mappés lorsque l'utilisateur n'est pas connecté, même lorsque les informations d'authentification sont fournis à la tâche elle-même. Ok, très bien.

Pour contourner ce que je viens de passer ma demande le chemin 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()

est la même implémentation je avec le lecteur mappé, mais en utilisant le chemin UNC, le processus ne se comporte pas comme si le chemin UNC est le répertoire de travail.

Y a-t-il des problèmes Known ProcessStartInfo.WorkingDirectory à un chemin UNC? Sinon, qu'est-ce que je fais mal?

Était-ce utile?

La solution

Votre problème avec les lecteurs mappés lorsque les utilisateurs ne sont pas connectés est qu'ils n'existent pas. Les lecteurs sont uniquement mis en correspondance et disponible pour l'utilisateur actuellement connecté. Si personne n'est connecté, aucun lecteur sont mis en correspondance.

Pour contourner ce problème, vous pouvez exécuter par CMD, appelez PUSHD qui mapper votre UNC à un lecteur dans les coulisses, puis d'exécuter votre code. J'ai copié le fichier tree.com de mon et l'a placé system32 sur mon serveur de fichiers comme « tree4.com » et ce code fonctionne comme prévu (je rediriger également la sortie standard afin que je puisse voir les résultats de l'appel, mais c'est pas nécessaire)

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

Autres conseils

Je suis tombé sur ce problème et la solution retenue est un peu compliqué pour moi. Ce que je faisais était de prendre le chemin UNC et copier le contenu de celui-ci à [Path.GetTempDir()]\[Guid.NewGuid().ToString()] et utiliser alors que mon répertoire de travail pour le process.StartInfo.WorkingDirectory. Enveloppez cette fonctionnalité dans une classe appelée « Environnement » qui mettra en œuvre IDisposable et dans le Éliminez nettoyer le répertoire temporaire que vous avez créé. Quelque chose comme ceci (ignorer les paramètres références):

 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();
                }

Et ProcessEnvironment ressemble à:

 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);
            }
        }
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top