C# 使用进程在后台模式下打开文件

C# 使用进程在后台模式下打开文件,c#,process,C#,Process,在我的程序中,我需要使用外部应用程序(Bentley MicroStation,如果重要的话)打开一个文件。我需要打开文件的应用程序对用户不可见(我将对其执行一些操作) 使用Process打开文件的方法似乎很好,除了一件事——对“example.txt”或“example.doc”的测试表明,即使将ProcessStartInfo属性WindowsStyle设置为Minimized或Hidden,您仍然可以看到打开文件的应用程序 那个么,如何在不向用户显示操作的情况下打开文件呢?当然,之后可以隐

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

使用Process打开文件的方法似乎很好,除了一件事——对“example.txt”或“example.doc”的测试表明,即使将ProcessStartInfo属性WindowsStyle设置为Minimized或Hidden,您仍然可以看到打开文件的应用程序

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

Upd。我与Bentley MicroStation XM edition合作。它有一个可以禁用的启动屏幕

主要问题:当使用命令行参数(要打开的文件名)和各种设置(如WindowsStyle(隐藏))通过Process和ProcessStartInfo启动MicroStation时,UseShellExecute(false),CreateNoWindow(true)应用程序窗口存在且可见。使用win api WinExec进行简单测试,uCmdShow设置为0(隐藏),得到相同的结果


接受在后台模式下启动应用程序的任何解决方案。提前感谢。

尝试设置为true以隐藏窗口。

在我看来,实现您的需求最简单的方法是在另一个窗口上启动新流程。默认进程pesktop为“WinSta0\Default”。就功能而言,您可以创建新的桌面,例如名称为“MyDesktop”,然后在桌面上启动进程

以下代码演示了该技术:

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

如果要隐藏Microstation窗口,必须通过mdl或.net加载项创建Microstation应用程序,您可以在其中执行工作,并加载和运行哪个Microstation。然后您可以在非图形模式下创建microstation。

我已经尝试过了。我不知道这是否重要-应用程序有一个启动屏幕。