How can I get file attributes or version info of driver file in windows via c#.
I'm using this code:
var version = File.GetAttributes(Environment.SystemDirectory + #"\drivers\acpi.sys");
but this code throw exception: Could not find file 'C:\Windows\system32\drivers\acpi.sys'..
Then i'm using this code var dir = Directory.GetFiles(Environment.SystemDirectory + #"\drivers"); in dir variable i have 4 files. If I open this folder via windows explorer i have in folder 300+ files. What am I doing wrong?
You should using >= FrameWork .net 4,
add :
using System.Management;
and add the reference System.Management;
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_PnPSignedDriver");
ManagementObjectCollection moc = searcher.Get();
foreach (var manObj in moc)
{
Console.WriteLine("Device Name:" + manObj["FriendlyName"] + " \r\nDeviceID: " + manObj["DeviceID"] + "\r\nDriverDate: " + manObj["DriverDate"] + "\r\nDriverVersion: " + manObj["DriverVersion"] + "\r\nDriverName:" + manObj["DriverName"] +"\n\r======================================\n\n";);
}
Result (part):
Another way could be reading the version from the file directly. Should work for 64/32bit apps, but I am not sure if you can get to all files.
string directory;
if (Environment.Is64BitOperatingSystem)
directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Sysnative");
else
directory = Environment.GetFolderPath(Environment.SpecialFolder.System);
var info = FileVersionInfo.GetVersionInfo(Path.Combine(directory, "drivers", "acpi.sys"));
You can find more information about Sysnative folders at Folders under C:\Windows\System32\GroupPolicyUsers created with Directory or File System Redirector
Related
I want to iterate through the processes of a machine and list all data files that process is using.. I am not getting all the files that process is using getting only..
c:\windows\system32\wow64win.dll,
c:\windows\system32\wow64cpu.dll,
c:\windows\system32\wow64.dll,
c:\windows\system32\ntdll.dll.
Why other dlls are not listed by WMI here... if process explorer shows all the correct files.
using (ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Process where ProcessId = 25364"))
{
foreach (ManagementObject mo in searcher.Get())
{
Console.WriteLine("Process Name:",
mo.Properties["Name"].Value);
// Get processes having this File open
var b = mo.GetRelated("CIM_DataFile");
if (b.Count > 0)
{
Console.WriteLine("Stop");
}
}
}
I know that you can get the path to a mapped drive (e.g. Find UNC path of a network drive?), but what if the only thing I have is just the path to the shared folder?
For example, let's say I have a friend who is sharing the folder C:\MyDocs\PublicDoc over the network. I can access it under the path \\danas-pc\PublicDoc. Is there any way that I could, being on another computer, determine that \\danas-pc\PublicDoc actually maps to \\danas-pc\c$\MyDocs\PublicDoc?
I ask because I am given a path to a log file that has the path (e.g. \danas-pc\c$\MyDocs\PublicDoc\mylog.log )and I need to check if it matches the same path that is set in another location. The other location has the "short path" (e.g. \\danas-pc\PublicDoc\mylog.log ), and thus, even though the log paths lead to the same location, the program determines that they are different. I wanted to see if there's a way to figure out that they are pointing to the same location.
I can't imagine why you might need this since for the remote instance's full path is \danas-pc\PublicDoc but if you let your imagination thrive I'd suggest something like this:
(1) on the remote computer inside the share folder you can drop a small script that if executed return the full path. You have to search for appropriate coding for windows or linux environment also you need to have execution privilege or rights on it. for example on windows you can have a vbscrit or cscript and a .sh script in linux.
Also please note that seeing it from the remote host, in terms of the remote host the full path is \NAME-OR-IP\Path\to\Folder\or\File etc. For you on the remote connection that is the full path ;)
UPDATE:
as per the comment below, this is a full script that does the following
creates a vbscript with code in it to retrieve the current full path
copies the files into the network desired path
executes the vbscript and reads the result back
deletes the vbscript
Assuming: you have the read/write access on the network folder
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace GetNetworkFullPath
{
class Program
{
static void Main(string[] args)
{
var networkFolder = "\\\\REMOTE-PC-NAME\\SharedFolder";
var nameOfVBScript = "capturepath.vbs";
var vbsOutput = "";
//Get the name of the current directory
var currentDirectory = Directory.GetCurrentDirectory();
Console.WriteLine("Current Dir: " + currentDirectory);
//1. CREATE A VBSCRIPT TO OUTPUT THE PATH WHERE IT IS PRESENT
//Ref. https://stackoverflow.com/questions/2129327/how-to-get-the-fully-qualified-path-for-a-file-in-vbscript
var vbscriptToExecute = "Dim folderName \n" +
"folderName = \"\" \n" +
"Dim fso \n" +
"Set fso = CreateObject(\"Scripting.FileSystemObject\") \n" +
"Dim fullpath \n" +
"fullpath = fso.GetAbsolutePathName(folderName) \n" +
"WScript.Echo fullpath \n";
//Write that script into a file into the current directory
System.IO.File.WriteAllText(#""+ nameOfVBScript + "", vbscriptToExecute);
//2. COPY THE CREATED SCRIPT INTO THE NETWORK PATH
//Ref. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-copy-delete-and-move-files-and-folders
string sourceFile = System.IO.Path.Combine(currentDirectory, nameOfVBScript);
string destFile = System.IO.Path.Combine(networkFolder, nameOfVBScript);
System.IO.File.Copy(sourceFile, destFile, true);
//3. EXECUTE THAT SCRIPT AND READ THE OUTPUT
//Ref. https://stackoverflow.com/questions/27050195/how-do-i-get-the-output-from-my-vbscript-console-using-c
Process scriptProc = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.WorkingDirectory = #"" + networkFolder + "";
info.FileName = "Cscript.exe";
info.Arguments = nameOfVBScript;
info.RedirectStandardError = true;
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
info.WindowStyle = ProcessWindowStyle.Hidden;
scriptProc.StartInfo = info;
scriptProc.Start();
scriptProc.WaitForExit();
bool exit = false;
while (!scriptProc.StandardOutput.EndOfStream)
{
vbsOutput = scriptProc.StandardOutput.ReadLine();
}
Console.WriteLine("vbscript says: " + vbsOutput);
//4. DELETE THE FILE YOU JUST COPIED THERE
System.IO.File.Delete(#"" + networkFolder + "\\" + nameOfVBScript);
}
}
}
Unfortunately when executed remotely the script replies with the Network Path :( so disappointed...really sorry! As long as execution is happening from a user outside the remote system it will reply with the absolute path related to that instance. I think an internal process/user should execute the file and reply back with the answer to the application.
I'll try to think something more tomorrow and maybe reply back if I'm lucky.
I'm using the following code to get my drive serial number. It's working fine with Windows 7, 8, 8.1, and 10 Professional, but I'm getting an error on Windows 10 Home.
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject wmi_HD in searcher.Get())
{
if (wmi_HD["SerialNumber"] == null)
hddId = null;
else
hddId = wmi_HD["SerialNumber"].ToString();
}
I'm getting
System.NullReferenceException : Object reference not set to an instance of an object.
Does anyone know why? What do I need to do to get the serial number in this case?
One more question: if I boot the OS from my pendrive, will this code work? How could I know that the OS is running from a pendrive or disk or any other resource?
When I go to the Device Manager, I see this:
I am adding this as an answer because it can save lot of time while debugging scenarios like System.NullReferenceException in WMI.
Windows+R (run command)
Type wbemtest
And connect to the machine for which you want to fetch information. Fire the query for Win32_DiskDrive and check the output for properties that you can fetch.
This is what I'm using on Windows 10 v1809:
using System;
using System.Management;
namespace GetSerialNo
{
class Program
{
static void Main(string[] args)
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject info in searcher.Get())
{
Console.WriteLine("DeviceID: " + info["DeviceID"].ToString());
Console.WriteLine("Model: " + "Model: " + info["Model"].ToString());
Console.WriteLine("Interface: " + "Interface: " + info["InterfaceType"].ToString());
Console.WriteLine("Serial#: " + "Serial#: " + info["SerialNumber"].ToString());
}
Console.ReadLine();
}
}
}
For details please see http://csharphelper.com/blog/2017/10/get-hard-drive-serial-number-c/
For the associated link Get Hard disk serial Number given by #ADreNaLiNe-DJ I wasn't able to find the required assembly reference for HardDrive hd = new HardDrive();
I am unable to write the response of a WMI query to file but I can print it to console.
I rewrote the query to use different WMI methods to pull the data. I changed back to the below method of ease of use.
I changed from mo["PackageName"] to mo["PackageName"].ToString() in case the response was not a writable string.
I googled - I have yet to find a similar issue and I am starting to think it is something obvious in my code that I am just overlooking.
//store log in same directory as exe is ran from
StreamWriter writeFile = new StreamWriter(filepath);
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT PackageName FROM Win32_Product WHERE PackageName LIKE 'jre%%'");
foreach (ManagementObject mo in mos.Get())
{
if (mo["PackageName"].ToString().Contains("jre"))
{
String packageName = mo["PackageName"].ToString();
writeFile.WriteLine(host + "," + packageName);
}
}
update
see my answer below:
foreach (ManagementObject mo in mos.Get())
{
if (mo["PackageName"].ToString().Contains("jre"))
{
String packageName = mo["PackageName"].ToString();
writeFile.WriteLine(host + "," + packageName);
writeFile.Flush();
}
}
Without knowing what writeFile is or how it's defined, I can only suggest that you use the easier System.IO.File class, like so:
File.AppendAllText(pathToYourFile, host + "," + packageName);
This will automatically open, write to, and close your file for you.
I use the WMI Code Creator for WMI query code creation.
It creates C# code and it is possible to test the queries.
Not a real answer - but might help.
I forgot to flush the writer after write.
String packageName = mo["PackageName"].ToString();
writeFile.WriteLine(host + "," + packageName);
writeFile.Flush();
I need to read a website's folders using WMI and C# in IIS 6.0. I am able to read the Virtual directories and applications using the "IISWebVirtualDirSetting" class. However the physical folders located inside a website cannot be read using this class.
And for my case i need to read sub folders located within a website and later on set permission on them. For my requirement i dont need to work on Virtual Directories/Web Service Applications (which can be easily obtained using the code below..).
I have tried to use IISWebDirectory class but it has been useful.
Here is the code that reads IIS Virtual Directories...
public static ArrayList RetrieveVirtualDirList(String ServerName, String WebsiteName)
{
ConnectionOptions options = SetUpAuthorization();
ManagementScope scope = new ManagementScope(string.Format(#"\\{0}\root\MicrosoftIISV2", ServerName), options);
scope.Connect();
String SiteId = GetSiteIDFromSiteName(ServerName, WebsiteName);
ObjectQuery OQuery = new ObjectQuery(#"SELECT * FROM IISWebVirtualDirSetting");
//ObjectQuery OQuery = new ObjectQuery(#"SELECT * FROM IIsSetting");
ManagementObjectSearcher WebSiteFinder = new ManagementObjectSearcher(scope, OQuery);
ArrayList WebSiteListArray = new ArrayList();
ManagementObjectCollection WebSitesCollection = WebSiteFinder.Get();
String WebSiteName = String.Empty;
foreach (ManagementObject WebSite in WebSitesCollection)
{
WebSiteName = WebSite.Properties["Name"].Value.ToString();
WebsiteName = WebSiteName.Replace("W3SVC/", "");
String extrctedSiteId = WebsiteName.Substring(0, WebsiteName.IndexOf('/'));
String temp = WebsiteName.Substring(0, WebsiteName.IndexOf('/') + 1);
String VirtualDirName = WebsiteName.Substring(temp.Length);
WebsiteName = WebsiteName.Replace(SiteId, "");
if (extrctedSiteId.Equals(SiteId))
//if (true)
{
WebSiteListArray.Add(VirtualDirName );
//WebSiteListArray.Add(WebSiteName);
//+ "|" + WebSite.Properties["Path"].Value.ToString()
}
}
return WebSiteListArray;
}
P.S:
I need to programmatically get the sub folders of an already deployed site(s) using WMI and C# in an ASP. Net Application. I need to find out the sub folders of existing websites in a local or remote IIS 6.0 Web Server. So i require a programmatic solution. Precisely if i am pointed at the right class (like IISWebVirtualDirSetting etc ) that i may use for retrieving the list of physical folders within a website then it will be quite helpful.
I am not working in Powershell and i don't really need a solution that involves powershell or vbscripts.
Any alternative programmatic way of doing the same in C#/ASP.Net will also be highly appreciated.
EDIT:
GetSiteIdFromSiteName
The code may look like this:
public static int GetSiteIdFromSiteName(String ServerName, String WebsiteName)
{
ConnectionOptions options = SetUpAuthorization();
ManagementScope scope = new ManagementScope(string.Format(#"\\{0}\root\MicrosoftIISV2", ServerName), options);
scope.Connect();
ObjectQuery OQuery = new ObjectQuery(#"SELECT * FROM IIsSetting");
ManagementObjectSearcher WebSiteFinder = new ManagementObjectSearcher(scope, OQuery);
ArrayList WebSiteListArray = new ArrayList();
ManagementObjectCollection WebSitesCollection = WebSiteFinder.Get();
String WebSiteName = String.Empty;
foreach (ManagementObject WebSite in WebSitesCollection)
{
WebSiteName = WebSite.Properties["Name"].Value.ToString();
WebsiteName = WebSiteName.Replace("W3SVC/", "");
String extrctedSiteId = WebsiteName.Substring(0, WebsiteName.IndexOf('/'));
break;
}
return extrctedSiteId;
}
and
SetupAuthorization()
Here is the SetupAuthorization function.
public ConnectionOptions SetUpAuthorization()
{
ConnectionOptions options = new ConnectionOptions();
//options.Authentication = AuthenticationLevel.Connect;
//may need to set Packetprivacy enum
options.Authentication = AuthenticationLevel.PacketPrivacy;
options.EnablePrivileges = true;
options.Impersonation = ImpersonationLevel.Impersonate;
return options;
}
Regards
Never mind. i got it myself.
If the directory structure is on local system the System.IO.DirectoryInfo is what is needed. Using remoting the same can be used for remote server as well.
Reference:
http://msdn.microsoft.com/en-us/library/system.io.directoryinfo.aspx
If WMi has to be there then Win32_Directory is the class which should used in query:
"Select * from Win32_directory where drive ='"+ DriveLetter +":' and Path ='%" + MyPath + "%'";
Reference:
http://msdn.microsoft.com/en-us/library/aa394130(VS.85).aspx
Have you looked at the Web Deployment Tool?
http://www.iis.net/expand/WebDeploy
Ability to package ACLs, COM, GAC and registry settings.