Frage

Ich habe ein Dienstprogramm, dass ich in VB.net geschrieben haben, dass läuft als geplante Aufgaben. Sie ruft intern eine andere ausführbare Datei, und es hat ein zugeordnetes Laufwerk zuzugreifen. Offenbar Fenster haben Probleme mit geplanten Tasks zugeordnete Laufwerke zugreifen, wenn der Benutzer nicht angemeldet ist, auch wenn die Authentifizierungsdaten an die Aufgabe selbst geliefert werden. Ok, gut.

Um dies zu umgehen ich meine Bewerbung nur den UNC-Pfad übergeben.

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

Dies ist die gleiche Implementierung ich mit dem zugeordneten Laufwerk verwenden jedoch den UNC-Pfad verwendet wird, wird der Prozess nicht verhalten, als ob der UNC-Pfad das Arbeitsverzeichnis ist.

Gibt es bekannte Probleme ProcessStartInfo.WorkingDirectory zu einem UNC-Pfad einstellen? Wenn nicht, was mache ich falsch?

War es hilfreich?

Lösung

Ihr Problem mit zugeordneten Laufwerken, wenn Benutzer nicht angemeldet ist, dass sie nicht existieren. Laufwerke werden nur abgebildet und zur Verfügung, die aktuell angemeldeten Benutzers. Wenn niemand angemeldet ist, werden keine Laufwerke zugeordnet.

Als Abhilfe können Sie durch CMD ausführen können, rufen Sie PUSHD die Ihre UNC mit einem Antrieb hinter den Kulissen abbildet und dann Code ausführen. Ich habe die tree.com Datei von meinem system32 kopiert und legte sie auf meinem Dateiserver als „tree4.com“ und dieser Code funktioniert wie erwartet (ich Umleitung auch die Standardausgabe so dass ich die Ergebnisse des Gesprächs sehen kann, aber das ist nicht erforderlich)

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

Andere Tipps

Ich lief über dieses Problem und die akzeptierte Lösung ist ein wenig für mich kompliziert. Was ich tat, war den UNC-Pfad zu nehmen und kopieren Sie den Inhalt davon [Path.GetTempDir()]\[Guid.NewGuid().ToString()] und dann, dass für die process.StartInfo.WorkingDirectory als mein Arbeitsverzeichnis verwenden. Wickeln Sie diese Funktionalität in einer Klasse mit dem Namen „Umwelt“, die IDisposable umsetzen wird und in den dispose aufzuräumen das temporäre Verzeichnis, das Sie erstellt. So etwas wie diese (die Einstellungen Referenzen ignorieren):

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

Und ProcessEnvironment sieht aus wie:

 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);
            }
        }
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top