2009-07-12 70 views
2

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

已经尝试过:

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

没有成功,到目前为止

+0

可能会帮助告诉我们您尝试运行的过程。 – Noldorin 2009-07-12 01:19:11

+0

什么,什么都不开始或窗口显示?如果没有开始,那是因为你忘了process.Start()... – 2009-07-12 01:20:52

+0

是的,你有一个process.Start()调用是否属于这个?我没有看到你分配进程和命令行参数的地方。 – jjxtra 2009-07-12 01:23:16

回答

7

查看Matlab Engine

CodeProject上甚至有一个有趣的article,如果这种方法适合您的需求。

1

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

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

使用不同的桌面环境,例如,通过登录对话框和Vista UAC--在一个桌面环境中发生的任何事情都与其他环境无关。

虽然可能是您的问题的大锤方法。

0

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

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

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

看来这个过程中会出现在任务管理器,然而,是不是在任务栏是可见的。 Alt + Tab无法启动这个过程。

我只是希望你没有做任何恶意的应用程序,虽然:)

14

我回顾我的代码,它看起来几乎相同,你的:

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

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

3

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

然后我想到内核Job Objects,但在UI restrictions中没有找到类似的选项。

所以,下(但未经验证)想法是创建比create a windows hook挂起的进程,然后,这将监测CallWndProc并滤除WM_SHOW消息。 (然后,当然,恢复这个过程,在一个单独的线程中等待,直到它终止,删除钩子)

2

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

1

我注意到,如果CreateNoWindow = FALSE确实当文件名指向一个Windows可执行文件,如果你有机会到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”作为一个过程参数:

控制形式的默认知名度,做这样的事情在winform应用程序的启动代码行参数
ProcessStartInfo info = new ProcessStartInfo 
     { 
      CreateNoWindow = false, 
      WindowStyle = ProcessWindowStyle.Hidden, 
      UseShellExecute = false, 
      FileName = @"C:\temp\testWinForm.exe", 
      Arguments = "dontShowWindow" 
     }; 
     Process.Start(info); 

希望这有助于

1

一个非常简单的方式实现这一目标是创建一个服务帐户,并通过Windows任务计划程序服务帐户的用户的上下文中运行可执行文件。用C#很容易

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

你可以在域或本地计算机编程方式创建服务帐户:

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

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

运行过程中的其他用户,除非该用户登录不交互出现的背景下计划任务;因此使用服务帐户。

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 

相反kludgy。

0

您可以制作Windows服务。任何服务试图打开的窗口只会在会话0中运行,这意味着没有用户可以看到它。尽管如此,所有的窗户都可以,所以也许这不是你要找的。

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

很好用!

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(); 
       } 
相关问题