3

是否有任何命令行或 .NET 方法在后台运行进程隐藏它试图打开的任何窗口?

已经尝试过:

 var process = new Process()
 {
      StartInfo = new ProcessStartInfo()
      {
          CreateNoWindow = true,
          WindowStyle = ProcessWindowStyle.Hidden,
          FileName = TheRealExecutableFileNameHere
      }
 }
 process.Start();

到目前为止没有成功

4

14 回答 14

15

我查看了我的代码,它看起来几乎与您的相同:

ProcessStartInfo psi = new ProcessStartInfo(fileName, arguments)
{
   CreateNoWindow = true,
   WindowStyle = ProcessWindowStyle.Hidden,
   UseShellExecute = false,
   RedirectStandardOutput = true                                               
};

Process process = Process.Start(psi);

唯一显着的区别(除了格式和我们选择的 PSI 构造函数)是我使用 UseShellExecute 和 RedirectStandardOutput,因为我需要读取运行过程的结果。

我发现上面的代码始终在 XP 和 Vista 上运行一个隐藏进程。但是,我也发现,您可能会遇到同样的情况,隐藏的进程可能会启动另一个默认情况下不隐藏的进程。换句话说,如果您启动隐藏的进程 A,而进程 A 反过来又启动进程 B,则您无法控制进程 B 的显示方式。可能会显示您无法控制的窗口。

希望这会有帮助。祝你好运。

于 2009-07-12T14:49:41.897 回答
6

查看Matlab 引擎

如果这种方法符合您的需要,甚至还有一篇关于 CodeProject的有趣文章。

于 2009-07-20T22:49:55.160 回答
5

您是否尝试过使用带有/B开关的 Microsoft DOS启动命令?

微软 DOS 启动命令

例如,

START /B cmd.exe
于 2009-07-24T15:14:09.477 回答
3

没有我不知道实现此目的的纯 .Net 方式。

然后我想到了内核Job Objects,但在UI 限制中没有发现类似的选项。

因此,下一个(尚未验证的)想法是创建比进程挂起,然后创建一个 windows 挂钩,它将监视CallWndProc并过滤掉 WM_SHOW 消息。(然后,当然,恢复进程,在一个单独的线程中等待直到它终止,移除钩子)

于 2009-07-21T07:16:27.840 回答
2

如果您还没有尝试过 .Net 框架中的BackgroundWorker 类,您可能还想尝试一下。它用于在单独的线程上执行长时间运行的进程,以防止它们阻碍 UI。给它看看。

于 2009-07-24T10:21:03.433 回答
2

我意识到这已得到解答,但您可以通过对 FindWindow 和 ShowWindow 的非托管调用来强制隐藏窗口。

[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

psi = new ProcessStartInfo(); // etc..
some_process = Process.Start(psi);
System.Threading.Thread.Sleep(50); // need give the window a chance to be created
IntPtr hWnd = FindWindow(null, "name of the window");
if (hWnd != IntPtr.Zero) ShowWindow(hWnd, 0); // 0 = SW_HIDE

比较笨拙。

于 2009-07-27T16:34:54.503 回答
1

这取决于您是要最小化启动应用程序,但如果需要允许它与用户交互,或者您是否要禁止用户的所有访问,无论发生什么。

如果是后者,您可以在与当前用户不同的桌面环境下运行该进程。

例如,登录对话框和 Vista UAC 使用不同的桌面上下文 - 在一个桌面上下文中发生的任何事情都独立于其他桌面上下文。

不过,可能是解决您的问题的大锤方法。

于 2009-07-12T01:22:50.010 回答
1

我注意到,如果 CreateNoWindow = false 在 Filename 指向 Windows 可执行文件时绝对不执行任何操作,如果您可以访问 winform 应用程序的源代码,那么您可以提供一个命令行参数来控制默认可见性窗体,并在 Winform App 启动代码中执行以下操作:

static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Form1 form1 = new Form1();

        form1.Load += new EventHandler((s,o) =>
            {
              //check if the form should be shown based on command line arg
                if (args.Contains("dontShowWindow"))
                {
                    //hide it
                    form1.ShowInTaskbar = false;
                    form1.Visible = form1.ShowInTaskbar = false;
                }
            }
        );
        Application.Run(form1);
    }

在您调用代码中,您现在可以将“dontShowWindow”指定为进程参数:

 ProcessStartInfo info = new ProcessStartInfo
        {
            CreateNoWindow = false, 
            WindowStyle = ProcessWindowStyle.Hidden,
            UseShellExecute = false, 
            FileName = @"C:\temp\testWinForm.exe",
            Arguments = "dontShowWindow"
        };
        Process.Start(info);

希望这可以帮助

于 2009-07-27T06:13:50.417 回答
1

实现此目的的一种非常简单的方法是创建一个服务帐户并通过 Windows 任务计划程序在服务帐户用户的上下文中运行可执行文件。

您可以使用此 CodeProject 设置计划任务:

http://www.codeproject.com/KB/cs/tsnewlib.aspx

您可以使用 C# 以编程方式在域或本地计算机中非常轻松地创建服务帐户。

http://www.codeproject.com/KB/system/OSUserMangement.aspx http://support.microsoft.com/kb/306273

在另一个用户的上下文中作为计划任务运行的进程不会以交互方式显示,除非该用户已登录;因此使用服务帐户。

于 2009-07-27T16:12:16.983 回答
1
public Form1()
    {
        InitializeComponent();
        Form1 fm = new Form1();
        fm.ShowInTaskbar = false;
        fm.Visible = fm.ShowInTaskbar = false;
    }

效果很好!

于 2015-06-13T00:08:50.940 回答
0

我假设您想要一个在运行时对用户不可见的进程。

您可以尝试以下操作,看看这是否是您想要的。

  1. 创建一个持续运行的简单控制台应用程序(并启动它进行测试)。
  2. 右键单击项目 --> 属性 --> 应用程序选项卡 --> 输出类型 --> 将其从“控制台应用程序”更改为 Windows 应用程序。
  3. 再次启动同一个应用程序(看看这是否是你想要的)。
  4. 通过 Windows 任务管理器关闭应用程序 :)

似乎该进程出现在任务管理器中,但在任务栏中不可见。Alt+TAB 无法启动此过程。

不过,我只是希望您没有制作任何恶意应用程序:)

于 2009-07-12T05:24:14.740 回答
0

我认为您可能想要尝试的是创建一个新的 Windows Station。查看这篇文章,它在 msdn 上对它们进行了一些解释。

http://msdn.microsoft.com/en-us/library/ms681928(VS.85).aspx

于 2009-07-24T21:10:09.593 回答
0

你可以做一个Windows的服务。服务尝试打开的任何窗口都只在会话 0 中运行,这意味着没有用户可以看到它。不过,这适用于所有窗户,所以也许这不是您想要的。

于 2014-07-14T15:35:59.117 回答
0

下面的代码对我有用: 早期用于在桌面屏幕上闪烁记事本进行打印的进程(记事本),但它分散了用户的注意力,因此下面的代码在后台隐藏了记事本进程。

                System.Windows.Forms.PrintDialog printDialog = new PrintDialog();
                System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(Application.StartupPath + "/PrintingDocketFile/PrintCustomerOrder.txt");
                psi.Verb = "PRINT";

                //Process.Start(psi);
                //psi.CreateNoWindow = true;
                psi.UseShellExecute = false;
                //---------------------------------------------------

                psi.CreateNoWindow = false;
                psi.UseShellExecute = true;
                psi.FileName = Application.StartupPath + "/PrintingDocketFile/PrintCustomerOrder.txt";
                psi.WindowStyle = ProcessWindowStyle.Hidden;
                psi.Arguments =  @"%windir%\system32\notepad.exe"; 
                //Process.Start(psi);
                //------------------------------------------------------

                /////////////////////----------------------------------

                printProcess.StartInfo = psi;
                /////psi.CreateNoWindow = true;

                //psi.FileName = "Application.StartupPath" + "/PrintingDocketFile/PrintCustomerOrder.txt";
                //p.StartInfo.FileName = "Notepad.EXE";
                //p.StartInfo.Arguments = "/i /q \"" + installationPackages[i] + "\"";

                printProcess.Start();

                /////////////////////////-------------------------------
                while (!printProcess.HasExited) ;


                if (!printProcess.HasExited)
                {
                    printProcess.Close();
                }
于 2016-09-14T05:24:41.993 回答