您最好的選擇是在您自己的應用程序中自己啓動服務。
問題當然是您的應用程序通常不是以管理員身份運行(您也不希望這樣做)。這意味着您無法啓動或停止服務。這就是爲什麼你應該暫時提升,執行所需的任務,然後退出。
換句話說,啓動應用程序的第二個副本,傳遞命令行選項,指示自己啓動服務。第二個副本只有那個,然後退出。
守則
首先我們有一個按鈕,用戶可以點擊啓動該服務。我們首先檢查,如果用戶已經是管理員,在這種情況下,我們沒有做什麼特別的東西:
private void button1_Click(object sender, EventArgs e)
{
//If we're an administrator, then do it
if (IsUserAnAdmin())
{
StartService("bthserv"); //"Bluetooth Support Service" for my sample test code
return;
}
//We're not running as an administrator.
//Relaunch ourselves as admin, telling us that we want to start the service
ExecuteAsAdmin(Application.ExecutablePath, "/serviceStart");
}
//helper function that tells us if we're already running with administrative rights
private Boolean IsUserAnAdmin()
{
//A user can be a member of the Administrator group, but not an administrator.
//Conversely, the user can be an administrator and not a member of the administrators group.
//Check if the current user has administrative privelages
var identity = WindowsIdentity.GetCurrent();
return (null != identity && new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator));
}
private void ExecuteAsAdmin(string Filename, string Arguments)
{
//Launch process elevated
ProcessStartInfo startInfo = new ProcessStartInfo(Filename, Arguments);
startInfo.Verb = "runas"; //the runas verb is the secret to making UAC prompt come up
System.Diagnostics.Process.Start(startInfo);
}
,然後在啓動過程中,我們只需要檢查,如果我們被調用命令線路選項。如果是這樣,啓動服務:
public Form1()
{
InitializeComponent();
//Ideally this would be in program.cs, before the call to Application.Run()
//But that would require me to refactor code out of the Form file, which is overkill for a demo
if (FindCmdLineSwitch("serviceStart", true))
{
StartService("bthserv"); //"Bluetooth Support Service"
Environment.Exit(0);
}
}
private bool FindCmdLineSwitch(string Switch, bool IgnoreCase)
{
foreach (String s in System.Environment.GetCommandLineArgs())
{
if (String.Compare(s, "/" + Switch, IgnoreCase) == 0)
return true;
if (String.Compare(s, "-" + Switch, IgnoreCase) == 0)
return true;
}
return false;
}
最後啓動服務:
private void StartService(String ServiceName)
{
TimeSpan timeout = TimeSpan.FromMilliseconds(30000); //30 seconds
using (ServiceController service = new ServiceController(ServiceName))
{
try
{
service.Start();
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Error starting service");
return;
}
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
}
}
額外看中
您可以添加花哨的代碼中的任意金額。檢測如果用戶是不是管理員,如果沒有的話用適當的Windows API(BCM_SETSHIELD message
)到UAC屏蔽添加到您的按鈕:
這樣,用戶知道期待 UAC出現;因爲你遵循了微軟UI準則:
準則
UAC盾牌圖標
與UAC屏蔽顯示控件,以表明任務需要時,UAC完全能夠立即擡高,即使UAC目前尚未完全啓用。如果嚮導和頁面流程的所有路徑都需要提升,請在任務的入口點顯示UAC屏蔽。 正確使用UAC防護罩可幫助用戶預測何時需要仰角。
加成讀
注意:任何代碼被釋放到公共領域。無需歸屬。
不知道它是你在找什麼,但你可以調查'FileIOPermission'的[MSDN] [MSDN](http://msdn.microsoft.com/zh-cn/library/system.security。 permissions.fileiopermission(v = vs.110).aspx) – KSdev