从Winforms创建独立进程的正确方法 [英] Proper Way To Create a Standalone Process From Winforms

查看:78
本文介绍了从Winforms创建独立进程的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



访问[文件位置和名称]时发生共享冲突。



如果我保持启动的编辑应用程序打开并关闭启动编辑器然后尝试保存更改的WinForms应用程序,它允许在100%的时间内保存更改而不会出现问题。相信ProcessStart实际上并没有在解耦的线程中启动进程,我尝试使用新线程启动编辑应用程序,这导致了相同的情况。如何从WinForms应用程序启动编辑程序作为独立的,解耦的程序,以便用户可以在不关闭WinForms应用程序的情况下保存更改?我很欣赏任何我不做或不考虑作为选项的见解。



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



  private   void  pbxImage_ButtonClick(object 发件人 EventArgs  e)
{
尝试
{
string strImageNum = BDL 数据[ImageNumber]。ToString();
string strDirectory = < span class =code-leadattribute> ConfigurationManager .AppSettings [ImageLocation];
string fileName = < span class =code-leadattribute> string .Empty;
fileName = string 。格式({{span class =code-attribute> 0 } \\ { 1 } { 2 } strDirectory strImageNum .jpg);
HelperFunctions .RunProcess(mspaint.exe, strDirectory ,fileName);
}
catch (例外情况) ex)
{
MessageBox 显示(ex.Message) );
}
}

public static void RunProcess(string ProcessExe string workingDirectory params string [] args)
{
Process myProcess = new Process();
尝试
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo 参数 < span class =code-leadattribute> = HelperFunctions .EscapeArguments(args); // 正确格式化参数。
startInfo CreateNoWindow = false;
startInfo FileName = App Shared HelperFunctions .FindExePath( ProcessExe); // 要打开的程序的名称
// 尝试将工作目录设置为%USERPROFILE%\ Document并且无差异
startInfo WorkingDirectory = workingDirectory;
startInfo RedirectStandardError = 假;
startInfo RedirectStandardInput = 假;
startInfo RedirectStandardOutput = 假;
startInfo UseShellExecute = 真正;
myProcess StartInfo = StartInfo的;
// myProcess.Start(); //尝试了这个直接的方法调用,但失败了
// 试图使用新的线程
线程 线程 = new 线程(新的ThreadStart(委托{ myProcess Start();}));
// 尝试未设置公寓状态,并设置为具有相同结果的MTA和STA
thread .TrySetApartmentState(ApartmentState.STA);
thread .Start();
}
catch (例外情况) ex)
{
控制台 WriteLine(ex.Message) );
}
}

解决方案

好的,所以,我现在第一次尝试一些解决方案,我们已经确定了最新情况,是/是



a )完全重新组织你的代码[叹气]



b)将图像副本复制到临时目录 - 将这些图像加载到图片框中,编辑工作副本..当编辑完成时(你将等待mspaint进程结束)将编辑后的一个复制回临时目录并刷新图片框



c产生mspaint过程之前,在图片框中显示一个完全不同的图像 - 可能是'正在''图像编辑正在进行' - 这可能会释放你正在编辑的图像



我不知道它们有多实用 - 我觉得它对你的过程有意义 - 我会尝试从(c)亲自开始


我不同意你需要做线程的东西 - 看看错误的用途会很有趣



 myProcess.Start( ); 





我也想知道,因为网络的东西,如果有权利/访问问题 - 所以我想知道是否将这些添加到startInfo会使情况好坏更好



 startInfo.Domain =<   > ; 
startInfo.UserName =< 用户 名称/帐户 读/写 访问 网络 分享 > ;
startInfo.Password =< 密码 for user > ;





显然,唯一的问题是,如果这样做,那么你有一个暴露的密码,但是可以处理



我最后的想法是,(尽管存在共享问题)你需要等待(mspaint)进程吗?退出?



我想知道在mspaint编辑会话进行过程中使用命令行程序'openfiles'是否有任何意义,看文件是否有用被其他东西锁定 - 我会开始 - >右键单击命令提示符 - >以管理员身份运行,然后运行'openfiles'并试验以查看文件是否为共享[/ edit]


I am trying to offer customers the ability to edit image files that are on a network drive by using ProcessStart within a WinForms application to launch the editing program for the file. It launches the editing program just fine with the image; however, it will not allow them to save changes resulting in an error:

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

If I keep the launched editing application open and close the WinForms application that launched the editor and then attempt to save the changes, it allows the changes to be saved 100% of the time without a problem. Believing that the ProcessStart was not actually launching the process in a decoupled thread, I tried to launch the editing application using a new thread and that resulted in the same situation. How can I launch the editing program from the WinForms app as a standalone, decoupled, program so the user can save the changes without closing the WinForms application? I appreciate any insight into what I am not doing or not considering as an option.

This is the method I am calling to launch the editing program. The ProcessExe is the name of the editing program on the users machines, the workingDirectory is the same value as the network file location, and the args is the fileLocation and Name

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

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

解决方案

ok, so, my first try at some solutions now we've established whats going on, is/are

a) completely re-organise your code [sigh]

b) make a copy of the images to a temp directory - load these ones into the picture box, edit a working copy .. when the edit is finished (you'll wait for the end of the mspaint process) copy the edited one back to the temp directory and refresh the picture box

c) before spawning off the mspaint process, display a completely different image in the picture box - maybe a 'canned' 'image edit in process' - this may free the image you're editing

I don't know how practical any of them are - its whatever makes sense to your process I guess - I'd try starting at (c) personally


I disagree that you need to do the threading stuff - it would be interesting to see what the error was using

myProcess.Start(); 



I also wonder, because of the network stuff, if there's rights/access issues - so I wonder if adding these to startInfo would make the situation better or worse

startInfo.Domain = "<domain>";
startInfo.UserName = "<User Name/Account With Read/Write Access To Network Share>";
startInfo.Password = "<Password for user>";



obviously, the one issue is, if this works, then you have a password exposed, but that can be handled

My last thought is, (despite the sharing issue) do you need to wait for the (mspaint)process to exit ?

[edit] I wonder if there's any point in using the commandline program 'openfiles' while a mspaint edit session is in progress, to see if the file is being locked by something else - I'd start -> right-click 'Command Prompt' -> Run As Administrator, then run 'openfiles' and experiment to see if the files are 'shared' [/edit]


这篇关于从Winforms创建独立进程的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆