Read All Value From Cache - c#

i am using .netcore with Microsoft.Extensions.Caching.Distributed , i have a scenario to get all the keys and also i need to flush all the values.
I have searched many articles no one gives the exact idea to get all values or Flush values. IDistributedCache don't have flush the redis cache.
Can anyone help on this.

For my project ,the follow function return all matched keys:
//using StackExchange.Redis;
/// <summary>
/// 搜索所有与<see cref="keyStr"/>相匹配的缓存的key
/// </summary>
/// <param name="keyStr">搜索词,*表示任意字符</param>
/// <param name="dbIndex">redis中查找db</param>
/// <param name="trimRedisInstanceName">是否在查询前及返回前去除<see cref="Extension.RedisInstanceName"/>前缀</param>
/// <returns>redis中的key列表,<see cref="trimRedisInstanceName"/>参数设置是否包括<see cref="Extension.RedisInstanceName"/></returns>
protected async Task<List<string>> FilterByKey(string keyStr, int dbIndex = 0, bool trimRedisInstanceName = true)
{
//创建连接
var conn = await ConnectionMultiplexer.ConnectAsync(_configuration.GetSection("Cache")["Redis"]);
//获取db
var db = conn.GetDatabase(dbIndex);
var listResult = new List<string>();
//遍历集群内服务器
foreach (var endPoint in conn.GetEndPoints())
{
//获取指定服务器
var server = conn.GetServer(endPoint);
//在指定服务器上使用 keys 或者 scan 命令来遍历key
foreach (var key in server.Keys(dbIndex, Extension.RedisInstanceName + keyStr))
{
if (trimRedisInstanceName)
{
listResult.Add(key.ToString().Replace(Extension.RedisInstanceName, ""));
}
else
{
listResult.Add(key);
}
//获取key对于的值
//var val = db.StringGet(key);
Console.WriteLine($"key: {key}, value:");
}
}
return listResult;
}
In the method,Extension.RedisInstanceName used in
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = config.GetSection("Cache")["Redis"];
options.InstanceName = RedisInstanceName;
});
it used by this:
//刷新缓存
var allCacheCompany = await FilterByKey("xxxx.*");
foreach (var companyKey in allCacheCompany)
{
await _cache.RemoveAsync(companyKey);
}

Related

.NET Core : IFileProvider.GetDirectoryContents recursive not working

I would like to scan a directory ("C:/test") and get all files .pdf recursively
I create a provider like this :
IFileProvider provider = new PhysicalFileProvider("C:/test"); // using config in my code and also tried with "C:/test/"
I placed some pdf in directories and subdirectories
There's a file with this path : C:/test/pdf59.pdf
Another with C:/test/testComplexe/pdf59.pdf
Where I try these lines, they all return "NotFoundDirectoryException" :
provider.getDirectoryContents(#"**")
provider.getDirectoryContents(#"*")
provider.getDirectoryContents(#"*.*")
provider.getDirectoryContents(#"**.*")
provider.getDirectoryContents(#"pdf59.pdf")
provider.getDirectoryContents(#"*.pdf")
Exception this line :
provider.getDirectoryContents(#"testComplexe")
How could i query these recursive directories and files ? Thank you
You can write your own recursive function.
var files = new List<IFileInfo>();
GetFiles("C:/Tests", files);
private void GetFiles(string path, ICollection<IFileInfo> files)
{
IFileProvider provider = new PhysicalFileProvider(path);
var contents = provider.GetDirectoryContents("");
foreach (var content in contents)
{
if (!content.IsDirectory && content.Name.ToLower().EndsWith(".pdf"))
{
files.Add(content);
}
else
{
GetFiles(content.PhysicalPath, files);
}
}
}
For my future self (and others) to copy-paste...
public static class Demo
{
public static void FindPdfs()
{
var provider = new PhysicalFileProvider("c:\\temp");
var pdfs = new List<IFileInfo>();
provider.FindFiles(
directory: "/",
match: file => file.Name.EndsWith(".pdf"),
process: pdfs.Add,
recursive: true);
foreach (var pdf in pdfs)
{
using (var stream = pdf.CreateReadStream())
{
// etc...
}
}
}
}
public static class FileProviderExtensions
{
/// <summary>
/// Searches for files matching some <paramref name="match"/>, and invokes <paramref name="process"/> on them.
/// </summary>
/// <param name="provider">File provider</param>
/// <param name="directory">parent directory for the search, a relative path, leading slashes are ignored,
/// use "" or "/" for starting at the root of <paramref name="provider"/></param>
/// <param name="match">the match predicate, if this returns true the file is passed to <paramref name="process"/></param>
/// <param name="process">this action is invoked on <paramref name="match"/>ing files </param>
/// <param name="recursive">if true directories a</param>
/// <returns>the number of files <paramref name="match"/>ed and <paramref name="process"/>ed</returns>
public static int FindFiles(this IFileProvider provider, string directory, Predicate<IFileInfo> match, Action<IFileInfo> process, bool recursive = false)
{
var dirsToSearch = new Stack<string>();
dirsToSearch.Push(directory);
var count = 0;
while (dirsToSearch.Count > 0)
{
var dir = dirsToSearch.Pop();
foreach (var file in provider.GetDirectoryContents(dir))
{
if (file.IsDirectory)
{
if (!recursive)
continue;
var relPath = Path.Join(dir, file.Name);
dirsToSearch.Push(relPath);
}
else
{
if (!match(file))
continue;
process(file);
count++;
}
}
}
return count;
}
}
This is the simplest version if you just want a list of IFileInfo objects. It uses an extension method. Assumes you already have a IFileProvider, such as one that has been injected.
var files = FileProvider.GetRecursiveFiles("/images").ToArray();
 
using Microsoft.Extensions.FileProviders;
using System.Collections.Generic;
using System.IO;
public static class FileProviderExtensions
{
public static IEnumerable<IFileInfo> GetRecursiveFiles(this IFileProvider fileProvider, string path, bool includeDirectories = true)
{
var directoryContents = fileProvider.GetDirectoryContents(path);
foreach (var file in directoryContents)
{
if (file.IsDirectory)
{
if (includeDirectories)
{
yield return file;
}
// recursively call GetFiles and return each one
// file.Name is the directory name alone (eg. images)
foreach (var f in fileProvider.GetRecursiveFiles(Path.Combine(path, file.Name), includeDirectories))
{
yield return f;
}
}
else
{
// return file
yield return file;
}
}
}
}
To get the content of your root folder ("C:/test/"), use the provider this way :
var contents = provider.getDirectoryContents("")
Then, you have to enumerate results in contents, and do what ever you want with each one.
Documentation : https://learn.microsoft.com/en-us/aspnet/core/fundamentals/file-providers?view=aspnetcore-2.1

Recursively get all children of SAP Gui Session in c#

I am looking to loop through all SAP GuiComponents in c# but am struggling to get all the children of children of a gui session.
This is what I have so far (initially passing session.ActiveWindow.Children to nodes):
private void IterateFindIDByNAme(GuiComponentCollection nodes, string searchstring)
{
if (foundID == "")
{
foreach (GuiComponent node in (GuiComponentCollection)nodes)
{
var comp = node;
if (comp.Name.Contains(searchstring))
foundID = comp.Id;
else
{
try
{
FindIDByNAme((GuiComponentCollection)node, searchstring);
}
catch { }
}
}
}
}
Its able to get all the child elements of session.ActiveWindow but when trying to cast all the children to GuiComponentCollections its falling over.
This would be irrelevant if I could use the FindByName function but for some reason it is not working on the SAP screen i am currently working on (it does work on others, not sure why).
The ID of the field is:
wnd[0]/usr/subBCA_SUB_HEADER:SAPLBANK_BDT_CTRL:0100/subSUBS_DETAIL:SAPLBUSS:0028/ssubGENSUB:SAPLBUSS:4038/subA01P02:SAPLBCA_DYN_CN_CNMANO:0002/ctxtBCA_DYN_CONTRACT_ORGENTRY-ORGUNIT
and the function I am trying is:
((GuiTextField)session.FindByName("BCA_DYN_CONTRACT_ORGENTRY-ORGUNIT", "GuiTextField")).Text = "Test";
The findbyid works fine, but not findbyname?
I know this is 2 questions, but kind of related.
ctxtBCA_DYN_CONTRACT_ORGENTRY-ORGUNIT
The type of the control is a GuiCTextField not GuiTextField:
session.FindByName("BCA_DYN_CONTRACT_ORGENTRY-ORGUNIT", "GuiCTextField")
Sample Code :
public DateTime? GetModificationDate(int employeeID)
{
var session = SapHelper.GetActiveSession();
Console.WriteLine("Recherche de la measure [A5 ou A6] avec un motif 90...");
var window = session.BeginTransaction("PA20", "Afficher données de base personnel");
window.FindByName<GuiCTextField>("RP50G-PERNR").Text = employeeID.ToString();
window.FindByName<GuiCTextField>("RP50G-CHOIC").Text = "Mesures (0000)";
window.FindByName<GuiCTextField>("RP50G-SUBTY").Text = null;
window.FindByName<GuiButton>("btn[20]").Press(); // list view
if (window.Text == "Afficher données de base personnel")
{
Console.WriteLine(">> " + window.FindByName<GuiStatusbar>("sbar").Text);
return null;
}
/* Index Type Title Tooltip
0 GuiTextField Début Date de début
1 GuiTextField Fin Date de fin
2 GuiCTextField Mes. Catégorie de mesure
3 GuiTextField Dés. cat. mesure Dés. cat. mesure
4 GuiCTextField MotMe Motif mesure
5 GuiTextField Dés. motif mesure Dés. motif mesure
6 GuiCTextField Client Statut propre client
7 GuiCTextField Activité Statut d'activité
8 GuiCTextField Paiement Statut paiement part */
var result = window.FindByName<GuiTableControl>("MP000000TC3000").AsEnumerable()
.Select(x => new
{
Start = x.GetText(0),
Category = x.GetCText(2),
CategoryText = x.GetText(3),
Reason = x.GetCText(4),
ReasonText = x.GetText(5),
})
.Where(x => (x.Category == "A5" || x.Category == "AG") && x.Reason == "90")
.FirstOrDefault();
if (result == null)
{
Console.WriteLine(">> aucune measure [A5 ou A6] avec un motif 90 trouvée");
return null;
}
else
{
Console.WriteLine(">> {0}:[{1}]{2} [{3}]{4}",
result.Start, result.Category, result.Category, result.Reason, result.ReasonText);
return DateTime.ParseExact(result.Start, "yyyy/MM/dd", CultureInfo.InvariantCulture);
}
}
Xy.Sap :
#region namespace Xy.Sap
namespace Xy.Sap
{
using System.Reflection;
using sapfewse;
using saprotwr.net;
using COMException = System.Runtime.InteropServices.COMException;
public static class SapHelper
{
public static GuiSession GetActiveSession()
{
var rot = new CSapROTWrapper().GetROTEntry("SAPGUI");
if (rot == null)
throw SapException.NotOpened();
var app = (GuiApplication)rot.GetType().InvokeMember("GetScriptingEngine", BindingFlags.InvokeMethod, null, rot, null);
var connectedSession = app.Connections.Cast<GuiConnection>()
.SelectMany(x => x.Children.Cast<GuiSession>())
.Where(x => !string.IsNullOrEmpty(x.Info.User))
.FirstOrDefault();
if (connectedSession == null)
throw SapException.NotOpened();
return connectedSession;
}
}
public class SapException : Exception
{
public SapException(string message) : base(message) { }
public static SapException NotOpened()
{
return new SapException("Veuillez lancer le SAP et de connecter avec votre identité");
}
}
public static class SapExtensions
{
#region GuiSession
/// <summary>
/// Shortcut for PA20 query
/// </summary>
/// <param name="session"></param>
/// <param name="employeeID"></param>
/// <param name="it">Infotype ID</param>
/// <param name="sty">Subtype ID</param>
/// <param name="asListView"></param>
/// <returns></returns>
public static GuiFrameWindow QueryPA20(this GuiSession session, int employeeID, string it, string sty = null, bool asListView = false)
{
var window = session.BeginTransaction("PA20", "Afficher données de base personnel");
window.FindByName<GuiCTextField>("RP50G-PERNR").Text = employeeID.ToString();
window.FindByName<GuiCTextField>("RP50G-CHOIC").Text = it;
window.FindByName<GuiCTextField>("RP50G-SUBTY").Text = sty;
window.FindByName<GuiButton>(asListView ? "btn[20]" : "btn[7]").Press();
if (window.Text == "Afficher données de base personnel")
{
var exception = new InvalidOperationException(string.Format("Failed to access to personal information of {0}", employeeID));
exception.Data["Employee ID"] = employeeID;
exception.Data["Infotype"] = it;
exception.Data["Subtype"] = sty;
exception.Data["View"] = asListView ? "ListView[Mont]" : "RecordView[Glasses]";
exception.Data["Status Message"] = window.FindByName<GuiStatusbar>("sbar").Text;
throw exception;
}
return window;
}
/// <summary>
/// Shortcut for PA30 query
/// </summary>
/// <param name="session"></param>
/// <param name="employeeID"></param>
/// <param name="it">Infotype ID</param>
/// <param name="sty">Subtype ID</param>
/// <param name="asListView"></param>
/// <returns></returns>
public static GuiFrameWindow QueryPA30(this GuiSession session, int employeeID, string it, string sty = null)
{
var window = session.BeginTransaction("PA30", "Gérer données de base HR");
window.FindByName<GuiCTextField>("RP50G-PERNR").Text = employeeID.ToString();
window.FindByName<GuiCTextField>("RP50G-CHOIC").Text = it;
window.FindByName<GuiCTextField>("RP50G-SUBTY").Text = sty;
window.FindByName<GuiButton>("btn[6]").Press();
if (window.Text == "Gérer données de base HR")
{
var exception = new InvalidOperationException(string.Format("Failed to access to personal information of {0}", employeeID));
exception.Data["Employee ID"] = employeeID;
exception.Data["Infotype"] = it;
exception.Data["Subtype"] = sty;
exception.Data["Status Message"] = window.FindByName<GuiStatusbar>("sbar").Text;
throw exception;
}
return window;
}
/// <summary>
/// Start a new transaction and return the active window
/// </summary>
public static GuiFrameWindow BeginTransaction(this GuiSession session, string transactionID, string expectedTitle)
{
return session.BeginTransaction(transactionID,
x => x.Text == expectedTitle,
x =>
{
var exception = new InvalidOperationException(string.Format("Failed to open transaction : {0}", transactionID));
exception.Data["Transaction ID"] = transactionID;
exception.Data["Expected Title"] = expectedTitle;
exception.Data["Current Title"] = x.Text;
exception.Data["Status Message"] = x.FindByName<GuiStatusbar>("sbar").Text;
return exception;
});
}
public static GuiFrameWindow BeginTransaction(this GuiSession session, string transactionID, Predicate<GuiFrameWindow> validation, Func<GuiFrameWindow, string> errorFormatter)
{
return session.BeginTransactionImpl(transactionID, validation, x => new Exception(errorFormatter(x)));
}
public static GuiFrameWindow BeginTransaction(this GuiSession session, string transactionID, Predicate<GuiFrameWindow> validation, Func<GuiFrameWindow, Exception> errorBuilder)
{
return session.BeginTransactionImpl(transactionID, validation, errorBuilder);
}
private static GuiFrameWindow BeginTransactionImpl(this GuiSession session, string transactionID, Predicate<GuiFrameWindow> validation, Func<GuiFrameWindow, Exception> errorBuilder)
{
// force current transaction to end, preventing any blocking(eg: model dialog)
session.EndTransaction();
session.StartTransaction(transactionID);
var window = session.ActiveWindow;
if (!validation(window))
throw errorBuilder(window);
return window;
}
#endregion
#region GuiFrameWindow
public static TSapControl FindByName<TSapControl>(this GuiFrameWindow window, string name)
{
try
{
return (TSapControl)window.FindByName(name, typeof(TSapControl).Name);
}
catch (COMException e)
{
var writer = new StringWriter();
writer.WriteLine("The control could not be found by name and type.");
writer.WriteLine("Name : " + name);
writer.WriteLine("Type : " + typeof(TSapControl).Name);
throw new Exception(writer.ToString(), e);
}
}
#endregion
#region GuiTableControl
/// <summary>Note: Do not iterate through this ienumerable more than once</summary>
public static IEnumerable<GuiTableRow> AsEnumerable(this GuiTableControl table)
{
var container = table.Parent as dynamic;
string name = table.Name, type = table.Type;
int rowCount = table.VerticalScrollbar.Maximum;
Func<GuiTableControl> getTable = () => container.FindByName(name, type) as GuiTableControl;
for (int i = 0; i <= rowCount; i++)
{
getTable().VerticalScrollbar.Position = i;
yield return getTable().Rows.Item(0) as GuiTableRow;
}
}
public static TSapControl GetCell<TSapControl>(this GuiTableRow row, int column)
{
return (TSapControl)row.Item(column);
}
public static string GetCText(this GuiTableRow row, int column)
{
return row.GetCell<GuiCTextField>(column).Text;
}
public static string GetText(this GuiTableRow row, int column)
{
return row.GetCell<GuiTextField>(column).Text;
}
#endregion
}
}
#endregion
EDIT: The link to the LINQPad script mentioned in comment below no longer works. I have re-uploaded it here.
This script helps you to browse SAP GUI:
List control type, name, id, content
List properties and methods
Highlight control
Generate selector : .FindByName<GuiTableControl>("MP000000TC3000")
In case anyone wants to know how to get child elements of any gui component (this will simply write all ids to the console):
private void LoopAllElements(GuiComponentCollection nodes)
{
foreach (GuiComponent node in (GuiComponentCollection)nodes)
{
Console.WriteLine(node.Id);
if (node.ContainerType)
{
var children = ((node as dynamic).Children as GuiComponentCollection);
LoopAllElements(children);
}
}
}
This will loop through all child elements of any GUIComponentCollection you pass to it such as
LoopAllElements(session.Children)
There is probably a better linq way of doing this but this should get you started.
Please also check out this gist created by Xiaoy312 https://gist.github.com/Xiaoy312/a1424bd34acae92554105b27b0c80971
this has a lot of useful functions to debug your current sap session which i have found extremely useful.
You can either view the code as it has a number of functions you can use such as improved findbyid and findbyname or run it in linqpad https://www.linqpad.net/Download.aspx which will allow you to interogate the current SAP session.
If I understood correctly we have to manually start SAP Logon to make line below working:
var rot = new CSapROTWrapper().GetROTEntry("SAPGUI");
Am I right?
If so maybe someone can explain me why at the line:
var app = (GuiApplication)rot.GetType().InvokeMember("GetScriptingEngine", BindingFlags.InvokeMethod, null, rot, null);
I am getting exception:
An exception of type 'System.Runtime.InteropServices.COMException'
occurred in System.Dynamic.dll but was not handled in user code
Additional information: Error loading type library/DLL. (Exception
from HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY))
I've already tried to change target platform from Any CPU to x86 and x64 and didn't have success in resolving this problem.
But when I run SAPGUI using following script:
var SapGuiApp = new GuiApplication();
string development = "Development ERP System";
var connection = SapGuiApp.OpenConnection(development);
instead of running SAP Logon manually described above problem is not reproducing.
But in this case I have other problem: GUI is different and for second option GUI looks corrupted - some of GUI controls are not displayed (please see screenshot). Please give me advice what can be wrong? Thank you in advance
UPDATE: I found solution that solves issue described below. You have to use object instead of var while you are trying to get session connection:
CSapROTWrapper sapROTWrapper = new CSapROTWrapper();
object rot = sapROTWrapper.GetROTEntry("SAPGUI");
object engine = rot.GetType().InvokeMember("GetScriptingEngine", System.Reflection.BindingFlags.InvokeMethod, null, rot, null);
GuiConnection connection = (engine as GuiApplication).OpenConnection(connectionName);
GuiSession session = connection.Children.ElementAt(0) as GuiSession;

Sugar CRM 6.5.14 - Calling REST API with C#

Amazingly low on doco when it comes to rest api. Can anyone give me a working example of Sugar CRM REST calls using C#?
I was trying out SugarSharp but it's just listing the services and not coming up with Data(null)
Appreciate this is an old question but for anyone else that comes across it, took me a while to get it all working with creating and updating relationships being the toughest to fathom.
Here is part of a wrapper class I wrote around the v4_1 rest api, hope it helps:-
public void Login()
{
object loginData = new
{
user_auth = new
{
user_name = Username,
password = CalculateMD5Hash(Password)
}
};
string jsonData = CreateFormattedPostRequest("login", loginData);
var request = GetRestRequest(jsonData, "POST");
var loginResponse = GetRestResponseByType<LoginResponse>(request);
if (string.IsNullOrEmpty(loginResponse.id))
{
throw new SugarException(string.Concat("Authorisation Failed for user: {0}, did not retrieve access token", Username));
}
SessionID = loginResponse.id;
}
Format the request:-
private string CreateFormattedPostRequest(string method, object data)
{
StringBuilder buffer = new StringBuilder();
using (StringWriter writer = new StringWriter(buffer))
{
serializer.Serialize(data, buffer);
}
string result = "method=" + method;
result += "&input_type=JSON&response_type=JSON&rest_data=" + buffer.ToString();
return result;
}
And finally get the response:-
private object GetRestResponseAsObject(HttpWebRequest request)
{
using (var response = (HttpWebResponse)request.GetResponse())
{
using (Stream input = response.GetResponseStream())
{
StreamReader reader = new StreamReader(input);
string buffer = reader.ReadToEnd();
var responseObj = serializer.DeserializeObject(buffer);
return responseObj;
}
}
}
And here is an example call to the set_entry method:-
/// <summary>
/// Creates or Updates a single bean, for update ensure that the name_value_list contains the ID of the record
/// name_value_lists - Dictionary where the keys of the are the SugarBean attributes (columns), the values of the array are the values the attributes should have.
/// </summary>
/// <param name="module">Module to update i.e Account</param>
/// <param name="record">key value pair object of record, include ID for update</param>
/// <returns>Returns the updated or created Bean ID</returns>
public string CreateUpdateBean(string module, object record)
{
var parameters = new Dictionary<string, object>();
parameters.Add("session", SessionID);
parameters.Add("module_name", module);
parameters.Add("name_value_list", record);
parameters.Add("track_view", false);
string jsonData = CreateFormattedPostRequest("set_entry", parameters);
var request = GetRestRequest(jsonData, "POST");
var result = GetRestResponseByType<object>(request);
return result.ToString();
}
For calling rest api SugarCRM/SuiteCRM with c#, you can use SugarRestSharp
Example for create Account:
var client = new SugarRestClient(TestAccount.Url, TestAccount.Username, TestAccount.Password);
Account insertAccount = AccountsModule.GetTestAccount();
// -------------------Create Account-------------------
SugarRestResponse response = AccountsModule.CreateAccount(client, insertAccount);
Assert.NotNull(response);
Assert.Equal(response.StatusCode, HttpStatusCode.OK);
string insertId = (response.Data == null) ? string.Empty : response.Data.ToString();
Assert.NotNull(insertId);
Assert.NotEmpty(insertId);
// -------------------End Create Account-------------------

The remote host closed the connection. The error code is 0x800703E3

I am currently trying to generate a CSV using nhibernate. This error does not occur on my development enviroment but it does on the live site that it's being used on. I have tried fiddling with time out's but this does not seem to have any effect as it's timing out way before it should. The timing is completely random, sometimes it'll be 3 seconds before it times out the next it will be 10 seconds. There doesn't seem to be any real consistancy in the timing.
Stack Trace:
System.Web.HttpException: The remote host closed the connection. The error code is 0x800703E3.
at System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32 result, Boolean throwOnDisconnect)
at System.Web.Hosting.IIS7WorkerRequest.ExplicitFlush()
at System.Web.HttpResponse.Flush(Boolean finalFlush)
at Reports.CustomCSVWriter.WritetoHttpStream(String filename, Boolean header)
The code is as follows:
public class ProductSpreadSheetDownload : CustomCSVWriter
{
protected override string[] GetCollection()
{
Page.Server.ScriptTimeout = 300;
IList<Product> products = new List<Product>();
IStockScheme stockScheme = Fabric.ObjectProvider.Get<IStockScheme>();
ICriteria criteria = CoreHttpModule.Session.CreateCriteria(typeof(Product))
.Add(NHibernate.Expression.Expression.IsNotNull(Product.STOCK_CODE))
.Add(NHibernate.Expression.Expression.Eq(Product.IS_VISIBLE_ON_WEBSITE, true))
.Add(NHibernate.Expression.Expression.Eq(Product.STOCK_TYPE, StockType.StockItem))
.Add(NHibernate.Expression.Expression.Not(NHibernate.Expression.Expression.Like(Product.NAME, "%*%")));
AddCustomCriteria(criteria);
products = criteria.List<Product>();
products = Product.RemoveOrphanedAndUnrooted((List<Product>)products);
Product[] productArray = new Product[products.Count];
products.CopyTo(productArray, 0);
double?[] levels = stockScheme.GetStock(productArray, false);
List<string> productStringList = new List<string>();
IProductMapper mapper = Fabric.ObjectProvider.Get<IProductMapper>();
var rootUrl = Fabric.SettingsProvider.ReadSetting<string>("RootUrl", string.Empty);
string showOutOfStock = Page.Request.QueryString["ShowOutOfStock"];
int minStockLevel = int.MinValue;
if (showOutOfStock == "False")
minStockLevel = 0;
for (int i = 0; i < productArray.Length; i++)
{
if (levels[i] > minStockLevel && levels[i] != null && productArray[i].Parent != null && productArray[i].Parent.IsVisibleOnWebsite)
{
StringBuilder productStringBuilder = new StringBuilder();
productStringBuilder.AppendFormat("{0}, ", CleanString(productArray[i].Name));
productStringBuilder.AppendFormat("{0}, ", CleanString(productArray[i].StockCode));
productStringBuilder.AppendFormat("{0}, ", levels[i]);
productStringBuilder.AppendFormat("{0}, ", mapper.GetUrl(productArray[i]) );
productStringBuilder.AppendFormat("{0}, ", CleanString(productArray[i].Category));
productStringBuilder.AppendFormat("{0}, ", CleanString(productArray[i].SubCategory));
productStringBuilder.AppendFormat("{0}, ", CleanString(mapper.GetText(productArray[i], "Description")));
productStringBuilder.AppendFormat("{0}, ", mapper.GetImageUrl(productArray[i], "Main"));
AddCustomFields(productStringBuilder, mapper);
productStringList.Add(productStringBuilder.ToString().Trim().TrimEnd(','));
}
}
string[] productstrings = new string[productStringList.Count];
productStringList.CopyTo(productstrings, 0);
return productstrings;
}
/// <summary>
/// Override this method to add custom criteria to the feed
/// </summary>
/// <example>
/// criteria.Add(NHibernate.Expression.Expression.Eq(Product.IS_VISIBLE_ON_WEBSITE, true));
/// </example>
protected virtual void AddCustomCriteria(ICriteria criteria) {}
/// <summary>
/// Override this method to add custom fields to the CSV output
/// </summary>
/// <example>
/// productStringBuilder.AppendFormat("{0}, ", mapper.GetImageUrl(productArray[i], "Main"));
/// </example>
protected virtual void AddCustomFields(StringBuilder productStringBuilder, IProductMapper mapper) { }
protected override string Headers()
{
string headers = "Name, Stockcode, Stock_Level, URL, Category, SubCategory, Description, Main Image URL";
return headers;
}
/// <summary>
/// Removes characters that are not safe in a CSV file.
/// </summary>
protected static string CleanString(string stringToClean)
{
return string.IsNullOrEmpty(stringToClean) ? string.Empty : stringToClean.Replace("\n", " ").Replace(',', ' ');
}
}
}

How can you change Network settings (IP Address, DNS, WINS, Host Name) with code in C#

I am developing a wizard for a machine that is to be used as a backup of other machines. When it replaces an existing machine, it needs to set its IP address, DNS, WINS, and host name to match the machine being replaced.
Is there a library in .net (C#) which allows me to do this programatically?
There are multiple NICs, each which need to be set individually.
EDIT
Thank you TimothyP for your example. It got me moving on the right track and the quick reply was awesome.
Thanks balexandre. Your code is perfect. I was in a rush and had already adapted the example TimothyP linked to, but I would have loved to have had your code sooner.
I've also developed a routine using similar techniques for changing the computer name. I'll post it in the future so subscribe to this questions RSS feed if you want to be informed of the update. I may get it up later today or on Monday after a bit of cleanup.
Just made this in a few minutes:
using System;
using System.Management;
namespace WindowsFormsApplication_CS
{
class NetworkManagement
{
public void setIP(string ip_address, string subnet_mask)
{
ManagementClass objMC =
new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if ((bool)objMO["IPEnabled"])
{
ManagementBaseObject setIP;
ManagementBaseObject newIP =
objMO.GetMethodParameters("EnableStatic");
newIP["IPAddress"] = new string[] { ip_address };
newIP["SubnetMask"] = new string[] { subnet_mask };
setIP = objMO.InvokeMethod("EnableStatic", newIP, null);
}
}
}
public void setGateway(string gateway)
{
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if ((bool)objMO["IPEnabled"])
{
ManagementBaseObject setGateway;
ManagementBaseObject newGateway =
objMO.GetMethodParameters("SetGateways");
newGateway["DefaultIPGateway"] = new string[] { gateway };
newGateway["GatewayCostMetric"] = new int[] { 1 };
setGateway = objMO.InvokeMethod("SetGateways", newGateway, null);
}
}
}
public void setDNS(string NIC, string DNS)
{
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if ((bool)objMO["IPEnabled"])
{
// if you are using the System.Net.NetworkInformation.NetworkInterface
// you'll need to change this line to
// if (objMO["Caption"].ToString().Contains(NIC))
// and pass in the Description property instead of the name
if (objMO["Caption"].Equals(NIC))
{
ManagementBaseObject newDNS =
objMO.GetMethodParameters("SetDNSServerSearchOrder");
newDNS["DNSServerSearchOrder"] = DNS.Split(',');
ManagementBaseObject setDNS =
objMO.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
}
}
}
}
public void setWINS(string NIC, string priWINS, string secWINS)
{
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if ((bool)objMO["IPEnabled"])
{
if (objMO["Caption"].Equals(NIC))
{
ManagementBaseObject setWINS;
ManagementBaseObject wins =
objMO.GetMethodParameters("SetWINSServer");
wins.SetPropertyValue("WINSPrimaryServer", priWINS);
wins.SetPropertyValue("WINSSecondaryServer", secWINS);
setWINS = objMO.InvokeMethod("SetWINSServer", wins, null);
}
}
}
}
}
}
Refactored the code from balexandre a little so objects gets disposed and the new language features of C# 3.5+ are used (Linq, var, etc). Also renamed the variables to more meaningful names. I also merged some of the functions to be able to do more configuration with less WMI interaction. I removed the WINS code as I don't need to configure WINS anymore. Feel free to add the WINS code if you need it.
For the case anybody likes to use the refactored/modernized code I put it back into the community here.
/// <summary>
/// Helper class to set networking configuration like IP address, DNS servers, etc.
/// </summary>
public class NetworkConfigurator
{
/// <summary>
/// Set's a new IP Address and it's Submask of the local machine
/// </summary>
/// <param name="ipAddress">The IP Address</param>
/// <param name="subnetMask">The Submask IP Address</param>
/// <param name="gateway">The gateway.</param>
/// <remarks>Requires a reference to the System.Management namespace</remarks>
public void SetIP(string ipAddress, string subnetMask, string gateway)
{
using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration"))
{
using (var networkConfigs = networkConfigMng.GetInstances())
{
foreach (var managementObject in networkConfigs.Cast<ManagementObject>().Where(managementObject => (bool)managementObject["IPEnabled"]))
{
using (var newIP = managementObject.GetMethodParameters("EnableStatic"))
{
// Set new IP address and subnet if needed
if ((!String.IsNullOrEmpty(ipAddress)) || (!String.IsNullOrEmpty(subnetMask)))
{
if (!String.IsNullOrEmpty(ipAddress))
{
newIP["IPAddress"] = new[] { ipAddress };
}
if (!String.IsNullOrEmpty(subnetMask))
{
newIP["SubnetMask"] = new[] { subnetMask };
}
managementObject.InvokeMethod("EnableStatic", newIP, null);
}
// Set mew gateway if needed
if (!String.IsNullOrEmpty(gateway))
{
using (var newGateway = managementObject.GetMethodParameters("SetGateways"))
{
newGateway["DefaultIPGateway"] = new[] { gateway };
newGateway["GatewayCostMetric"] = new[] { 1 };
managementObject.InvokeMethod("SetGateways", newGateway, null);
}
}
}
}
}
}
}
/// <summary>
/// Set's the DNS Server of the local machine
/// </summary>
/// <param name="nic">NIC address</param>
/// <param name="dnsServers">Comma seperated list of DNS server addresses</param>
/// <remarks>Requires a reference to the System.Management namespace</remarks>
public void SetNameservers(string nic, string dnsServers)
{
using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration"))
{
using (var networkConfigs = networkConfigMng.GetInstances())
{
foreach (var managementObject in networkConfigs.Cast<ManagementObject>().Where(objMO => (bool)objMO["IPEnabled"] && objMO["Caption"].Equals(nic)))
{
using (var newDNS = managementObject.GetMethodParameters("SetDNSServerSearchOrder"))
{
newDNS["DNSServerSearchOrder"] = dnsServers.Split(',');
managementObject.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
}
}
}
}
}
}
I like the WMILinq solution. While not exactly the solution to your problem, find below a taste of it :
using (WmiContext context = new WmiContext(#"\\.")) {
context.ManagementScope.Options.Impersonation = ImpersonationLevel.Impersonate;
context.Log = Console.Out;
var dnss = from nic in context.Source<Win32_NetworkAdapterConfiguration>()
where nic.IPEnabled
select nic;
var ips = from s in dnss.SelectMany(dns => dns.DNSServerSearchOrder)
select IPAddress.Parse(s);
}
http://www.codeplex.com/linq2wmi
A far more clear solution is to use the command netsh to change the IP (or setting it back to DHCP)
netsh interface ip set address "Local Area Connection" static 192.168.0.10 255.255.255.0
Where "Local Area Connection" is the name of the network adapter. You could find it in the windows Network Connections, sometimes it is simply named "Ethernet".
Here are two methods to set the IP and also to set the IP back to DHCP "Obtain an IP address automatically"
public bool SetIP(string networkInterfaceName, string ipAddress, string subnetMask, string gateway = null)
{
var networkInterface = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(nw => nw.Name == networkInterfaceName);
var ipProperties = networkInterface.GetIPProperties();
var ipInfo = ipProperties.UnicastAddresses.FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork);
var currentIPaddress = ipInfo.Address.ToString();
var currentSubnetMask = ipInfo.IPv4Mask.ToString();
var isDHCPenabled = ipProperties.GetIPv4Properties().IsDhcpEnabled;
if (!isDHCPenabled && currentIPaddress == ipAddress && currentSubnetMask == subnetMask)
return true; // no change necessary
var process = new Process
{
StartInfo = new ProcessStartInfo("netsh", $"interface ip set address \"{networkInterfaceName}\" static {ipAddress} {subnetMask}" + (string.IsNullOrWhiteSpace(gateway) ? "" : $"{gateway} 1")) { Verb = "runas" }
};
process.Start();
var successful = process.ExitCode == 0;
process.Dispose();
return successful;
}
public bool SetDHCP(string networkInterfaceName)
{
var networkInterface = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(nw => nw.Name == networkInterfaceName);
var ipProperties = networkInterface.GetIPProperties();
var isDHCPenabled = ipProperties.GetIPv4Properties().IsDhcpEnabled;
if (isDHCPenabled)
return true; // no change necessary
var process = new Process
{
StartInfo = new ProcessStartInfo("netsh", $"interface ip set address \"{networkInterfaceName}\" dhcp") { Verb = "runas" }
};
process.Start();
var successful = process.ExitCode == 0;
process.Dispose();
return successful;
}
A slightly more concise example that builds on top of the other answers here. I leveraged the code generation that is shipped with Visual Studio to remove most of the extra invocation code and replaced it with typed objects instead.
using System;
using System.Management;
namespace Utils
{
class NetworkManagement
{
/// <summary>
/// Returns a list of all the network interface class names that are currently enabled in the system
/// </summary>
/// <returns>list of nic names</returns>
public static string[] GetAllNicDescriptions()
{
List<string> nics = new List<string>();
using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration"))
{
using (var networkConfigs = networkConfigMng.GetInstances())
{
foreach (var config in networkConfigs.Cast<ManagementObject>()
.Where(mo => (bool)mo["IPEnabled"])
.Select(x=> new NetworkAdapterConfiguration(x)))
{
nics.Add(config.Description);
}
}
}
return nics.ToArray();
}
/// <summary>
/// Set's the DNS Server of the local machine
/// </summary>
/// <param name="nicDescription">The full description of the network interface class</param>
/// <param name="dnsServers">Comma seperated list of DNS server addresses</param>
/// <remarks>Requires a reference to the System.Management namespace</remarks>
public static bool SetNameservers(string nicDescription, string[] dnsServers, bool restart = false)
{
using (ManagementClass networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration"))
{
using (ManagementObjectCollection networkConfigs = networkConfigMng.GetInstances())
{
foreach (ManagementObject mboDNS in networkConfigs.Cast<ManagementObject>().Where(mo => (bool)mo["IPEnabled"] && (string)mo["Description"] == nicDescription))
{
// NAC class was generated by opening a developer console and entering:
// mgmtclassgen Win32_NetworkAdapterConfiguration -p NetworkAdapterConfiguration.cs
// See: http://blog.opennetcf.com/2008/06/24/disableenable-network-connections-under-vista/
using (NetworkAdapterConfiguration config = new NetworkAdapterConfiguration(mboDNS))
{
if (config.SetDNSServerSearchOrder(dnsServers) == 0)
{
RestartNetworkAdapter(nicDescription);
}
}
}
}
}
return false;
}
/// <summary>
/// Restarts a given Network adapter
/// </summary>
/// <param name="nicDescription">The full description of the network interface class</param>
public static void RestartNetworkAdapter(string nicDescription)
{
using (ManagementClass networkConfigMng = new ManagementClass("Win32_NetworkAdapter"))
{
using (ManagementObjectCollection networkConfigs = networkConfigMng.GetInstances())
{
foreach (ManagementObject mboDNS in networkConfigs.Cast<ManagementObject>().Where(mo=> (string)mo["Description"] == nicDescription))
{
// NA class was generated by opening dev console and entering
// mgmtclassgen Win32_NetworkAdapter -p NetworkAdapter.cs
using (NetworkAdapter adapter = new NetworkAdapter(mboDNS))
{
adapter.Disable();
adapter.Enable();
Thread.Sleep(4000); // Wait a few secs until exiting, this will give the NIC enough time to re-connect
return;
}
}
}
}
}
/// <summary>
/// Get's the DNS Server of the local machine
/// </summary>
/// <param name="nicDescription">The full description of the network interface class</param>
public static string[] GetNameservers(string nicDescription)
{
using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration"))
{
using (var networkConfigs = networkConfigMng.GetInstances())
{
foreach (var config in networkConfigs.Cast<ManagementObject>()
.Where(mo => (bool)mo["IPEnabled"] && (string)mo["Description"] == nicDescription)
.Select( x => new NetworkAdapterConfiguration(x)))
{
return config.DNSServerSearchOrder;
}
}
}
return null;
}
/// <summary>
/// Set's a new IP Address and it's Submask of the local machine
/// </summary>
/// <param name="nicDescription">The full description of the network interface class</param>
/// <param name="ipAddresses">The IP Address</param>
/// <param name="subnetMask">The Submask IP Address</param>
/// <param name="gateway">The gateway.</param>
/// <remarks>Requires a reference to the System.Management namespace</remarks>
public static void SetIP(string nicDescription, string[] ipAddresses, string subnetMask, string gateway)
{
using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration"))
{
using (var networkConfigs = networkConfigMng.GetInstances())
{
foreach (var config in networkConfigs.Cast<ManagementObject>()
.Where(mo => (bool)mo["IPEnabled"] && (string)mo["Description"] == nicDescription)
.Select( x=> new NetworkAdapterConfiguration(x)))
{
// Set the new IP and subnet masks if needed
config.EnableStatic(ipAddresses, Array.ConvertAll(ipAddresses, _ => subnetMask));
// Set mew gateway if needed
if (!String.IsNullOrEmpty(gateway))
{
config.SetGateways(new[] {gateway}, new ushort[] {1});
}
}
}
}
}
}
}
Full source:
https://github.com/sverrirs/DnsHelper/blob/master/src/DnsHelperUI/NetworkManagement.cs
The existing answers have quite broken code. The DNS method does not work at all. Here is code that I used to configure my NIC:
public static class NetworkConfigurator
{
/// <summary>
/// Set's a new IP Address and it's Submask of the local machine
/// </summary>
/// <param name="ipAddress">The IP Address</param>
/// <param name="subnetMask">The Submask IP Address</param>
/// <param name="gateway">The gateway.</param>
/// <param name="nicDescription"></param>
/// <remarks>Requires a reference to the System.Management namespace</remarks>
public static void SetIP(string nicDescription, string[] ipAddresses, string subnetMask, string gateway)
{
using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration"))
{
using (var networkConfigs = networkConfigMng.GetInstances())
{
foreach (var managementObject in networkConfigs.Cast<ManagementObject>().Where(mo => (bool)mo["IPEnabled"] && (string)mo["Description"] == nicDescription))
{
using (var newIP = managementObject.GetMethodParameters("EnableStatic"))
{
// Set new IP address and subnet if needed
if (ipAddresses != null || !String.IsNullOrEmpty(subnetMask))
{
if (ipAddresses != null)
{
newIP["IPAddress"] = ipAddresses;
}
if (!String.IsNullOrEmpty(subnetMask))
{
newIP["SubnetMask"] = Array.ConvertAll(ipAddresses, _ => subnetMask);
}
managementObject.InvokeMethod("EnableStatic", newIP, null);
}
// Set mew gateway if needed
if (!String.IsNullOrEmpty(gateway))
{
using (var newGateway = managementObject.GetMethodParameters("SetGateways"))
{
newGateway["DefaultIPGateway"] = new[] { gateway };
newGateway["GatewayCostMetric"] = new[] { 1 };
managementObject.InvokeMethod("SetGateways", newGateway, null);
}
}
}
}
}
}
}
/// <summary>
/// Set's the DNS Server of the local machine
/// </summary>
/// <param name="nic">NIC address</param>
/// <param name="dnsServers">Comma seperated list of DNS server addresses</param>
/// <remarks>Requires a reference to the System.Management namespace</remarks>
public static void SetNameservers(string nicDescription, string[] dnsServers)
{
using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration"))
{
using (var networkConfigs = networkConfigMng.GetInstances())
{
foreach (var managementObject in networkConfigs.Cast<ManagementObject>().Where(mo => (bool)mo["IPEnabled"] && (string)mo["Description"] == nicDescription))
{
using (var newDNS = managementObject.GetMethodParameters("SetDNSServerSearchOrder"))
{
newDNS["DNSServerSearchOrder"] = dnsServers;
managementObject.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
}
}
}
}
}
}
This maybe more clear:
static NetworkInterface GetNetworkInterface(string macAddress)
{
foreach(NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
if (macAddress == ni.GetPhysicalAddress().ToString())
return ni;
}
return null;
}
static ManagementObject GetNetworkInterfaceManagementObject(string macAddress)
{
NetworkInterface ni = GetNetworkInterface(macAddress);
if (ni == null)
return null;
ManagementClass managementClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = managementClass.GetInstances();
foreach(ManagementObject mo in moc)
{
if (mo["settingID"].ToString() == ni.Id)
return mo;
}
return null;
}
static bool SetupNIC(string macAddress, string ip, string subnet, string gateway, string dns)
{
try
{
ManagementObject mo = GetNetworkInterfaceManagementObject(macAddress);
//Set IP
ManagementBaseObject mboIP = mo.GetMethodParameters("EnableStatic");
mboIP["IPAddress"] = new string[] { ip };
mboIP["SubnetMask"] = new string[] { subnet };
mo.InvokeMethod("EnableStatic", mboIP, null);
//Set Gateway
ManagementBaseObject mboGateway = mo.GetMethodParameters("SetGateways");
mboGateway["DefaultIPGateway"] = new string[] { gateway };
mboGateway["GatewayCostMetric"] = new int[] { 1 };
mo.InvokeMethod("SetGateways", mboGateway, null);
//Set DNS
ManagementBaseObject mboDNS = mo.GetMethodParameters("SetDNSServerSearchOrder");
mboDNS["DNSServerSearchOrder"] = new string[] { dns };
mo.InvokeMethod("SetDNSServerSearchOrder", mboDNS, null);
return true;
}
catch (Exception e)
{
return false;
}
}

Categories

Resources