سؤال

لدي فائدة كتبت في 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؟ إذا لم يكن كذلك ، ماذا أفعل خطأ؟

هل كانت مفيدة؟

المحلول

مشكلتك في محركات الأقراص المعينة عند عدم تسجيل المستخدمين هي أنها غير موجودة. يتم تعيين محركات الأقراص فقط ومتاحة للمستخدم الذي تم تسجيله حاليًا. إذا لم يتم تسجيل أي شخص ، فلا يتم تعيين محركات الأقراص.

كحل بديل ، يمكنك الركض من خلال CMD ، واتصل PushD والذي سيقوم بتخطيط UNC الخاص بك إلى محرك الأقراص خلف الكواليس ثم تنفيذ الكود الخاص بك. لقد قمت بنسخ ملف Tree.com من System32 الخاص بي ووضعته على خادم الملفات الخاص بي على أنه "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();
                }

وبيئة ProcessEnviper يشبه:

 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);
            }
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top