各位好,我用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);
}
}
在他的代码中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);
}
}
具体的什么我到忘了!好像是什么线程Start……
加asp.net群交流83847699
建议你重新考虑需求。要定时启动程序用“计划任务”就可以了,即简单又不需要写代码。采用服务进程来启动用户桌面下的程序牵涉到不少的问题,比如安全问题,又比如你附的代码在Vista下就不见得能用。
如果你对使用CreateProcessAsUser API感到舒服,或许你可以偷一个桌面用户Token来创建一个运行在用户名下的进程。
如果你感到哪怕一点点不太把握,建议你放弃这种方法。