|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Process.Start failes on Win 2000 after showing open file dialogI have an application that is launching a process (see the code below) to perfom some operation on a file. On Windows 2000, if my application first uses the OpenFileDialog to open a file on the desktop, Process.Start failes with the following exception: System.ComponentModel.Win32Exception: The system cannot find the file specified at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo) at System.Diagnostics.Process.Start() at System.Diagnostics.Process.Start(ProcessStartInfo startInfo) The code is roughly as follows: // here we ask the user to open a file OpenFileDialog openFileBox = new OpenFileDialog(); openFileBox.Filter = mAddFileFilter.ToString(); openFileBox.FilterIndex = 1; if(openFileBox.ShowDialog() == DialogResult.OK) { inputFilePath = openFileBox.FileNames; } // later we launch a process to perform an operation on the file outputFilePath = System.IO.Path.GetTempFileName(); string arguments = "\"" + inputFilePath + "\" \"" + outputFilePath + "\""; arguments += " /a"; arguments += " /dm1"; arguments += " /DL0"; arguments += " /a1"; arguments += " /h" + progressWindow.ClassId; string ConverterPath = @"C:\Program Files\foo\bar\converter\go.exe"; // for example ProcessStartInfo psInfo = new ProcessStartInfo(ConverterPath, arguments); psInfo.WindowStyle = ProcessWindowStyle.Hidden; mProcess = Process.Start(psInfo); The exception is observed on Windows 2000, but never on Windows XP. It works fine on Windows 2000 if I never call the OpenFileDialog. I tried setting the WorkingDirectory of the ProcessStartInfo instance to the directory that contains the process executable, but this does not help. Thanks, Bret Hi Bret,
I'm not sure if it's a typo or not: inputFilePath = openFileBox.FileNames; FileNames returns an array of string rather than a string. Also, I think this might not be related to the open file dialog; you could verify this by hard code the inputFilePath using the result from the file dialog and test it again. This looks like a command line length limit, please verify the command line string length before pass to Process.Start(). I wasn't able to reproduce the issue on Windows 2000 using the information you provided; you might have to create a smaller reproducible project and send it to me. Thank you. Sincerely, Walter Wang (waw***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. If you are using Outlook Express, please make sure you clear the check box "Tools/Options/Read: Get 300 headers at a time" to see your reply promptly. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hi,
Thanks for your quick response Walter. Setting the inputFilePath from the open dialog was a typo. I did not paste the full code here, but meant just to give an impression of what I am doing. My first observation was that the same exact command that fails after the open file dialog works fine normally. So, I don't think the problem can be in the command string. I am, in fact, also having trouble reproducing in a minimal project. Perhaps there is something else going on that I haven't noticed. Yet, I seem to have a process start command whose success is depending on something outside of the actual command itself. What things could possibly cause this? Thanks, Bret Hi Bret,
So the issue only occurs for the specific program with specific arguments, and only occurs when the OpenFileDialog has been used? I must say that's a very strange one. By default, Process.Start is using ShellExecuteEx (you can use Reflector to view the source). The exception seems either ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND, it didn't tell exactly reason why the call failed. #ShellExecuteEx function() http://msdn2.microsoft.com/en-us/library/ms647733.aspx I would really appreciate it if you could create a reproducible project and let me see if there's anything I can do to find the root cause. By the way, you might want to use CreateProcess instead, just set the ProcessStartInfo.UseShellExecute to false: #ProcessStartInfo.UseShellExecute http://msdn2.microsoft.com/en-gb/library/system.diagnostics.processstartinfo .useshellexecute.aspx CreateProcess has much longer command line length limit than ShellExecute: #The Old New Thing: What is the command line length limit? http://blogs.msdn.com/oldnewthing/archive/2003/12/10/56028.aspx Although according to your description, this issue might not be related to command line length limit, you might want to try CreateProcess to see if it works. Regards, Walter Wang (waw***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hi Walter,
I am as confident as you that setting UseShellExecute=false will solve my problem. I had a similar issue a while back with a different process launching on Win 2000, and doing this fixed it. In this case, I have not applied this solution because my process opens a window that I need to hide, and it seems that setting WindowStyle=ProcessWindowStyle.Hidden does not work with UseShellExecute=false. Is this normal (I'm using .NET 1.1)? I've just disassembled and it seems that System.Diagnostics.ProcessStartWithCreate isn't copying the WindowStyle property into the STARTUPINFO structure for CreateProcess. Normally, can the window be supressed using CreateProcess, as it is with UseShellExecute=true + ProcessWindowStyle.Hidden? Otherwise, I agree that I need to reproduce the issue in a minimal project before I can expect a real answer here... Thanks, Bret Hi Bret,
It seems Process.Start will only apply the ProcessWindowStyle when we use ShellExecute; you might have to use P/Invoke to call CreateProcess directly to hide the window: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct STARTUPINFO { public Int32 cb; public string lpReserved; public string lpDesktop; public string lpTitle; public Int32 dwX; public Int32 dwY; public Int32 dwXSize; public Int32 dwYSize; public Int32 dwXCountChars; public Int32 dwYCountChars; public Int32 dwFillAttribute; public STARTF dwFlags; public SHOWWINDOW wShowWindow; public Int16 cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; public IntPtr hStdError; } public enum SHOWWINDOW : uint { SW_HIDE = 0, SW_SHOWNORMAL = 1, SW_NORMAL = 1, SW_SHOWMINIMIZED = 2, SW_SHOWMAXIMIZED = 3, SW_MAXIMIZE = 3, SW_SHOWNOACTIVATE = 4, SW_SHOW = 5, SW_MINIMIZE = 6, SW_SHOWMINNOACTIVE = 7, SW_SHOWNA = 8, SW_RESTORE = 9, SW_SHOWDEFAULT = 10, SW_FORCEMINIMIZE = 11, SW_MAX = 11, } [Flags] public enum STARTF : uint { STARTF_USESHOWWINDOW = 0x00000001, STARTF_USESIZE = 0x00000002, STARTF_USEPOSITION = 0x00000004, STARTF_USECOUNTCHARS = 0x00000008, STARTF_USEFILLATTRIBUTE = 0x00000010, STARTF_RUNFULLSCREEN = 0x00000020, // ignored for non-x86 platforms STARTF_FORCEONFEEDBACK = 0x00000040, STARTF_FORCEOFFFEEDBACK = 0x00000080, STARTF_USESTDHANDLES = 0x00000100, } [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public int dwProcessId; public int dwThreadId; } [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { public int nLength; public IntPtr lpSecurityDescriptor; public int bInheritHandle; } [DllImport("kernel32.dll")] static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); public static void Test() { const uint NORMAL_PRIORITY_CLASS = 0x0020; bool retValue; string Application = Environment.GetEnvironmentVariable("windir") + @"\Notepad.exe"; string CommandLine = string.Empty; PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION(); STARTUPINFO sInfo = new STARTUPINFO(); sInfo.dwFlags = STARTF.STARTF_USESHOWWINDOW; sInfo.wShowWindow = SHOWWINDOW.SW_HIDE; SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES(); SECURITY_ATTRIBUTES tSec = new SECURITY_ATTRIBUTES(); pSec.nLength = Marshal.SizeOf(pSec); tSec.nLength = Marshal.SizeOf(tSec); //Open Notepad retValue = CreateProcess(Application, CommandLine, ref pSec, ref tSec, false, NORMAL_PRIORITY_CLASS, IntPtr.Zero, null, ref sInfo, out pInfo); Process p = Process.GetProcessById(pInfo.dwProcessId); p.WaitForExit(); } You can find most of the P/Invoke declaration on http://www.pinvoke.net. Regarding the OpenFileDialog issue, I was wondering is it possible that it's related to current working directory? As far as I know, a common file dialog might change the working directory. Will it have impact on your application? Regards, Walter Wang (waw***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hi Walter,
Thank you for the example code. Indeed, calling CreateProcess directly fixes my problem and allows me to hide the process window. I will leave the interference of OpenFileDialog and ShellExecute as a mystery... Thanks, Bret Hi Bret,
Thanks for the update. Please feel free to open a new post if you're able to reproduce the issue of OpenFileDialog and ShellExecute on Win2000. Thanks. Regards, Walter Wang (waw***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. |
|||||||||||||||||||||||