代码之家  ›  专栏  ›  技术社区  ›  26071986

使用进程以后台模式打开文件

  •  2
  • 26071986  · 技术社区  · 14 年前

    在我的程序中,我需要使用外部应用程序(BentleyMicroStation,如果它很重要的话)打开一个文件。我需要打开文件的应用程序对用户不可见(我将对其执行一些操作)。

    除了“example.txt”或“example.doc”上的测试显示,即使将processstartinfo属性windowstyle设置为最小化或隐藏,也可以看到打开文件的应用程序。

    那么,如何在不向用户显示操作的情况下打开文件?当然,以后可以隐藏应用程序窗口,但这不是我需要的…

    UPD。 我和宾利MicroStation XM版合作。它有一个可以禁用的启动屏幕。

    主要问题:通过process和processstartinfo启动MicroStation时,命令行参数(要打开的文件名)和各种设置(如windowsstyle(hidden)、useShellExecute(false)、createNowindow(true)应用程序窗口存在且可见。使用win-api-winexec和ucmdshow设置为0(隐藏)的简单测试给出了相同的结果。

    可以接受在后台模式下启动应用程序的任何解决方案。事先谢谢。

    3 回复  |  直到 12 年前
        1
  •  3
  •   Oleg    14 年前

    windows desktop CreateDesktop

    using System;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.ComponentModel;
    
    namespace HiddenDesktop {
        class Program {
            static void Main (string[] args) {
                string desktopName = "MyDesktop";
                string appPath = @"%SystemRoot%\system32\cmd.exe";
                string parameters = @"/c dir C:\ >%TEMP%\dir.txt";
                IntPtr hDesktop = IntPtr.Zero;
                NativeMethods.ProcessInformation processInfo = new NativeMethods.ProcessInformation ();
                bool isSuccess;
    
                try {
                    hDesktop = NativeMethods.CreateDesktop (desktopName, null, null, 0,
                            NativeMethods.ACCESS_MASK.MAXIMUM_ALLOWED, null);
                    if (hDesktop == IntPtr.Zero) {
                        DisplayLastErrorMessage ();
                        return;
                    }
    
                    NativeMethods.StartupInfo startupInfo = new NativeMethods.StartupInfo ();
                    NativeMethods.CreateProcessFlags dwCreationFlags = NativeMethods.CreateProcessFlags.NormalPriorityClass;
                    startupInfo.cb = Marshal.SizeOf (typeof (NativeMethods.StartupInfo));
                    startupInfo.lpDesktop = "WinSta0\\" + desktopName;
                    string currentDirectory = Environment.CurrentDirectory;
                    appPath = Environment.ExpandEnvironmentVariables (appPath);
                    //if (appPath.IndexOf (' ') != -1)
                    //    appPath = '\"' + appPath + '\"';
                    StringBuilder sbParameters = new StringBuilder (3 + appPath.Length + parameters.Length);
                    if (appPath.IndexOf (' ') != -1) {
                        sbParameters.Append ('\"');
                        sbParameters.Append (appPath);
                        sbParameters.Append ('\"');
                    }
                    else
                        sbParameters.Append (appPath);
                    sbParameters.Append (' ');
                    sbParameters.Append (parameters);
                    // appPath - full path to the exe without having " if the file has blanks in the path
                    isSuccess = NativeMethods.CreateProcess (appPath,
                        sbParameters.ToString(), IntPtr.Zero, IntPtr.Zero, false, dwCreationFlags,
                    IntPtr.Zero, currentDirectory, ref startupInfo, out processInfo);
                    if (!isSuccess) {
                        DisplayLastErrorMessage ();
                        return;
                    }
                    NativeMethods.CloseHandle (processInfo.hThread);
                    processInfo.hThread = IntPtr.Zero;
    
                    if (NativeMethods.WaitForSingleObject (processInfo.hProcess, NativeMethods.Infinite) == NativeMethods.WaitObject0) {
                        Console.WriteLine ("the process is ended");
                    }
                }
                finally {
                    if (processInfo.hThread != IntPtr.Zero)
                        isSuccess = NativeMethods.CloseHandle (processInfo.hThread);
                    if (processInfo.hProcess != IntPtr.Zero)
                        isSuccess = NativeMethods.CloseHandle (processInfo.hProcess);
                    if (hDesktop != IntPtr.Zero)
                        isSuccess = NativeMethods.CloseDesktop (hDesktop);
                }
            }
            static void DisplayLastErrorMessage () {
                int errorCode = Marshal.GetLastWin32Error ();
                Win32Exception error32 = new Win32Exception (errorCode);
                Console.WriteLine ("Error {0}: {1}", errorCode, error32.Message);
            }
        }
        internal static class NativeMethods {
            internal const int NoError = 0;
            internal const UInt32 Infinite = 0xFFFFFFFF;
    
            internal const UInt32 WaitAbandoned = 0x00000080;
            internal const UInt32 WaitObject0 = 0x00000000;
            internal const UInt32 WaitTimeout = 0x00000102;
    
            [Flags]
            internal enum ACCESS_MASK : uint {
                DELETE = 0x00010000,
                READ_CONTROL = 0x00020000,
                WRITE_DAC = 0x00040000,
                WRITE_OWNER = 0x00080000,
                SYNCHRONIZE = 0x00100000,
    
                STANDARD_RIGHTS_REQUIRED = 0x000f0000,
    
                STANDARD_RIGHTS_READ = 0x00020000,
                STANDARD_RIGHTS_WRITE = 0x00020000,
                STANDARD_RIGHTS_EXECUTE = 0x00020000,
    
                STANDARD_RIGHTS_ALL = 0x001f0000,
    
                SPECIFIC_RIGHTS_ALL = 0x0000ffff,
    
                ACCESS_SYSTEM_SECURITY = 0x01000000,
    
                MAXIMUM_ALLOWED = 0x02000000,
    
                GENERIC_READ = 0x80000000,
                GENERIC_WRITE = 0x40000000,
                GENERIC_EXECUTE = 0x20000000,
                GENERIC_ALL = 0x10000000,
    
                DESKTOP_READOBJECTS = 0x00000001,
                DESKTOP_CREATEWINDOW = 0x00000002,
                DESKTOP_CREATEMENU = 0x00000004,
                DESKTOP_HOOKCONTROL = 0x00000008,
                DESKTOP_JOURNALRECORD = 0x00000010,
                DESKTOP_JOURNALPLAYBACK = 0x00000020,
                DESKTOP_ENUMERATE = 0x00000040,
                DESKTOP_WRITEOBJECTS = 0x00000080,
                DESKTOP_SWITCHDESKTOP = 0x00000100,
    
                WINSTA_ENUMDESKTOPS = 0x00000001,
                WINSTA_READATTRIBUTES = 0x00000002,
                WINSTA_ACCESSCLIPBOARD = 0x00000004,
                WINSTA_CREATEDESKTOP = 0x00000008,
                WINSTA_WRITEATTRIBUTES = 0x00000010,
                WINSTA_ACCESSGLOBALATOMS = 0x00000020,
                WINSTA_EXITWINDOWS = 0x00000040,
                WINSTA_ENUMERATE = 0x00000100,
                WINSTA_READSCREEN = 0x00000200,
    
                WINSTA_ALL_ACCESS = 0x0000037f
            }
    
            [StructLayout (LayoutKind.Sequential)]
            public class SECURITY_ATTRIBUTES {
                public int nLength;
                public IntPtr lpSecurityDescriptor;
                public int bInheritHandle;
            }
            [StructLayout (LayoutKind.Sequential)]
            internal struct ProcessInformation {
                internal IntPtr hProcess;
                internal IntPtr hThread;
                internal int dwProcessId;
                internal int dwThreadId;
            }
    
            [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            internal struct StartupInfo {
                internal Int32 cb;
                internal string lpReserved;
                internal string lpDesktop;
                internal string lpTitle;
                internal Int32 dwX;
                internal Int32 dwY;
                internal Int32 dwXSize;
                internal Int32 dwYSize;
                internal Int32 dwXCountChars;
                internal Int32 dwYCountChars;
                internal Int32 dwFillAttribute;
                internal Int32 dwFlags;
                internal Int16 wShowWindow;
                internal Int16 cbReserved2;
                internal IntPtr lpReserved2;
                internal IntPtr hStdInput;
                internal IntPtr hStdOutput;
                internal IntPtr hStdError;
            }
            [Flags]
            internal enum CreateProcessFlags : uint {
                DebugProcess = 0x00000001,
                DebugOnlyThisProcess = 0x00000002,
                CreateSuspended = 0x00000004,
                DetachedProcess = 0x00000008,
                CreateNewConsole = 0x00000010,
                NormalPriorityClass = 0x00000020,
                IdlePriorityClass = 0x00000040,
                HighPriorityClass = 0x00000080,
                RealtimePriorityClass = 0x00000100,
                CreateNewProcessGroup = 0x00000200,
                CreateUnicodeEnvironment = 0x00000400,
                CreateSeparateWowVdm = 0x00000800,
                CreateSharedWowVdm = 0x00001000,
                CreateForcedos = 0x00002000,
                BelowNormalPriorityClass = 0x00004000,
                AboveNormalPriorityClass = 0x00008000,
                InheritParentAffinity = 0x00010000,
                InheritCallerPriority = 0x00020000,  // Deprecated
                CreateProtectedProcess = 0x00040000,
                ExtendedStartupinfoPresent = 0x00080000,
                ProcessModeBackgroundBegin = 0x00100000,
                ProcessModeBackgroundEnd = 0x00200000,
                CreateBreakawayFromJob = 0x01000000,
                CreatePreserveCodeAuthzLevel = 0x02000000,
                CreateDefaultErrorMode = 0x04000000,
                CreateNoWindow = 0x08000000,
                ProfileUser = 0x10000000,
                ProfileKernel = 0x20000000,
                ProfileServer = 0x40000000,
                CreateIgnoreSystemDefault = 0x80000000,
            }
    
            [DllImport ("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            internal static extern IntPtr CreateDesktop (
                            string desktopName,
                            string device, // must be null.
                            string deviceMode, // must be null,
                            int flags,  // use 0
                            ACCESS_MASK accessMask,
                            SECURITY_ATTRIBUTES attributes);
            [DllImport ("user32.dll", SetLastError = true)]
            [return: MarshalAs (UnmanagedType.Bool)]
            internal static extern bool CloseDesktop (IntPtr hDesktop);
    
            [DllImport ("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            [return: MarshalAs (UnmanagedType.Bool)]
            internal static extern bool CreateProcess (string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes,
                bool bInheritHandles, CreateProcessFlags dwCreationFlags, IntPtr lpEnvironment,
                string lpCurrentDirectory, ref StartupInfo lpStartupInfo, out ProcessInformation lpProcessInformation);
    
            [DllImport ("kernel32.dll", SetLastError = true)]
            [return: MarshalAs (UnmanagedType.Bool)]
            internal static extern bool CloseHandle (IntPtr hObject);
            [DllImport ("kernel32.dll", SetLastError = true)]
            internal static extern UInt32 WaitForSingleObject (IntPtr hHandle, UInt32 dwMilliseconds);
        }
    }
    
        2
  •  1
  •   Giorgi    14 年前
        3
  •  0
  •   feelapi    12 年前