I'm building a PowerShell host by C#, and I want to display the result after invoking PowerShell. Now I use the following method:
public static string GetLogQueriedString(
PSMemberInfoCollection<PSPropertyInfo> PSPropertyCollection)
{
string line = string.Empty;
foreach (var item in PSPropertyCollection)
{
if (!line.Equals(string.Empty)) line += ",";
line += item.Name + " : " + item.Value;
}
return line;
}
It works if the PSObject has many properties that I need, but in this situation, if the PSObject is a string, the result is not what I want. It will display "Length: 40", rather than the string itself.
And another question: if I execute several PowerShell commands, why will it display all the results, including the previous result. For example, I execute "ls; get-process", and it will display the result of "ls" and the result of "get-process".
I think we need to see more of your code. The typical approach to display returned PSObjects is:
using (var ps = PowerShell.Create()) {
while (true) {
Console.WriteLine("Enter an expression:");
string input = Console.ReadLine();
if (String.IsNullOrWhiteSpace(input)) break;
ps.AddScript(input);
Collection<PSObject> results = ps.Invoke();
foreach (var result in results) {
Console.WriteLine(result);
}
}
}
If you don't need to access properties on the returned objects and all you're interested in is the formatted text try changing this line:
ps.AddScript(input + " | Out-String");
If you want to do custom formatting based on object type, you will need to test for the type and format as you see fit:
foreach (var result in results) {
var baseObj = result.BaseObject;
if (baseObj is System.Diagnostics.Process)
{
var p = (System.Diagnostics.Process) baseObj;
Console.WriteLine("Handles:{0}, NPM:{1}, PM:{2}, etc", p.HandleCount, p.NonpagedSystemMemorySize, p.PagedMemorySize);
}
else {
Console.WriteLine(result);
}
}
More of your code is needed, but just a clarification of the previous answer.... It may be helpful to think of PSObject LIKE an array, in that each value is a key-value pair. Because of this, if you try to explicitly cast like ToString, you'll get the object type, much like if you try to cast an array to a string you'll get a memory reference.
An easy solution is to use a foreach. For your code:
foreach(var r in results) {
string toConsole = r.ToString()
}
Console.WriteLine(toConsole);
Related
Sorry, this is pretty basic but for the life of me I have not been able to solve it:
I have this:
public static IHtmlString HrefLangLinks(this PageData currentPage)
{
var availablePageLanguages = currentPage.ExistingLanguages.Select(culture => culture.Name).ToArray();
foreach (string listitem in availablePageLanguages)
{
var Output = string.Join(",", listitem);
}
// Dictionary<String, String>
return new HtmlString(Output.ToString());
}
I would like to get the results of the foreach loop outputted in the return value. But Visual Studio informs me that "Output" (the instance in my return value) does not exist in the current context.
I thought I could solve this by adding var Output =""; outside of my foreach loop but that did not work.
Define Output before going into the foreach loop and then assign it a value:
var Output = "";
foreach (string listitem in availablePageLanguages)
{
Output = string.Join(",", listitem);
}
Apart from that I wonder if you really need a for loop in this case as you should also be able to this at once if availablePageLanguages is an array of string (string[]):
var Output = String.Join(" ", availablePageLanguages));
Im trying to find an answer for this but i must be searching for the wrong terms.
Im working on a Windows phone app and am getting data from an API with a nested array value "user.username"
void data_arrived(object sender, DownloadCompleteData e)
{
String data = e.data;
JArray obj = JArray.Parse(data);
for (int i = 0; i < obj.Count; i++)
{
JObject row = JObject.Parse(obj[i].ToString());
var item = new DataList();
item.country = row["title"].ToString() + " (€" + row["price"].ToString() + ") ";
item.code = row["price"].ToString();
item.imageURL = row["urlimage"].ToString();
item.votes = row["votes"].ToString();
item.category = row["category"].ToString();
item.username = row["user.username"].ToString();
list.Items.Add(item);
}
}
Everything else works fine except user.username
How do i use this properly?
Thanks
You can deserialize a valid JSON string to a dynamic object. This will allow you access to underlying object using dot notation. e.g.
dynamic row = JsonConvert.DeserializeObject (obj[i].ToString());
Your final code block inside loop will look like
dynamic row = JsonConvert.DeserializeObject(obj[i].ToString());
Console.WriteLine(row.title.ToString() + " (€" + row.price.ToString() + ") ");
Console.WriteLine(row.price.ToString());
Console.WriteLine(row.urlimage.ToString());
Console.WriteLine(row.votes.ToString());
Console.WriteLine(row.category.ToString());
Console.WriteLine(row.user.username.ToString());
Console.WriteLine();
Console.WriteLine("-----------------------------\n");
There is no "easy" way to achieve this because the . in C# is reserved.
However, you could achieve something pretty close by using a dictionary and collection initializer. It's still somewhat isolated, and doesn't require you to create a custom class.
var obj = new Dictionary<string, object>
{
{ "user.username", "myvalue" }
};
var json = JsonConvert.SerializeObject(obj);
//{"user.username":"myvalue"}
How do I iterate through the List<Galaxy> and print out the value(s) of every property without having to write the property name(s) explicitly?
For example, I use this code to write property values of all properties of galaxy
private static void IterateThroughList()
{
var theGalaxies = new List<Galaxy>
{
new Galaxy() { Name = "Tadpole", MegaLightYears = 400},
new Galaxy() { Name = "Pinwheel", MegaLightYears = 25}
};
foreach (Galaxy theGalaxy in theGalaxies)
{
// this part is of concern
Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears);
}
}
I'm trying to avoid the explicit property names in this line
Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears);
So that, if my Galaxy class had more properties than Name and MegaLightYears, it would automatically print them too.
If you want to
Write all properties without naming them
Use it for any Type in a generic way
You can write a quick Reflection utility like this
public static string GetAllProperties(object obj)
{
return string.Join(" ", obj.GetType()
.GetProperties()
.Select(prop => prop.GetValue(obj)));
}
And use it like
foreach (Galaxy theGalaxy in theGalaxies)
{
Console.WriteLine(GetAllProperties(theGalaxy));
}
If I understand you correctly you want to avoid having to write the individual properties of the galaxy within the loop?
In that case you might overload ToString on Galaxy appropriately:
class Galaxy {
public override string ToString() {
return Name + " " + MegaLightYearsl;
}
}
Then you can just do
foreach (var galaxy in theGalaxies) {
Console.WriteLine(galaxy);
}
However, since you only have one ToString to override, you cannot do this for wildly differing string representations of your object that may be needed in different contexts.
Your question is a little unclear, but I assume you're asking for how you iterate through a list by index instead of as a foreach loop.
Try a standard for loop, like so:
for(int i = 0; i < theGalaxies.Count; i++) {
Console.WriteLine(theGalaxies[i].Name + " " + theGalaxies[i].MegaLightYears);
}
I am trying to read in POST data to an ASPX (c#) page. I have got the post data now inside a string. I am now wondering if this is the best way to use it. Using the code here (http://stackoverflow.com/questions/10386534/using-request-getbufferlessinputstream-correctly-for-post-data-c-sharp) I have the following string
<callback variable1="foo1" variable2="foo2" variable3="foo3" />
As this is now in a string, I am splitting based on a space.
string[] pairs = theResponse.Split(' ');
Dictionary<string, string> results = new Dictionary<string, string>();
foreach (string pair in pairs)
{
string[] paramvalue = pair.Split('=');
results.Add(paramvalue[0], paramvalue[1]);
Debug.WriteLine(paramvalue[0].ToString());
}
The trouble comes when a value has a space in it. For example, variable3="foo 3" upsets the code.
Is there something better I should be doing to parse the incoming http post variables within the string??
You might want to treat it as XML directly:
// just use 'theResponse' here instead
var xml = "<callback variable1=\"foo1\" variable2=\"foo2\" variable3=\"foo3\" />";
// once inside an XElement you can get all the values
var ele = XElement.Parse(xml);
// an example of getting the attributes out
var values = ele.Attributes().Select(att => new { Name = att.Name, Value = att.Value });
// or print them
foreach (var attr in ele.Attributes())
{
Console.WriteLine("{0} - {1}", attr.Name, attr.Value);
}
Of course you can change that last line to whatever you want, the above is a rough example.
i have a list of objects in a collection. Each object has a string property called Issue. I want to concatenate the issue from all of the items in the collection and put them into a single string. what is the cleanest way of doing this using LINQ.
here is manual way:
string issueList = "";
foreach (var item in collection)
{
if (!String.IsNullOrEmpty(item.Issue)
{
issueList = issueList + item.Issue + ", ";
}
}
//Remove the last comma
issueList = issueList.Remove(issueList.Length - 2);
return issueList;
You can write
return String.Join(", ", collection.Select(o => o.Issue));
In .Net 3.5, you'll need to add .ToArray().
You could use ToDelimitedString from morelinq.