各位好,我用c#写一个windows服务,他的作用是定时启动另一个程序,现在的问题是定时启动的程序它不显示窗体,我在网上找到一段解决该问题的方法,但它的代码是启动一个服务自带的窗体,我现在是想启动另外一个程序,如启动记事本,那位高手能帮我改成启动一个程序,而不是一个窗体?下面的代码是摘自csdn上一位叫尤建波的高手博客中的,在这里先向这位高手道个谢。
在他的代码中threadForm=new Thread(new ThreadStart(FormShow));
   threadForm.Start();FormShow启动一个窗体,怎么改成启动一个外部程序?另外有没有其它方法实现在在服务中启动一个外部程序并显示窗体,谢谢了。
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using System.Runtime.InteropServices;
namespace FileWatchService
{
 public class Service1 : System.ServiceProcess.ServiceBase
 {
  /// <summary> 
  /// 必需的设计器变量。
  /// </summary>
  private System.ComponentModel.Container components = null;
  Thread threadForm=null;
  public Service1()
  {
   // 该调用是 Windows.Forms 组件设计器所必需的。
   InitializeComponent();   // TODO: 在 InitComponent 调用后添加任何初始化
  }  #region 组件设计器生成的代码
  /// <summary> 
  /// 设计器支持所需的方法 - 不要使用代码编辑器 
  /// 修改此方法的内容。
  /// </summary>
  private void InitializeComponent()
  {
   // 
   // Service1
   // 
   this.ServiceName = "JadeWatchService";  }
  #endregion
  [STAThread]
  static void Main() 
  {
   System.ServiceProcess.ServiceBase.Run(new Service1());  }
  /// <summary>
  /// 清理所有正在使用的资源。
  /// </summary>
  protected override void Dispose( bool disposing ) 
  {
   if( disposing )
   {
    if (components != null) 
    {
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }  /// <summary>
  /// 设置具体的操作,以便服务可以执行它的工作。
  /// </summary>
  protected override void OnStart(string[] args)
  {
   threadForm=new Thread(new ThreadStart(FormShow));
   threadForm.Start();
  }
 
  /// <summary>
  /// 停止此服务。
  /// </summary>
  protected override void OnStop()
  {
   if(threadForm!=null)
   {
    if(threadForm.IsAlive)
    {
     threadForm.Abort();
     threadForm=null;
    }
   }
  }  void FormShow()
  {
   
   GetDesktopWindow(); 
   IntPtr hwinstaSave = GetProcessWindowStation(); 
   IntPtr dwThreadId = GetCurrentThreadId(); 
   IntPtr hdeskSave = GetThreadDesktop(dwThreadId); 
   IntPtr hwinstaUser = OpenWindowStation("WinSta0", false,33554432); 
   if (hwinstaUser == IntPtr.Zero) 
   { 
    RpcRevertToSelf(); 
    return ;
   } 
   SetProcessWindowStation(hwinstaUser); 
   IntPtr hdeskUser = OpenDesktop("Default", 0, false, 33554432); 
   RpcRevertToSelf(); 
   if (hdeskUser == IntPtr.Zero) 
   { 
    SetProcessWindowStation(hwinstaSave); 
    CloseWindowStation(hwinstaUser); 
    return ; 
   } 
   SetThreadDesktop(hdeskUser); 
 
   IntPtr dwGuiThreadId = dwThreadId; 
   
   Form1 f=new Form1(); //此FORM1可以带notifyIcon,可以显示在托盘里,用户可点击托盘图标进行设置
   System.Windows.Forms.Application.Run(f);
   
   
   dwGuiThreadId = IntPtr.Zero; 
    SetThreadDesktop(hdeskSave); 
   SetProcessWindowStation(hwinstaSave); 
   CloseDesktop(hdeskUser); 
   CloseWindowStation(hwinstaUser); 
  }  [DllImport("user32.dll")]
  static extern int GetDesktopWindow();  [DllImport("user32.dll")]
  static extern IntPtr GetProcessWindowStation();  [DllImport("kernel32.dll")]
  static extern IntPtr GetCurrentThreadId();  [DllImport("user32.dll")]
  static extern IntPtr GetThreadDesktop(IntPtr dwThread);  [DllImport("user32.dll")]
  static extern IntPtr OpenWindowStation(string a,bool b,int c);  [DllImport("user32.dll")]
  static extern IntPtr OpenDesktop(string lpszDesktop, uint dwFlags,
   bool fInherit, uint dwDesiredAccess);  [DllImport("user32.dll")]
  static extern IntPtr CloseDesktop(IntPtr p);  [DllImport("rpcrt4.dll", SetLastError=true)]
  static extern IntPtr RpcImpersonateClient(int i);
  [DllImport("rpcrt4.dll", SetLastError=true)]
  static extern IntPtr RpcRevertToSelf();  [DllImport("user32.dll")]
  static extern IntPtr SetThreadDesktop(IntPtr a);  [DllImport("user32.dll")]
  static extern IntPtr SetProcessWindowStation(IntPtr a);
  [DllImport("user32.dll")]
  static extern IntPtr CloseWindowStation(IntPtr a);
 }
}

解决方案 »

  1.   

    可以启动外部的记事本……
    具体的什么我到忘了!好像是什么线程Start……
    加asp.net群交流83847699
      

  2.   

    http://topic.csdn.net/t/20060210/10/4548700.html
      

  3.   


    建议你重新考虑需求。要定时启动程序用“计划任务”就可以了,即简单又不需要写代码。采用服务进程来启动用户桌面下的程序牵涉到不少的问题,比如安全问题,又比如你附的代码在Vista下就不见得能用。
    如果你对使用CreateProcessAsUser API感到舒服,或许你可以偷一个桌面用户Token来创建一个运行在用户名下的进程。
    如果你感到哪怕一点点不太把握,建议你放弃这种方法。
      

  4.   

    也许是你再progrm里没有设置。
      

  5.   

    也许是你再progrm里没有设置。