设置c#windows服务描述及允许服务与桌面交互的几种方法
方法一:
在ProjectInstaller.cs重寫 install() ,Uninstall()方法
public override void Install(IDictionary stateServer)
??{
???Microsoft.Win32.RegistryKey system,
????//HKEY_LOCAL_MACHINE\Services\CurrentControlSet
????currentControlSet,
????//...\Services
????services,
????//...\<Service Name>
????service,
????//...\Parameters - this is where you can put service-specific configuration
????config;
???try
???{
????//Let the project installer do its job
????base.Install(stateServer);
????//Open the HKEY_LOCAL_MACHINE\SYSTEM key
????system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
????//Open CurrentControlSet
????currentControlSet = system.OpenSubKey("CurrentControlSet");
????//Go to the services key
????services = currentControlSet.OpenSubKey("Services");
????//Open the key for your service, and allow writing
????service = services.OpenSubKey(this.serviceInstaller1.ServiceName, true);
????//Add your service's description as a REG_SZ value named "Description"
????service.SetValue("Description","PI實(shí)時(shí)數(shù)據(jù)采集:能源--每天8點(diǎn)或20點(diǎn)取一次數(shù)據(jù);汽車衡--每天1點(diǎn)取一次數(shù)據(jù);設(shè)備狀態(tài)--每分鐘取一次數(shù)據(jù)。");
????//(Optional) Add some custom information your service will use...
????//允許服務(wù)與桌面交互
????service.SetValue("Type",0x00000110);
????config = service.CreateSubKey("Parameters");
???}
???catch(Exception e)
???{
????Console.WriteLine("An exception was thrown during service installation:\n" + e.ToString());
???}
??}
??public override void Uninstall(IDictionary stateServer)
??{
???Microsoft.Win32.RegistryKey system,
????currentControlSet,
????services,
????service;
???try
???{
????//Drill down to the service key and open it with write permission
????system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
????currentControlSet = system.OpenSubKey("CurrentControlSet");
????services = currentControlSet.OpenSubKey("Services");
????service = services.OpenSubKey(this.serviceInstaller1.ServiceName, true);
????//Delete any keys you created during installation (or that your service created)
????service.DeleteSubKeyTree("Parameters");
????//...
???}
???catch(Exception e)
???{
????Console.WriteLine("Exception encountered while uninstalling service:\n" + e.ToString());
???}
???finally
???{
????//Let the project installer do its job
????base.Uninstall(stateServer);
???}
??}
?
?
方法二:
此方法經(jīng)測(cè)試,發(fā)現(xiàn)無效,勾是選上了,但程序啟動(dòng)后還是沒有界面出現(xiàn),好像需要電腦重啟才生效
我們寫一個(gè)服務(wù),有時(shí)候要讓服務(wù)啟動(dòng)某個(gè)應(yīng)用程序,就要修改服務(wù)的屬性,勾選允許服務(wù)與桌面交互,
可以用修改注冊(cè)表實(shí)現(xiàn),我們必須在安裝后操作,所以請(qǐng)重寫Installer的OnAfterInstall。
?
protected override void OnAfterInstall(System.Collections.IDictionary savedState) {
RegistryKey rk = Registry.LocalMachine;
string key = @"SYSTEM\CurrentControlSet\Services\" + this.sInstaller.ServiceName;
RegistryKey sub = rk.OpenSubKey(key, true);
int value = (int)sub.GetValue("Type");
if (value < 256) {
sub.SetValue("Type", value | 256);
}
base.OnAfterInstall(savedState);
}
onstart的時(shí)候修改注冊(cè)表???
?? [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\你的服務(wù)名]???
?? "Type"=dword:00000010???
?? key??? value+256???
?? 比如現(xiàn)在00000010是16+256=272???
?? 16進(jìn)制就是00000110?
方法三:
使用System.ServiceProcess.ServiceController
??????????? ConnectionOptions coOptions = new ConnectionOptions();
??????????? coOptions.Impersonation = ImpersonationLevel.Impersonate;
??????????? ManagementScope mgmtScope = new System.Management.ManagementScope(@"root\CIMV2", coOptions);
??????????? mgmtScope.Connect();
??????????? ManagementObject wmiService;
??????????? wmiService = new ManagementObject("Win32_Service.Name='" + ServiceController.ServiceName + "'");
??????????? ManagementBaseObject InParam = wmiService.GetMethodParameters("Change");
??????????? InParam["DesktopInteract"] = true;
??????????? ManagementBaseObject OutParam = wmiService.InvokeMethod("Change", InParam, null);
??????????? ServiceController.Start();
描述:在自己寫的一個(gè)系統(tǒng)服務(wù)程序,需要經(jīng)常用到“允許與桌面進(jìn)行交互”的設(shè)置,網(wǎng)上很多使用修改注冊(cè)表的形式實(shí)現(xiàn),我測(cè)試過,修改注冊(cè)表后,選中的勾是選上了,
但不能彈出應(yīng)用程序;據(jù)說重啟電腦后可以,但我不想重啟,實(shí)際應(yīng)用也不允許重啟,故沒有測(cè)試重啟是否可行的情況。如圖:
?
?
例如:
當(dāng)我需要運(yùn)行服務(wù)程序的時(shí)候,彈出我的應(yīng)用程序,則要在Windows服務(wù)“允許服務(wù)與桌面交互”中打勾,
當(dāng)我不想彈出應(yīng)用程序界面的時(shí)候,則去掉其中的勾選。
實(shí)現(xiàn)方式:
1.在服務(wù)程序安裝時(shí)編程實(shí)現(xiàn),ProjectInstaller.cs
using?System;
using?System.Collections;
using?System.Collections.Generic;
using?System.ComponentModel;
using?System.Configuration.Install;
//using?System.Linq;
using?Microsoft.Win32;?//對(duì)注冊(cè)表操作一定要引用這個(gè)命名空間
namespace?MonitorService
{
????[RunInstaller(true)]
????public?partial?class?ProjectInstaller?:?Installer
????{
????????public?ProjectInstaller()
????????{
????????????InitializeComponent();????????????
????????????//this.Context.Parameters["ServerCode"].ToString();?//?讀取安裝時(shí)輸入的服務(wù)器編號(hào)???????????
????????}
????????private?void?ProjectInstaller_AfterInstall(object?sender,?InstallEventArgs?e)
????????{
????????????//設(shè)置允許服務(wù)與桌面交互
????????????SetServiceTable("MonitorService");????????????
????????}
????????///?<summary>
????????///?設(shè)置允許服務(wù)與桌面交互?,修改了注冊(cè)表,要重啟系統(tǒng)才能生效
????????///?</summary>
????????///?<param?name="ServiceName">服務(wù)程序名稱</param>
????????private?void?SetServiceTable(string?ServiceName)
????????{
????????????RegistryKey?rk?=?Registry.LocalMachine;
????????????string?key?=?@"SYSTEM\CurrentControlSet\Services\"?+?ServiceName;
????????????RegistryKey?sub?=?rk.OpenSubKey(key,?true);
????????????int?value?=?(int)sub.GetValue("Type");
????????????sub.SetValue("Type",?value?|?256);
????????}
????}
}
2.注冊(cè)表修改
onstart的時(shí)候修改注冊(cè)表???
???[HKEY_LOCAL_MACHINE"SYSTEM"CurrentControlSet"Services"你的服務(wù)名]???
???"Type"=dword:00000010???
???key????value+256???
???比如現(xiàn)在00000010是16+256=272???
???16精制就是00000110
?
3.SC程序修改, 允許與桌面進(jìn)行交互
?在dos命令提示符下輸入:
sc config MonitorService type= interact type= own
?回車即可。
可以用批處理的方式實(shí)現(xiàn),把下面代碼保存為 myservice.bat 即可:
?rem 配置服務(wù)程序?yàn)樵试S與桌面進(jìn)行交互方式
@echo "準(zhǔn)備停止服務(wù)程序..."
sc stop MyService
@echo "設(shè)置允許與桌面進(jìn)行交互方式允許"
sc config MyService type= interact type= own
@echo "正在重新啟動(dòng)服務(wù)..."
sc start MyService
@echo "啟動(dòng)服務(wù)成功!"
取消“允許與桌面進(jìn)行交互”
DOS命令提示符下運(yùn)行下面語句即可:
?sc config MyService type= own
經(jīng)測(cè)試:1,2 可以選中“允許與桌面進(jìn)行交互”,但啟動(dòng)服務(wù)的時(shí)候,不能彈出應(yīng)用程序的界面。
?????????? 3 可以完美實(shí)現(xiàn)所有要求。
至此,我遇到的問題也完美的得到解決。
用VS2003部署,讓服務(wù)程序安裝完后立即啟動(dòng)服務(wù)并且選中“允許服務(wù)與桌面交互”及添加服務(wù)描述的方法
?
view plaincopy to clipboardprint?
-----------立即啟動(dòng)--------------???
private?void?serviceInstaller1_AfterInstall(object?sender,?System.Configuration.Install.InstallEventArgs?e)???
{???
ServiceController?myService?=?new?ServiceController("XJOAPigeonholeServer");???
myService.Start();???
myService.Dispose();???
}???
??
??
添加描述:1.1沒有直接方法,2.0里有直接的方法?ServiceInstaller.Description???
//----------------------------添加服務(wù)描述信息?開始?------------???
public?override?void?Install(IDictionary?stateServer)???
{???
Microsoft.Win32.RegistryKey?system,???
//HKEY_LOCAL_MACHINE\Services\CurrentControlSet???
currentControlSet,???
//...\Services???
services,???
//...\?<Service?Name>???
service,???
//...\Parameters?-?this?is?where?you?can?put?service-specific?configuration???
config;???
try???
{???
//Let?the?project?installer?do?its?job???
base.Install(stateServer);???
??
//Open?the?HKEY_LOCAL_MACHINE\SYSTEM?key???
system?=?Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");???
//Open?CurrentControlSet???
currentControlSet?=?system.OpenSubKey("CurrentControlSet");???
//Go?to?the?services?key???
services?=?currentControlSet.OpenSubKey("Services");???
//Open?the?key?for?your?service,?and?allow?writing???
service?=?services.OpenSubKey(this.serviceInstaller1.ServiceName,?true);???
//Add?your?service's?description?as?a?REG_SZ?value?named?"Description"???
service.SetValue("Description","XJOA系統(tǒng)自動(dòng)歸檔服務(wù)(BeijiOffice)");???
//(Optional)?Add?some?custom?information?your?service?will?use...???
//允許服務(wù)與桌面交互???
service.SetValue("Type",0x00000110);???
config?=?service.CreateSubKey("Parameters");???
}???
catch(Exception?e)???
{???
Console.WriteLine("An?exception?was?thrown?during?service?installation:\n"?+?e.ToString());???
}???
}???
??
public?override?void?Uninstall(IDictionary?stateServer)???
{???
Microsoft.Win32.RegistryKey?system,???
currentControlSet,???
services,???
service;???
??
try???
{???
//Drill?down?to?the?service?key?and?open?it?with?write?permission???
system?=?Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");???
currentControlSet?=?system.OpenSubKey("CurrentControlSet");???
services?=?currentControlSet.OpenSubKey("Services");???
service?=?services.OpenSubKey(this.serviceInstaller1.ServiceName,?true);???
//Delete?any?keys?you?created?during?installation?(or?that?your?service?created)???
service.DeleteSubKeyTree("Parameters");???
//...???
}???
catch(Exception?e)???
{???
Console.WriteLine("Exception?encountered?while?uninstalling?service:\n"?+?e.ToString());???
}???
finally???
{???
//Let?the?project?installer?do?its?job???
base.Uninstall(stateServer);???
}???
}???
//----------------------------?結(jié)束?----------------------------???
?
四、這一服務(wù)程序運(yùn)行時(shí)沒有圖形界面?
不錯(cuò),剛才直接運(yùn)行mfc1.exe時(shí)我們看到了圖形界面,但在服務(wù)列表中用右鍵菜單中的“啟動(dòng)”時(shí)卻看不到任何界面。這該怎么辦?
我們還需要在使用CreateService函數(shù)時(shí)(Install()中),加上一個(gè)參數(shù),這樣才能允許程序與桌面交互,也就是可以顯示界面。這個(gè)參數(shù)是SERVICE_INTERACTIVE_PROCESS。
填加后的CreateService:
SC_HANDLE hService = ::CreateService(
hSCM, m_szServiceName, m_szServiceName,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
szFilePath, NULL, NULL, _T("RPCSS"), NULL, NULL);
再次編譯mfc1,卸載服務(wù)后,安裝服務(wù)。我們可以看到,通過服務(wù)列表啟動(dòng)mfc1,原有的對(duì)話框出現(xiàn)了。
如需將服務(wù)設(shè)為自動(dòng)啟動(dòng),則將 SERVICE_DEMAND_START 改為 SERVICE_AUTO_START。
?
總結(jié)
以上是生活随笔為你收集整理的设置c#windows服务描述及允许服务与桌面交互的几种方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入理解position:relativ
- 下一篇: C# 使用反射设置某个对象的属性或读取某