【问题标题】:Sharing Violation from Program That Was Launched Using Process Start From WinForms共享使用从 WinForms 开始的进程启动的程序的冲突
【发布时间】:2014-10-31 01:15:58
【问题描述】:

我试图让客户能够编辑网络驱动器上的图像文件,方法是使用 WinForms 应用程序中的 ProcessStart 来启动文件的编辑程序。它可以很好地启动图像编辑程序;但是,它不允许他们保存导致错误的更改:

A sharing violation occurred while accessing [File location and Name].

如果我保持启动的编辑应用程序打开并关闭启动编辑器的 WinForms 应用程序,然后尝试保存更改,则可以 100% 地保存更改而不会出现问题。相信ProcessStart 实际上并没有在解耦线程中启动进程,我尝试使用新线程启动编辑应用程序,结果出现了同样的情况。如何从 WinForms 应用程序启动编辑程序作为独立的、解耦的程序,以便用户可以在不关闭 WinForms 应用程序的情况下保存更改?我很感激任何关于我没有做或没有考虑作为一种选择的见解。

这是我用来启动编辑程序的方法。 ProcessExe 是用户机器上编辑程序的名称,workingDirectory 是与网络文件位置相同的值,args 是文件位置和名称

    public static void RunProcess(string ProcessExe, string workingDirectory, params string[] args)
    {
        Process myProcess = new Process();
        try
        {
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.Arguments = HelperFunctions.EscapeArguments(args); //format the arguments correctly.
            startInfo.CreateNoWindow = false;
            startInfo.FileName = App.Shared.HelperFunctions.FindExePath(ProcessExe); //Name of the program to be opened
            //Tried setting the working directory to %USERPROFILE%\Documents and no difference
            startInfo.WorkingDirectory = workingDirectory;
            startInfo.RedirectStandardError = false;
            startInfo.RedirectStandardInput = false;
            startInfo.RedirectStandardOutput = false;
            startInfo.UseShellExecute = true;
            myProcess.StartInfo = startInfo;
            //myProcess.Start(); //Tried this straight forward method call and it failed
            //Tried to use a new thread
            Thread thread = new Thread(new ThreadStart(delegate { myProcess.Start(); }));
            //Tried without setting the apartment state, and setting as MTA and STA with the same result
            thread.TrySetApartmentState(ApartmentState.STA);
            thread.Start();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

调用代码:

    private void pbxImage_ButtonClick(object sender, EventArgs e)
    {
        try
        {
            string strImageNum = BDL.Data["ImageNumber"].ToString();
            string strDirectory = ConfigurationManager.AppSettings["ImageLocation"];
            string fileName = string.Empty;
            fileName = string.Format("{0}\\{1}{2}", strDirectory, strImageNum, ".jpg");
            HelperFunctions.RunProcess("mspaint.exe", strDirectory, fileName);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

我使用了来自 VDohnal (stackoverflow.com/a/20623302/2224701) 的代码,并验证了图像文件实际上已被主机 WinForms 应用程序锁定。

【问题讨论】:

  • 听起来不像是线程问题。听起来您的程序锁定了图像文件。您没有向我们展示该代码。
  • 使用此代码找出究竟是哪个进程锁定了文件stackoverflow.com/a/20623302/2224701
  • 我将尝试链接中的代码。您是正确的,程序在启动 ProcessStart 时会在图像文件上创建一个锁。就调用代码而言,它是一个简单的 ButtonClick 事件"

标签: .net multithreading winforms


【解决方案1】:

感谢 Garth J. Lancaster。 Garth 指出我正在使用 Picture.Load(file) 在 WinForms 应用程序中显示图像。这样做会锁定图像文件;因此,当我尝试使用单击事件将图像文件打开到 MS Paint 中时,该文件已被锁定,从而创建了共享条件。解决方案是从图像文件中的 byte[] 创建位图并使用 Picture.Image = bitmap.我不知道 Picture.Load() 在源图像文件上创建了一个锁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-24
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多