How to get the below high lighted data from windows services using c#?
I have tried the below code to get the path to executable
private string GetInstallationPath(string serviceName)
{
ServiceController[] services = ServiceController.GetServices();
foreach (ServiceController service in services)
{
if (service.ServiceName == serviceName)
{
return service.GetType().Assembly.Location.ToString();
}
}
return string.Empty;
}
But it does not return the exe exutable path.
AFAIK it can't be done via ServiceController API. You can use WMI:
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Service");
var result = searcher.Get()
.OfType<ManagementBaseObject>()
.Select(mo => new
{
Name = mo["Name"] as string,
Path = mo["PathName"] as string
})
.ToArray();
Related
I need to get (not download) the content from 10.000~ manifest files within a project in Azure DevOps, but I don't manage to achieve this. I have found several ways to retrieve the content from one file at a time, but in this context, it is neither an efficient nor sustainable solution. I have managed to retrieve all files of a particular file type by checking if the file path ends with the name of the file, then using the TfvcHttpClientBase.GetItemsBatch method. However, this method does not return the item's content.
Program.cs
using Microsoft.TeamFoundation.SourceControl.WebApi;
AzureRest azureRest = new AzureRest();
var tfvcItems = azureRest.GetTfvcItems();
List<TfvcItemDescriptor> itemDescriptorsList = new List<TfvcItemDescriptor>();
foreach(var item in tfvcItems)
{
//Example manifest file .NET
if (item.Path.EndsWith("packages.config"))
{
var itemDescriptor = new TfvcItemDescriptor()
{
Path = item.Path,
RecursionLevel = VersionControlRecursionType.None,
Version = "",
VersionOption = TfvcVersionOption.None,
VersionType = TfvcVersionType.Latest
};
itemDescriptorsList.Add(itemDescriptor);
}
}
TfvcItemDescriptor[] itemDescriptorsArray = itemDescriptorsList.ToArray();
var itemBatch = azureRest.GetTfvcItemsBatch(itemDescriptorsArray);
foreach(var itemList in itemBatch)
{
foreach(var itemListList in itemList)
{
Console.WriteLine("Content: " + itemListList.Content); //empty/null
Console.WriteLine("ContentMetadata: " + itemListList.ContentMetadata); //not empty/null
}
}
AzureRest.cs
using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
public class AzureRest
{
const string ORG_URL = "https://org/url/url";
const string PROJECT = "Project";
const string PAT = "PersonalAccessToken";
private string GetTokenConfig()
{
return PAT;
}
private string GetProjectNameConfig()
{
return PROJECT;
}
private VssConnection Authenticate()
{
string token = GetTokenConfig();
string projectName = GetProjectNameConfig();
var credentials = new VssBasicCredential(string.Empty, token);
var connection = new VssConnection(new Uri(ORG_URL), credentials);
return connection;
}
public List<TfvcItem> GetTfvcItems()
{
var connection = Authenticate();
using (TfvcHttpClient tfvcClient = connection.GetClient<TfvcHttpClient>())
{
var tfvcItems = tfvcClient.GetItemsAsync(scopePath: "/Path", recursionLevel: VersionControlRecursionType.Full, true).Result;
return tfvcItems;
}
}
public List<List<TfvcItem>> GetTfvcItemsBatch(TfvcItemDescriptor[] itemDescriptors)
{
TfvcItemRequestData requestData = new TfvcItemRequestData()
{
IncludeContentMetadata = true,
IncludeLinks = true,
ItemDescriptors = itemDescriptors
};
var connection = Authenticate();
using (TfvcHttpClient tfvcClient = connection.GetClient<TfvcHttpClient>())
{
var tfvcItems = tfvcClient.GetItemsBatchAsync(requestData).Result;
return tfvcItems;
}
}
}
}
For reference:
I have tested the codes you shared and when debugging at "itemDescriptorsList" and have found that there is no content specified in it, so that's why you cannot get the txt content.
You should first check and add the content property into the "itemDescriptorsList".
Is there a way to get the path of the system files like "wininit.exe" from processId? Below code doesn't work. Process.GetProcesses() also doesn't return anything logical. Please help me.
P.S. I'm trying to code my own task manager designed based on my needs.
private static string GetMainModuleFilepath(int processId)
{
string wmiQueryString = "SELECT ProcessId, ExecutablePath FROM Win32_Process WHERE ProcessId = " + processId;
using (var searcher = new ManagementObjectSearcher(wmiQueryString))
{
using (var results = searcher.Get())
{
ManagementObject mo = results.Cast<ManagementObject>().FirstOrDefault();
if (mo != null)
{
return (string)mo["ExecutablePath"];
}
}
}
return null;
}
You can use the Process.GetProcessById method and pass in the ProcessId.
Then you can use the MainModule.FileName property on the ProcessModule.
My full code can be seen below: (I have done this in a Console App for quicker writing)
static void Main(string[] args)
{
while (true)
{
Console.WriteLine("Enter Process ID:");
var processIdString = Console.ReadLine();
var parsed = int.TryParse(processIdString, out var procId);
if (parsed)
{
var path = GetMainModuleFilepath(procId);
Console.WriteLine($"Found Path: {path}");
}
else
{
Console.WriteLine("Process Id must be a number!");
}
}
}
private static string GetMainModuleFilepath(int processId)
{
var process = Process.GetProcessById(processId);
if (process == null)
{
return string.Empty;
}
return process.MainModule?.FileName;
}
Which results in the following:
Note:
If you are running this code in 32 bit application, you'll not be able to access 64-bit application paths, so you'd have to compile and run you app as 64-bit application (Project Properties → Build → Platform Target → x64).
public static void GetServices() {
var serviceList = new List<string>();
var servicePathList = new List<string>();
ServiceController[] services = ServiceController.GetServices();
foreach (var service in services)
{
serviceList.Add(service.DisplayName);
}
serviceList.Sort();
int serviceCount = 0;
foreach (var service in serviceList)
{
serviceCount++;
Console.WriteLine(serviceCount.ToString() + " - " + service);
}
}
Above code lists the names of the windows services installed. But I also want to get the Physical path of it. Any help?
I want to remove a Printer from a Windows account. This will be used via Citrix.
First I want to retrieve all printers that are installed for the user and then I want to remove a printer.
I am using the following code to do this.
This works on a normal PC. But when I use this via Citrix then it does not work.
Not all Printers are retrieved via this method. Also I cannot remove the Printer.
Does somebody know why?
What can I do to use this via Citrix?
What is different when using this via Citrix?
using System.Collections.Generic;
using System.Linq;
using System.Management;
namespace RemovePrinter
{
public class PrinterManager
{
public List<string> GetInstalledPrinters()
{
var managementScope = new ManagementScope(ManagementPath.DefaultPath);
managementScope.Connect();
var selectQuery = new SelectQuery {QueryString = #"SELECT * FROM Win32_Printer"};
var objectSearcher = new ManagementObjectSearcher(managementScope, selectQuery);
var ojectCollection = objectSearcher.Get();
return (from ManagementBaseObject item in ojectCollection select item["Name"].ToString()).ToList();
}
public bool DeletePrinter(string printerName)
{
var managementScope = new ManagementScope(ManagementPath.DefaultPath);
managementScope.Connect();
var selectQuery = new SelectQuery
{
QueryString = #"SELECT * FROM Win32_Printer WHERE Name = '" +
printerName.Replace("\\", "\\\\") + "'"
};
var ojectSearcher = new ManagementObjectSearcher(managementScope, selectQuery);
var ojectCollection = ojectSearcher.Get();
if (ojectCollection.Count == 0) return false;
foreach (var item in ojectCollection.Cast<ManagementObject>())
{
item.Delete();
return true;
}
return false;
}
}
}
ManagementObjectSearcher is a part of WMI API classes. By default these services are not enabled on Citrix and that is the reason why it does not work.
You need to have the right services installed as well have license to use those.
Check this out "http://support.citrix.com/article/ctx116423"
Does anyone know if there is a way to install a Windows service created in C# without making an installer?
I include a class that does the installation for me. I call the application using command line parameters to install or uninstall the app. I have also in the past included a prompt to the user whether they wanted the service installed when started directly from the command line.
Here's the class I use:
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Microsoft.Win32;
namespace [your namespace here]
{
class IntegratedServiceInstaller
{
public void Install(String ServiceName, String DisplayName, String Description,
System.ServiceProcess.ServiceAccount Account,
System.ServiceProcess.ServiceStartMode StartMode)
{
System.ServiceProcess.ServiceProcessInstaller ProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller();
ProcessInstaller.Account = Account;
System.ServiceProcess.ServiceInstaller SINST = new System.ServiceProcess.ServiceInstaller();
System.Configuration.Install.InstallContext Context = new System.Configuration.Install.InstallContext();
string processPath = Process.GetCurrentProcess().MainModule.FileName;
if (processPath != null && processPath.Length > 0)
{
System.IO.FileInfo fi = new System.IO.FileInfo(processPath);
//Context = new System.Configuration.Install.InstallContext();
//Context.Parameters.Add("assemblyPath", fi.FullName);
//Context.Parameters.Add("startParameters", "Test");
String path = String.Format("/assemblypath={0}", fi.FullName);
String[] cmdline = { path };
Context = new System.Configuration.Install.InstallContext("", cmdline);
}
SINST.Context = Context;
SINST.DisplayName = DisplayName;
SINST.Description = Description;
SINST.ServiceName = ServiceName;
SINST.StartType = StartMode;
SINST.Parent = ProcessInstaller;
// http://bytes.com/forum/thread527221.html
// SINST.ServicesDependedOn = new String[] {};
System.Collections.Specialized.ListDictionary state = new System.Collections.Specialized.ListDictionary();
SINST.Install(state);
// http://www.dotnet247.com/247reference/msgs/43/219565.aspx
using (RegistryKey oKey = Registry.LocalMachine.OpenSubKey(String.Format(#"SYSTEM\CurrentControlSet\Services\{0}", SINST.ServiceName), true))
{
try
{
Object sValue = oKey.GetValue("ImagePath");
oKey.SetValue("ImagePath", sValue);
}
catch (Exception Ex)
{
// System.Console.WriteLine(Ex.Message);
}
}
}
public void Uninstall(String ServiceName)
{
System.ServiceProcess.ServiceInstaller SINST = new System.ServiceProcess.ServiceInstaller();
System.Configuration.Install.InstallContext Context = new System.Configuration.Install.InstallContext("c:\\install.log", null);
SINST.Context = Context;
SINST.ServiceName = ServiceName;
SINST.Uninstall(null);
}
}
}
And here's how I call it:
const string serviceName = "service_name";
const string serviceTitle = "Service Title For Services Control Panel Applet";
const string serviceDescription = "A longer description of what the service does. This is used by the services control panel applet";
// Install
IntegratedServiceInstaller Inst = new IntegratedServiceInstaller();
Inst.Install(serviceName, serviceTitle, serviceDescription,
// System.ServiceProcess.ServiceAccount.LocalService, // this is more secure, but only available in XP and above and WS-2003 and above
System.ServiceProcess.ServiceAccount.LocalSystem, // this is required for WS-2000
System.ServiceProcess.ServiceStartMode.Automatic);
// Uninstall
IntegratedServiceInstaller Inst = new IntegratedServiceInstaller();
Inst.Uninstall(serviceName);
You could try the windows sc command
C:\WINDOWS\system32>sc create
DESCRIPTION:
SC is a command line program used for communicating with the NT Service Controller and services.
You can use installutil.
From the command line:
installutil YourWinService.exe
This utility is installed with the .NET Framework