// POST api/<controller> public HttpResponseMessage Post([FromBody] ReportData reportData) { string method = "ReportController.Post"; SCTracer.Info(method, string.Format("Start. {0}, {1}", reportData.ReporterName, reportData.ReporterHostName)); bool hasHandle = false; try { // 送信されたデータでreport.jsonを更新 string reportPath = HostingEnvironment.MapPath(Common.JSON_FILE_VPATH); Common.CollectDataList data; // ファイル操作のためにミューテックス取る (※ファイルの排他取るだけでもいいのでは?) hasHandle = mutex.WaitOne(); if (File.Exists(reportPath)) { data = JsonConvert.DeserializeObject <Common.CollectDataList>(File.ReadAllText(reportPath)); } else { SCTracer.Info(method, "Not found ." + reportPath); data = new Common.CollectDataList(); } // 古いデータ(ホスト名が一致)があれば更新、なければ新規追加 int oldDataIndex = data.DataList.FindIndex(x => x.Data.ReporterHostName == reportData.ReporterHostName); if (oldDataIndex < 0) { SCTracer.Info(method, "Add new information."); data.DataList.Add(new Common.CollectData() { Data = reportData }); } else { SCTracer.Info(method, "Update old information."); data.DataList[oldDataIndex].UpdateReportData(reportData); } File.WriteAllText(reportPath, JsonConvert.SerializeObject(data)); SCTracer.Info(method, "End."); return(new HttpResponseMessage(HttpStatusCode.OK)); } catch (Exception e) { SCTracer.Error(method, "Unexpected Error Occurred."); SCTracer.Exception(method, e); throw; } finally { if (hasHandle) { mutex.ReleaseMutex(); } } }
static int Main(string[] args) { string method = "Reporter.Main"; SCTracer.Info(method, "Start."); try { // 送信データ1: Reporter実行マシンの情報: configファイルから設定を読み取る string reporterName = System.Configuration.ConfigurationManager.AppSettings["ReporterName"]; string destinationURL = System.Configuration.ConfigurationManager.AppSettings["DestinationURL"]; ReportData reportData = new ReportData(); reportData.ReporterName = reporterName; reportData.ReporterHostName = System.Net.Dns.GetHostName(); // 送信データ2: ログインセッション情報 List <ReportData.LoginSession> sessions; ReportResult result = GetLoginSessions(out sessions); if (result != ReportResult.Success) { SCTracer.Error(method, "GetLoginSessions failed. result = " + result); return((int)result); } reportData.Sessions = sessions; // 送信データ3:インストール済みソフトウェアを取得 string checkSoftwareNames = System.Configuration.ConfigurationManager.AppSettings["CheckSoftwareNames"]; reportData.Softwares = GetInstalledSoftwares(checkSoftwareNames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); // 送信データをJsonにシリアライズし、送信する string json = JsonConvert.SerializeObject(reportData); try { ReportJson(json, destinationURL).Wait(); } catch (Exception e) { SCTracer.Error(method, "Reporting Failed. Need Retry Again. return " + ReportResult.CommunicateServerFailed); SCTracer.Exception(method, e); return((int)ReportResult.CommunicateServerFailed); } } catch (Exception e) { SCTracer.Error(method, "Unexpected Error Occured. return " + ReportResult.UnexpectedError); SCTracer.Exception(method, e); return((int)ReportResult.UnexpectedError); } SCTracer.Info(method, "End."); return((int)ReportResult.Success); }
// GET api/<controller> public HttpResponseMessage Get() { string method = "ReportController.Get"; SCTracer.Info(method, "Start."); bool hasHandle = false; try { string reportPath = HostingEnvironment.MapPath(Common.JSON_FILE_VPATH); string data; hasHandle = mutex.WaitOne(); if (File.Exists(reportPath)) { data = File.ReadAllText(reportPath); } else { data = JsonConvert.SerializeObject(new Common.CollectDataList()); } mutex.ReleaseMutex(); hasHandle = false; HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK); response.Content = new StringContent(data, System.Text.Encoding.UTF8, @"application/json"); SCTracer.Info(method, "End."); return(response); } catch (Exception e) { SCTracer.Error(method, "Unexpected Error Occurred."); SCTracer.Exception(method, e); throw; } finally { if (hasHandle) { mutex.ReleaseMutex(); } } }
async static Task ReportJson(string json, string url) { string method = "Reporter.ReportJson"; SCTracer.Info(method, "Start. url = " + url + " json = " + json); using (HttpClient client = new HttpClient()) { client.Timeout = TimeSpan.FromMilliseconds(10000); var result = await client.PostAsync(url, new StringContent(json, Encoding.UTF8, "application/json")); if (!result.IsSuccessStatusCode) { SCTracer.Error(method, "Report Failed. status = " + (int)result.StatusCode); SCTracer.Error(method, result.Content.ReadAsStringAsync().Result); throw new Exception(string.Format("Failed to report to server.({0})", (int)result.StatusCode)); } } SCTracer.Info(method, "End."); }
public MonitorModel(string filePath) { string method = "MonitorModel.MonitorModel"; bool hasHandle = false; string value = System.Configuration.ConfigurationManager.AppSettings["UnknownStatusThresholdMinutes"]; if (!int.TryParse(value, out unknownStatusThresholdMinutes)) { SCTracer.Error(method, "UnknownStatusThresholdMinutes: failed to parse " + value + " to int."); } value = System.Configuration.ConfigurationManager.AppSettings["MonitorSoftwareNames"]; monitorSoftwareNames = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); for (int i = 0; i < monitorSoftwareNames.Count; i++) { monitorSoftwareNames[i] = monitorSoftwareNames[i].Trim(); } try { hasHandle = mutex.WaitOne(); if (File.Exists(filePath)) { data = JsonConvert.DeserializeObject <Common.CollectDataList>(File.ReadAllText(filePath)); } } catch (Exception e) { SCTracer.Exception(method, e); throw; } finally { if (hasHandle) { mutex.ReleaseMutex(); } } }
static ReportResult GetLoginSessions(out List <ReportData.LoginSession> sessions) { string method = "Reporter.GetLoginSessions"; SCTracer.Info(method, "Start."); sessions = new List <ReportData.LoginSession>(); // 後のbat実行のために、exeのパスに移動しておく string currentDirectory = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)); // query user 実行 string queryResult; string queryError; using (Process proc = new Process()) { proc.StartInfo.FileName = "query_user.bat"; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.RedirectStandardError = true; proc.Start(); queryResult = proc.StandardOutput.ReadToEnd(); queryError = proc.StandardError.ReadToEnd(); proc.WaitForExit(); SCTracer.Info(method, queryResult); if (proc.ExitCode != 1) // batファイルが見つからないなどの異常時、1以外になる { SCTracer.Error(method, "query_result.bat exit with errorcode = " + proc.ExitCode + ". return " + ReportResult.FailQueryUserCmd); return(ReportResult.FailQueryUserCmd); } if (string.IsNullOrWhiteSpace(queryResult)) { SCTracer.Error(method, "query_result.bat failed. StandardOutput is empty. return " + ReportResult.FailQueryUserCmd); SCTracer.Error(method, "StandardError:\n" + queryError); return(ReportResult.FailQueryUserCmd); } } string[] queryResultLines = queryResult.Split('\n'); for (int i = 1; i < queryResultLines.Length; i++) // 1行目はヘッダのためスキップ { string[] userData = queryResultLines[i].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (userData.Length < 2) { // 不正行はスキップ continue; } if (!userData[1].StartsWith("console") && !userData[1].StartsWith("rdp")) { // RDP切断後など、Session名が空の場合対策 continue; } if (userData[0].StartsWith(">")) { // カレントセッションのユーザー名先頭には > が付く userData[0] = userData[0].Substring(1); } SCTracer.Info(method, "add session: " + userData[0] + ", " + userData[1]); sessions.Add(new ReportData.LoginSession() { UserName = userData[0], SessionName = userData[1] }); } // レジストリからCLIENTNAMEを探す foreach (string subkey in Registry.Users.GetSubKeyNames()) { RegistryKey key = Registry.Users.OpenSubKey(subkey + @"\Volatile Environment"); if (key == null || key.SubKeyCount == 0) { continue; } RegistryKey volatileEnvironment = key.OpenSubKey(key.GetSubKeyNames()[0]); // 1個しかないはずなので決め打ち string userName = (string)key.GetValue("USERNAME"); string clientName = (string)volatileEnvironment.GetValue("CLIENTNAME"); string sessionName = (string)volatileEnvironment.GetValue("SESSIONNAME"); ReportData.LoginSession session = sessions.Find(x => x.UserName.ToLower() == userName.ToLower()); if (session != null) { SCTracer.Info(method, "found login session: SID = " + subkey); session.ClientName = clientName; SCTracer.Info(method, string.Format("userName = {0}, clientName = {1}, sessionName = {2}", userName, clientName, sessionName)); } } Directory.SetCurrentDirectory(currentDirectory); SCTracer.Info(method, "End."); return(ReportResult.Success); }