[英]WQL request working in console application but not in Windows service
我目前正在研究“監視”解決方案。 這個想法是將目光投向遠程資源,並在可用磁盤空間低於定義的閾值時提醒用戶。
該應用程序是Windows服務。 啟動計時器,每x秒發出一個WQL請求。 該請求包含一些指標,然后我在代碼中進一步使用這些指標(例如,總磁盤大小,可用空間)。
我已經在控制台應用程序中測試了整個過程,並且一切正常。 但是,當我在Win服務中實現它時,WQL請求變得瘋狂並返回一個null元素。
怎么會 ? 我想念什么嗎?
這是我的代碼:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Management;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
namespace DatafactMonitoring
{
public partial class DatafactMonitoring : ServiceBase
{
public DatafactMonitoring()
{
InitializeComponent();
//Creating the event log entry
eventLog1 = new System.Diagnostics.EventLog();
if (!System.Diagnostics.EventLog.SourceExists("ServiceMonitoringDatafact"))
{
System.Diagnostics.EventLog.CreateEventSource("ServiceMonitoringDatafact", "Événements Monitoring Datafact");
}
eventLog1.Source = "ServiceMonitoringDatafact";
eventLog1.Log = "Événements Monitoring Datafact";
}
//Parameters
protected static int threshold = 10;
//Declarations
private static int indexLog = 0;
protected static float diskUsage;
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("Starting the Datafact monitoring service...");
// Timer that triggers OnTimer function every 60 seconds
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 10000; // 10 seconds, to be changed
timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
timer.Start();
}
public ManagementObject GetMetrics()
{
ConnectionOptions options = new ConnectionOptions();
ManagementScope scope = new ManagementScope("\\\\ad", options);
scope.Connect();
SelectQuery query1 = new SelectQuery("Select Name, Size, FreeSpace from Win32_LogicalDisk Where DeviceID = 'P:'");
eventLog1.WriteEntry("Requete...");
ManagementObjectSearcher searcher1 = new ManagementObjectSearcher(scope, query1);
ManagementObjectCollection queryCollection1 = searcher1.Get();
ManagementObject mo = queryCollection1.OfType<ManagementObject>().First();
return mo;
}
public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
ManagementObject datafactMetrics = GetMetrics();
//Metrics parsing
string diskName = datafactMetrics["Name"].ToString();
eventLog1.WriteEntry(diskName);
float diskSize = float.Parse(datafactMetrics["Size"].ToString());
float freeSpace = float.Parse(datafactMetrics["FreeSpace"].ToString());
diskUsage = (freeSpace / diskSize) * 100;
indexLog += 1;
eventLog1.WriteEntry("Log n°" + indexLog + " - Monitoring Datafact server - Space avaiable : " + freeSpace + "Go", EventLogEntryType.Information);
if (diskUsage >= threshold)
{
try
{
//TODO: Change url to SMS sender
System.Diagnostics.Process.Start("http://www.google.com");
eventLog1.WriteEntry("Space avaiable below " + threshold + "% (Disk usage : " + diskUsage + "%) - Mail & SMS sent to the team", EventLogEntryType.Warning);
}
catch (Exception ex)
{
eventLog1.WriteEntry("Error : " + ex.ToString(), EventLogEntryType.Error);
}
}
else
{
eventLog1.WriteEntry("Disk usage : " + diskUsage + "%", EventLogEntryType.Information);
}
}
protected override void OnStop()
{
eventLog1.WriteEntry("Datafact monitoring service stopped.");
}
}
}
WMI無法找到合適的解決方案。 使用Win32API中的GetDiskFreeSpace找到了解決方法。
//Starting with the function's import...
[DllImport("kernel32")]
public static extern int GetDiskFreeSpace(
string lpRootPathName,
out int lpSectorsPerCluster,
out int lpBytesPerSector,
out int lpNumberOfFreeClusters,
out int lpTotalNumberOfClusters
);
.
.
.
//... which I then use in my OnTimer function
public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
string lpRootPathName = @"\\ServerName\SharedFolder";
int lpSectorsPerCluster;
int lpBytesPerSector;
int lpNumberOfFreeClusters;
int lpTotalNumberOfClusters;
int bRC = GetDiskFreeSpace(
lpRootPathName,
out lpSectorsPerCluster,
out lpBytesPerSector,
out lpNumberOfFreeClusters,
out lpTotalNumberOfClusters
);
.
.
.
eventLog1.WriteEntry("Root : "+ lpRootPathName + "Sectors : "+ lpSectorsPerCluster +"Bytes : "+ lpBytesPerSector +"FreeClusters : "+ lpNumberOfFreeClusters + "TotalClusters : "+ lpTotalNumberOfClusters);
如果LogicalDrive P是網絡驅動器,則不能從Windows服務訪問它,至少不能通過默認設置訪問它,因為它具有最低權限:
如果您無法控制網絡驅動器的特權,則必須將Windows服務配置為以特定用戶身份運行:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.