有什么办法可以让进程在后台运行吗?

发布于 2024-07-26 22:49:12 字数 356 浏览 8 评论 0原文

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

已经尝试过:

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

到目前为止还没有成功

There is any command line or .NET method that runs a process in the background hiding any window it tries to open?

Already tried:

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

With no success so far

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

初熏 2024-08-02 22:49:12

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

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 的显示方式。 可能会显示您无法控制的窗口。

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

I reviewed my code and it looks nearly identical to yours:

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

Process process = Process.Start(psi);

The only notable difference (other than formatting and which PSI constructor we chose) is my use of UseShellExecute and RedirectStandardOutput as I needed to read the result of the ran process.

I have found the code above consistently runs a hidden process on XP and Vista. I have also found, however, and you may be experiencing the same, that a hidden process may kick off another process which by default isn't hidden. In other words, if you start hidden Process A and Process A, in turn, kicks off Process B, you have no control as to how Process B will be displayed. Windows which you have no control over may be displayed.

I hope this helps a little. Good luck.

旧故 2024-08-02 22:49:12

查看 Matlab 引擎

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

Check out the Matlab Engine.

There's even an interesting article on CodeProject, if this approach fits your needs.

套路撩心 2024-08-02 22:49:12

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

Microsoft DOS 启动命令

例如,

START /B cmd.exe

Have you tried using the Microsoft DOS start command with the /B switch?

Microsoft DOS start command

For example,

START /B cmd.exe
网名女生简单气质 2024-08-02 22:49:12

没有 我不知道一个纯粹的.Net 方法来实现这一点。

然后我想到了内核 作业对象,但是在 UI 限制 中没有发现类似的选项。

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

There is no I do not know a pure .Net way to achieve this.

Then I thought about kernel Job Objects, but found no similar option in UI restrictions.

So, the next (yet unverified) idea is to create than process suspended, create a windows hook then, which will monitor CallWndProc and filter out WM_SHOW messages. (Then, surely, resume the process, wait in a separate thread till it terminates, remove the hook)

送舟行 2024-08-02 22:49:12

您可能想尝试 BackgroundWorker 类 .Net Framework(如果您还没有)。 它用于在单独的线程上执行长时间运行的进程,以防止它们妨碍 UI。 看看吧。

You may want to try the BackgroundWorker Class in the .Net Framework if you haven't already. It's for executing long running processes on a separate thread to prevent them from impeding the UI. Give it a look.

孤单情人 2024-08-02 22:49:12

我意识到这个问题已经得到解答,但您可以通过对 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

相当笨拙。

I realize this has been answered but you could force a window to hide with unmanaged calls to FindWindow and 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

Rather kludgy.

知你几分 2024-08-02 22:49:12

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

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

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

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

It depends on whether you want to start the application minimized, but allow it to interact with the user if required, or if you want to prohibit all access with the user regardless of what happens.

If the latter, you could run the process under a different desktop context to the current user.

Different Desktop contexts are used, for example, by the Login dialog and by Vista UAC - anything that happens in one desktop context is independent of others.

Might be a sledgehammer approach to your problem though.

油饼 2024-08-02 22:49:12

我注意到,如果当文件名指向 Windows 可执行文件时 CreateNoWindow = false 绝对不执行任何操作,如果您有权访问 winform 应用程序的源代码,那么您可能能够提供一个命令行参数来控制默认可见性表单,并在 Winform 应用程序启动代码中执行类似的操作:

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

希望这有帮助

I noticed that if CreateNoWindow = false does absolutely nothing when the Filename is pointing to a Windows executable, if you have access to the source code of the winform app then you might be able to provide a command line argument which controls the default visibility of the form, and do something like this in the Winform App startup code:

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

In you calling code, you can now specify "dontShowWindow" as a process Argument:

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

Hope this helps

梦在夏天 2024-08-02 22:49:12

实现此目的的一种非常简单的方法是创建一个服务帐户并通过 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

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

One very simply way to achieve this is to create a Service Account and run the executable under the context of the Service Account user via the Windows Task Scheduler.

You could use this CodeProject to setup the scheduled task:

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

You could create the service account programatically in the Domain or local machine very easily with C#.

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

Processes running as scheduled tasks in the context of another user do not appear interactively unless that user is logged in; hence the use of a service account.

独守阴晴ぅ圆缺 2024-08-02 22:49:12
public Form1()
    {
        InitializeComponent();
        Form1 fm = new Form1();
        fm.ShowInTaskbar = false;
        fm.Visible = fm.ShowInTaskbar = false;
    }

效果很好!

public Form1()
    {
        InitializeComponent();
        Form1 fm = new Form1();
        fm.ShowInTaskbar = false;
        fm.Visible = fm.ShowInTaskbar = false;
    }

Works great !

陈年往事 2024-08-02 22:49:12

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

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

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

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

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

I assume you want a process that is not visible to users while running.

You can try the following to see whether this is what you want.

  1. Create a simple console app that keeps running (and launch it to test).
  2. Right click on Project --> Properties --> Application tab --> Output type --> Change it from "Console Application" to Windows Application.
  3. Launch the same app one more time (to see whether this is what you want).
  4. Close the app via Windows Task Manager :)

It seems that the process appears in Task Manager, yet, is not visible in the task bar. Alt+TAB cannot bring this process up.

I just hope that you are not making any malicious app, though :)

爱冒险 2024-08-02 22:49:12

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

http://msdn.microsoft.com/en-我们/库/ms681928(VS.85).aspx

I think what you might want to try is to create a new Windows Station. Check out this article that explains a bit about them on msdn.

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

画骨成沙 2024-08-02 22:49:12

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

You could make a Windows' service. Any window a service tries to open just runs in session 0, which means no user can see it. That goes for all windows though, so perhaps that's not what you're looking for.

咿呀咿呀哟 2024-08-02 22:49:12

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

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

Below code worked for me:
Earlier the process (notepad) used to flash the notepad on desktop screen for printing, but it distract the user , so below code hides the notepad process in background.

                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();
                }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文