在服务中调用外部的窗体程序出现的问题

已经解决!


本人在一个服务中使用:


System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
myProcess.StartInfo.FileName = updatecmd;
myProcess.StartInfo.Arguments = upArg;
myProcess.StartInfo.WorkingDirectory = appDir;
//myProcess.StartInfo.CreateNoWindow = false;
myProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
myProcess.Start();

来显示一个带有对话框的窗体应用程序,用正常的MessageBox.Show("信息","标题",按键,图标);来显示信息,但是怎么也不会出现提示,且占用内存不会放出,通过多次调试得到如下异常信息:

"当应用程序不是以 UserInteractive 模式运行时显示模式对话框或窗体是无效操作。请指定 ServiceNotification 或 DefaultDesktopOnly 样式,以显示服务应用程序发出的通知。"

此信息不是那么容易得到的:)

按异常修正代码为:

MessageBox.Show("完成更新部署","完成",MessageBoxButtons.OK,MessageBoxIcon.Information,

MessageBoxDefaultButton.Button1,

MessageBoxOptions.ServiceNotification);

在此可以正常显示提示信息,但主窗体仍然没有显示出来!!!

如果要显示主窗体的话,服务安装后一定要注意,右键->属性->登录,选择 "本地系统帐户"下面的"允许服务与桌面交互"打勾.

问题解决,看以上显示主窗体的方法可否用代码解决?是否允许交互后MessageBox中就不要设置:MessageBoxOptions.ServiceNotification?

解决方案:
将服务的安装类中(serviceProcessInstaller1)中的Account属性设置为"LocalSystem"(运行此服务的用户类型),
并在服务的OnStart事件中修改注册表: 
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices你的服务名] 
"Type"=dword:00000010 
keyvalue+256 
比如现在00000010是16+256=272 
16进制就是00000110,即可
如:
#region 操作作注册表,设置这个服务可以"允许服务与桌面交互"
public static void setReg_Pos_Servers_Desktop(string serverName)
{
string keyvalue = getReg_Services(serverName);
if (keyvalue == "")
keyvalue = "0";
int kvalue = int.Parse(keyvalue);//返回10进制
if (kvalue < 256)
{
kvalue = kvalue + 256;//这个新值可以设置"允许服务与桌面交互"为真
setReg_Services(serverName, kvalue.ToString());
}

}

public static string getReg_Services(string serverName)
{
string rootKey = @"HKEY_LOCAL_MACHINE";
string subKey = @"SYSTEMCurrentControlSetServices" + serverName;//你的服务名;
string keyname = rootKey + "" + subKey;
return getReg(keyname, "Type");
}

private static void setReg_Services(string serverName,string newvalue)
{
string rootKey = @"HKEY_LOCAL_MACHINE";
string subKey = @"SYSTEMCurrentControlSetServices" + serverName;//你的服务名;
string keyname = rootKey + "" + subKey;
setReg(keyname, "Type", newvalue);//先得查看其值
}
private static string getReg(string keyname, string valuename)
{
//string valuename = "";
object defaultvalue = "";
return Microsoft.Win32.Registry.GetValue(keyname, valuename, defaultvalue).ToString();
}
private static void setReg(string keyName, string valuename, string keyvalue)
{
Microsoft.Win32.Registry.SetValue(keyName, valuename, keyvalue, Microsoft.Win32.RegistryValueKind.DWord);
}

posted on 2011-03-30 12:50  懒懒的呐喊  阅读(902)  评论(0编辑  收藏  举报