请教windows服务中不能显示窗体的问题

RockPlus 2009-04-05 07:14:24
各位好,我用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);
}
}
...全文
384 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
gomoku 2009-04-06
  • 打赏
  • 举报
回复
[Quote=引用楼主 xiaolong85 的帖子:]
...他的作用是定时启动另一个程序...
[/Quote]

建议你重新考虑需求。

要定时启动程序用“计划任务”就可以了,即简单又不需要写代码。

采用服务进程来启动用户桌面下的程序牵涉到不少的问题,比如安全问题,又比如你附的代码在Vista下就不见得能用。
如果你对使用CreateProcessAsUser API感到舒服,或许你可以偷一个桌面用户Token来创建一个运行在用户名下的进程。
如果你感到哪怕一点点不太把握,建议你放弃这种方法。
RockPlus 2009-04-06
  • 打赏
  • 举报
回复
楼上的朋友说的方法,我己经在用了,还是不行啊?问题还是没解决啊?有谁有别的办法吗?
leiziaitudou 2009-04-06
  • 打赏
  • 举报
回复
也许是你再progrm里没有设置。
leiziaitudou 2009-04-06
  • 打赏
  • 举报
回复
也许是你再progrm里没有设置。
RockPlus 2009-04-06
  • 打赏
  • 举报
回复
谢谢各位好.弄好了,原来是我自己粗心了
li_dao_hang_1989 2009-04-05
  • 打赏
  • 举报
回复
可以启动外部的记事本……
具体的什么我到忘了!好像是什么线程Start……
加asp.net群交流83847699
yangqidong 2009-04-05
  • 打赏
  • 举报
回复
窗体不能显示一般是因为没有做下面操作
控制面板-》管理工具-》服务
在你的服务上面右键,属性-》登陆,选中 允许与桌面交互

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧