How to get the name of the Oid (#Snmp)? - c#

Ok, following the advice of Lex Li and I try to get Oid name using an other lib : #SnmpLib
Here the sample :
public static void Main(string[] args)
{
string oid = ".1.3.6.1.4.1";
IObjectRegistry registry = new ReloadableObjectRegistry(#"C:\Users\Fnizz\Desktop\MIBS_BARCO\");
IObjectTree tree = registry.Tree;
var o = tree.Search(ObjectIdentifier.Convert(oid));
string textual = o.AlternativeText;
Console.WriteLine(textual);
if (o.GetRemaining().Count == 0)
{
Console.WriteLine(o.Definition.Type.ToString());
}
Console.ReadKey();
}
But instead of to get the value .iso.org.dod.internet.private.enterprises I get this one : .iso.3.6.1.4.1

You must use #SNMP MIB Compiler (Compiler.exe) to compile your MIB documents first. If there is any dependency missing, it will tell. Only when all dependencies are there, the Compiler can compile your documents without an error.
The compiler generates *.module files in modules folder. Then you need to put these files (*.module) into C:\Users\Fnizz\Desktop\MIBS_BARCO\ folder.
The object registry is able to load them and perform the name resolution correctly. The object registry does not under MIB documents directly, so feeding it with MIB documents will not work.

Related

Can I store an Ini file in a Resources file?

I have a Windows Forms application, .Net Framework 4.6.1, and I want to store some DB connection data in an Ini file.
I then wanted to store it in the Resources file of the project (so I don't have to copy/paste the file in the Debug and Release folder manually, etc.) as a normal file, but when I tried to compile the program and read the Ini data with ini-parser, the following exception showed up: System.ArgumentException: 'Invalid characters in path access'.
I'm using Properties.Resources where I read the Ini file, so I guessed there would be no problem with the path. Could it be a problem with the Ini file itself?
The content of the Ini file is the following:
[Db]
host = (anIP)
port = (aPort)
db = (aDbName)
user = (aDbUser)
password = (aDbUserPwd)
And my method for reading the data:
public static void ParseIniData()
{
var parser = new FileIniDataParser();
IniData data = parser.ReadFile(Properties.Resources.dbc);
mysqlHost = data["Db"]["host"];
mysqlPort = data["Db"]["port"];
mysqlDb = data["Db"]["db"];
mysqlUser = data["Db"]["user"];
mysqlPwd = data["Db"]["password"];
}
I finally could do it using what #KlausGütter told me in the comments (thanks!).
Instead of using the FileIniDataParser you have to use the StreamIniDataParser, and get the Stream with Assembly.GetManifestResourceStream.
I found this a bit tricky, because using this method you need to set the Build Action in the file you want to read to Embedded Resource.
This file is then added as an embedded resource in compile time and you can retrieve its stream.
So my method ended up the following way:
public static void ParseIniData()
{
var parser = new StreamIniDataParser();
dbcReader = new StreamReader(_Assembly.GetManifestResourceStream("NewsEditor.Resources.dbc.ini"));
IniData data = parser.ReadData(dbcReader);
mysqlHost = data["Db"]["host"];
mysqlPort = data["Db"]["port"];
mysqlDb = data["Db"]["db"];
mysqlUser = data["Db"]["user"];
mysqlPwd = data["Db"]["password"];
}
where _Assembly is a private static attribute: private static Assembly _Assembly = Assembly.GetExecutingAssembly();. This gets you the assembly that's being executed when running the code (you could also use this code directly in the method, but I used the Assembly on another method in my class, so I decided to set an attribute... DRY I guess).

Querying TFS 2015 Source Code Repository DateTime Properties with .Net Framework v4.8 and Visual Studio 2019

I am trying to filter for source control files that were either created or modified within a specific time period on particular Team Foundation Server 2015 branches. I am thus far able to access file properties (e.g. url) with the Microsoft.VisualStudio.Services.WebAPI and Microsoft.TeamFoundation.SourceControl.WebApi libraries with a C# .Net Framework 4.8 Console Application using the GitHttpClient class.
The GetItemsAsync() method of this class returns a list of "GitItems" that contain a "path" property that can be passed as an argument into the System.IO class FileInfo to instantiate an object with the properties I need: CreationTime and LastWriteTime. However, the GitItem objects do not include the full file (blob) path that FileInfo (as well as the class File) needs to generate these properties accurately. The path property only includes the file name (e.g. '/.gitignore'). Therefore, in the code below, the variable lastWriteTime and the CreationTime property both return '12/31/1600 7:00:00 PM,' since the path isn't recognized.
static void Main(string[] args)
{
VssCredentials creds = new VssClientCredentials();
creds.Storage = new VssClientCredentialStorage();
VssConnection connection = new VssConnection(new Uri(teamCollection), creds);
// Get a GitHttpClient to talk to the Git endpoints
GitHttpClient gitClient = connection.GetClient<GitHttpClient>();
// Get data about a specific repository
var repositories = gitClient.GetRepositoriesAsync(teamProject).Result;
GitVersionDescriptor descriptor = new GitVersionDescriptor()
{
VersionType = GitVersionType.Branch,
Version = "develop",
VersionOptions = GitVersionOptions.None
};
foreach (var repository in repositories)
{
var branches = gitClient.GetBranchesAsync(repository.Id).Result;
var items = gitClient.GetItemsAsync(repository.Id, recursionLevel: VersionControlRecursionType.Full, versionDescriptor: descriptor, includeContentMetadata: true).Result;
foreach (var item in items)
{
var fullPath = Path.GetFullPath(item.Path);
FileInfo file = new FileInfo(fullPath);
DateTime lastWriteTime = file.LastWriteTime;
}
Console.WriteLine(repository.Name);
}
}
}
}
According to your code, you are using GitHttpClient.GetItemsAsync method.
public Task<GitItemsCollection> GetItemsAsync(
Guid repositoryId,
string path,
GitVersionDescriptor version,
VersionControlRecursionType recursionLevel,
bool includeContentMetadata,
bool includeLatestChange,
Object userState
)
This will return a server side git path. File info class with LastWriteTime properties
Gets or sets the time when the current file or directory was last written to. This should be a local system path.
That's why the path isn't recognized. Which may return a date kind of '12/31/1600 7:00:00 PM,'
Your question is similar to this VSTS API - repository creation date
Don't think it is possible to get the exact date of the moment the
operation create repo was completed. However, logically the birthday
of the repository is usually considered its first commit date.
If that's what you're looking for, you can achieve your goal with a
usual Git command:
git log -1 --reverse --format="format:%ci"
Besides, you could also get a git commit with detail info through Rest API. Also take a look at this blog, which maybe helpful.

SharpShell server .dll NOT signed

I need to develop a Shell Context Menu extension that references some other custom assemblies... I don't want to assign a Strong Name Key to those custom assemblies!
The guide I followed to do this uses the SharpShell project and illustrates how to sign (but does not expalins why) the assembly... and this is my problem: if I sign my final .dll then I have many errors during my project's building phase, because some assemblies my project references are not strongly named ("Referenced assembly does not have a strong name").
In general, googling about the C# Shell Extension implementation, all best tutorials I found sign the final assembly... is it mandatory?
Without signing the assembly ServerManager.exe returns this error: "The file 'XYZ.dll' is not a SharpShell Server".
Finally I've solved my troubles... the SharpShell.dll file obtained through NuGet was a different version of the ServerManager.exe ones.
Uninstalling the SharpShell NuGet package and directly referencing the SharpShell.dll you find inside the ServerManager folder was my solution!
Moreover, I was looking between the article comments... please read this question.
You don't need to use old DLL.
Please use this code directly, without using ServerManager.exe.
private static ServerEntry serverEntry = null;
public static ServerEntry SelectedServerEntry
{
get
{
if (serverEntry == null)
serverEntry = ServerManagerApi.LoadServer("xxx.dll");
return serverEntry;
}
}
public static ServerEntry LoadServer(string path)
{
try
{
// Create a server entry for the server.
var serverEntry = new ServerEntry();
// Set the data.
serverEntry.ServerName = Path.GetFileNameWithoutExtension(path);
serverEntry.ServerPath = path;
// Create an assembly catalog for the assembly and a container from it.
var catalog = new AssemblyCatalog(Path.GetFullPath(path));
var container = new CompositionContainer(catalog);
// Get the exported server.
var server = container.GetExport<ISharpShellServer>().Value;
serverEntry.ServerType = server.ServerType;
serverEntry.ClassId = server.GetType().GUID;
serverEntry.Server = server;
return serverEntry;
}
catch (Exception)
{
// It's almost certainly not a COM server.
MessageBox.Show("The file '" + Path.GetFileName(path) + "' is not a SharpShell Server.", "Warning");
return null;
}
}
Install code:
ServerRegistrationManager.InstallServer(SelectedServerEntry.Server, RegistrationType.OS64Bit, true);
Register code:
ServerRegistrationManager.RegisterServer(SelectedServerEntry.Server, RegistrationType.OS64Bit);

Getting Downloads Folder in C#? [duplicate]

This question already has answers here:
How to programmatically derive Windows Downloads folder "%USERPROFILE%/Downloads"?
(11 answers)
Closed 5 years ago.
I have made some code that will search directories and display files in a listbox.
DirectoryInfo dinfo2 = new DirectoryInfo(#"C:\Users\Hunter\Downloads");
FileInfo[] Files2 = dinfo2.GetFiles("*.sto");
foreach (FileInfo file2 in Files2)
{
listBox1.Items.Add(file2.Name);
}
However, where it says Users\Hunter - well, when people get my software, their name is not Hunter. So how can I automatically detect the user's Downloads folder?
I have tried this:
string path = Environment.SpecialFolder.UserProfile + #"\Downloads";
DirectoryInfo dinfo2 = new DirectoryInfo(Environment.SpecialFolder.UserProfile + path);
FileInfo[] Files2 = dinfo2.GetFiles("*.sto");
foreach (FileInfo file2 in Files2)
{
listBox1.Items.Add(file2.Name);
}
I get an error though.
The Downloads folder is a so called "known" folder, together with Documents, Videos, and others.
Do NOT:
combine hardcoded path segments to retrieve known folder paths
assume known folders are children of the user folder
abuse a long deprecated registry key storing outdated paths
Known folders can be redirected anywhere in their property sheets. I've gone into more detail on this several years ago in my CodeProject article.
Do:
use the WinAPI method SHGetKnownFolderPath as it is the intended and only correct method to retrieve those paths.
You can p/invoke it as follows (I've provided only a few GUIDs which cover the new user folders):
public enum KnownFolder
{
Contacts,
Downloads,
Favorites,
Links,
SavedGames,
SavedSearches
}
public static class KnownFolders
{
private static readonly Dictionary<KnownFolder, Guid> _guids = new()
{
[KnownFolder.Contacts] = new("56784854-C6CB-462B-8169-88E350ACB882"),
[KnownFolder.Downloads] = new("374DE290-123F-4565-9164-39C4925E467B"),
[KnownFolder.Favorites] = new("1777F761-68AD-4D8A-87BD-30B759FA33DD"),
[KnownFolder.Links] = new("BFB9D5E0-C6A9-404C-B2B2-AE6DB6AF4968"),
[KnownFolder.SavedGames] = new("4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4"),
[KnownFolder.SavedSearches] = new("7D1D3A04-DEBB-4115-95CF-2F29DA2920DA")
};
public static string GetPath(KnownFolder knownFolder)
{
return SHGetKnownFolderPath(_guids[knownFolder], 0);
}
[DllImport("shell32",
CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
private static extern string SHGetKnownFolderPath(
[MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags,
nint hToken = 0);
}
Here's an example of retrieving the path of the Downloads folder:
string downloadsPath = KnownFolders.GetPath(KnownFolder.Downloads);
Console.WriteLine($"Downloads folder path: {downloadsPath}");
NuGet Package
If you don't want to p/invoke yourself, have a look at my NuGet package (note that the usage is different, please check its README).
The easiest way is:
Process.Start("shell:Downloads");
If you only need to get the current user's download folder path, you can use this:
I extracted it from #PacMani 's code.
// using Microsoft.Win32;
string GetDownloadFolderPath()
{
return Registry.GetValue(#"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", "{374DE290-123F-4565-9164-39C4925E467B}", String.Empty).ToString();
}
Note:
SHGetKnownFolderPath will return the WRONG value if you changed the download-folder.
The only thing that will ever return you the correct value is reading the shell-folders registry-key 374DE290-123F-4565-9164-39C4925E467B on Windows.
Now you can either use the "!Do not use this registry key", or you can get the wrong value.
You decide which is better for you.
Cross-Platform version:
public static string GetHomePath()
{
// Not in .NET 2.0
// System.Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
return System.Environment.GetEnvironmentVariable("HOME");
return System.Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
}
public static string GetDownloadFolderPath()
{
if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
{
string pathDownload = System.IO.Path.Combine(GetHomePath(), "Downloads");
return pathDownload;
}
return System.Convert.ToString(
Microsoft.Win32.Registry.GetValue(
#"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
,"{374DE290-123F-4565-9164-39C4925E467B}"
,String.Empty
)
);
}
string download = Environment.GetEnvironmentVariable("USERPROFILE")+#"\"+"Downloads";
http://msdn.microsoft.com/en-us//library/system.environment.specialfolder.aspx
There are the variables with the path to some special folders.
typically, your software shall have a configurable variable that stores the user's download folder, which can be assigned by the user, and provide a default value when not set. You can store the value in app config file or the registry.
Then in your code read the value from where it's stored.

How to search for specific value in Registry keys

How can I search for specific value in the registry keys?
For example I want to search for XXX in
HKEY_CLASSES_ROOT\Installer\Products
any code sample in C# will be appreciated,
thanks
In case you don't want to take a dependency on LogParser (as powerful as it is): I would take a look at the Microsoft.Win32.RegistryKey class (MSDN). Use OpenSubKey to open up HKEY_CLASSES_ROOT\Installer\Products, and then call GetSubKeyNames to, well, get the names of the subkeys.
Open up each of those in turn, call GetValue for the value you're interested in (ProductName, I guess) and compare the result to what you're looking for.
Help here...
Microsoft has a great (but not well known) tool for this - called LogParser
It uses a SQL engine to query all kind of text based data like the Registry,
the Filesystem, the eventlog, AD etc...
To be usable from C#, you need to build an Interop Assembly from the
Logparser.dll COM server using following (adjust LogParser.dll path)
command.
tlbimp "C:\Program Files\Log Parser 2.2\LogParser.dll"
/out:Interop.MSUtil.dll
Following is a small sample, that illustrates how to query for the Value
'VisualStudio' in the \HKLM\SOFTWARE\Microsoft tree.
using System;
using System.Runtime.InteropServices;
using LogQuery = Interop.MSUtil.LogQueryClass;
using RegistryInputFormat = Interop.MSUtil.COMRegistryInputContextClass;
using RegRecordSet = Interop.MSUtil.ILogRecordset;
class Program
{
public static void Main()
{
RegRecordSet rs = null;
try
{
LogQuery qry = new LogQuery();
RegistryInputFormat registryFormat = new RegistryInputFormat();
string query = #"SELECT Path from \HKLM\SOFTWARE\Microsoft where
Value='VisualStudio'";
rs = qry.Execute(query, registryFormat);
for(; !rs.atEnd(); rs.moveNext())
Console.WriteLine(rs.getRecord().toNativeString(","));
}
finally
{
rs.close();
}
}
}
This method will search a specified registry key for the first subkey that contains a specified value. If the key is found then the specified value is returned. Searchign is only one level deep. If you require deeper searching then I suggest modifying this code to make use of recursion. Searching is case-sensitive but again you can modify that if required.
private string SearchKey(string keyname, string data, string valueToFind, string returnValue)
{
RegistryKey uninstallKey = Registry.LocalMachine.OpenSubKey(keyname);
var programs = uninstallKey.GetSubKeyNames();
foreach (var program in programs)
{
RegistryKey subkey = uninstallKey.OpenSubKey(program);
if (string.Equals(valueToFind, subkey.GetValue(data, string.Empty).ToString(), StringComparison.CurrentCulture))
{
return subkey.GetValue(returnValue).ToString();
}
}
return string.Empty;
}
Example usage
// This code will find the version of Chrome (32 bit) installed
string version = this.SearchKey("SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall", "DisplayName", "Google Chrome", "DisplayVersion");
#Caltor your solution gave me the answer I was looking for. I welcome improvements or a completely different solution that does not involve the registry. I am working with enterprise applications on Windows 10 with devices joined to Azure AD. I want/need to use Windows Hello for devices and for HoloLens 2 in a UWP app. My problem has been getting the AAD userPrincipal name from Windows 10. After a couple days searching and trying lots of code I searched the Windows Registry for my AAD account in the Current User key and found it. With some research it appears that this information is in a specific key. Because you can be joined to multiple directories there may be more than one entry. I was not trying to solve that issue, that is done with the AAD tenant Id. I just needed the AAD userPrincipal name.
My solution de-dups the return list so that I have a list of unique userPrincipal names. App users may have to select an account, this is tolerable for even HoloLens.
using Microsoft.Win32;
using System.Collections.Generic;
using System.Linq;
namespace WinReg
{
public class WinRegistryUserFind
{
// Windows 10 apparently places Office/Azure AAD in the registry at this location
// each login gets a unique key in the registry that ends with the aadrm.com and the values
// are held in a key named Identities and the value we want is the Email data item.
const string regKeyPath = "SOFTWARE\\Classes\\Local Settings\\Software\\Microsoft\\MSIPC";
const string matchOnEnd = "aadrm.com";
const string matchKey = "Identities";
const string matchData = "Email";
public static List<string> GetAADuserFromRegistry()
{
var usersFound = new List<string>();
RegistryKey regKey = Registry.CurrentUser.OpenSubKey(regKeyPath);
var programs = regKey.GetSubKeyNames();
foreach (var program in programs)
{
RegistryKey subkey = regKey.OpenSubKey(program);
if(subkey.Name.EndsWith(matchOnEnd))
{
var value = (subkey.OpenSubKey(matchKey) != null)? (string)subkey.OpenSubKey(matchKey).GetValue(matchData): string.Empty;
if (string.IsNullOrEmpty(value)) continue;
if((from user in usersFound where user == value select user).FirstOrDefault() == null)
usersFound.Add(value) ;
}
}
return usersFound;
}
}
}

Categories