How can one get examples on how to use the objects' methods through Get-Help?
And why is there a discrepancy in the number of methods listed in PowerShell and in MSDN?
For example, 'a'|gm|? name -like '*char*' shows there is a ToChar() method for strings but String Class, Methods doesn’t.
There is another way around. For example, you are not sure about all members in System.String class then to list out all members you can do below using Get-Member commandlet
$string = "hello";
$string | Get-Member
This will give you a rough signature/definition of the members like
TypeName: System.String
Name MemberType Definition
---- ---------- ----------
Clone Method System.Object Clone()
CompareTo Method int CompareTo(System.Object value), int CompareTo(string strB)
Contains Method bool Contains(string value)
similarly, to view Static members use -Static switch like
$string | Get-Member -Static
If you want more information on a particular member(s) then MSDN is always there.
Also, see this Nice Technet Article
If you are using the PSCX module, you can get to the online MSDN topic like so:
Pscx\Get-Help -Object [string] -Online
If you grab the latest version of PSCX (3.2.0), this proxy is disabled by default. To turn it on, import the module like so:
Import-Module Pscx -ArgumentList #{ModulesToImport = #{GetHelp = $true}}
Unfortunately Get-Help cannot be used to get help about methods on objects/classes. At the moment you'll have to resort to web searches.
Related
I am having a hard time with the literature on this. I am hoping someone can explain the difference here so that I can better understand the flow of my scripts.
function select-bin {
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Select a Bin"
$objForm.Size = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"
$x = #()
# Create $OKButton and $objListBox ... removed code as not relevant.
$OKButton.Add_Click({
$x+=$objListBox.SelectedItems
$objForm.Close()
})
$objForm.ShowDialog()
if ($x) {
return $x
}
else {
return $null
}
}
In the code sample above, it works great in Powershell V2, however in V4 the add_click section doesn't work. It successfully closes the form (created in the functions scope) but fails to update $x.
So I guess here are my questions.
In V2, was the add_click section considered in the same scope as the function? (only way I see it having been able to update $x)
What is the proper way to have an event like this alter data? I feel like declaring $x in the global scope is a bit much seeing as I only need it in the function.
In V4 what scope is add_click running in? It is clearly different from what it was in V2, but is it running in the global? is it relative to the $OKButton or the function? I am assuming its a child of either the global or the function but I truly do not know.
Any clarity that anyone could offer would be greatly appreciated. I have a lot of updating to do before my company moves to V4, seeing as I have not been following best practices for scoping (my bad).
In V2, a ScriptBlock, when converted to a delegate, would run dot sourced in whatever scope happened to be the current scope.
Often, this was the scope that created the script block, so things worked naturally. In some cases though, the scope it ran in had nothing to do with the scope it was created in.
In V4, these script blocks run in their own scope - a new scope that is the child of the current scope, just as they were a function and you called the function normally (not dot sourcing.)
I think your best bet is to use one of the following (in roughly best to worst):
$script:x
$x = Get-Variable -Scope 1 -Name x
$global:x
I have a method which runs Before a feature like so,
[BeforeFeature, Scope(Feature = "Feature1"]
Method()
{
}
I want the same method to be ran for another feature file that i've wiritten i.e. Feature2
How do i combine this "Feature2" in the scope Binding?
I tried this
[BeforeFeature, Scope(Feature = "Feature1"]
[Scope(Feature="Feature2")]
but didn't work. The method only runs for Feature1 and not for Feature2
According to the scoping rules multiple Scope bindings will be OR'd so I would expect the second example to work. Are you sure that you are spelling the feature name correctly?
I'll try and get an example worked up to verify this behaviour.
I have a problem with my puppet script.
I would like to get a value set in my resource file. I declare a resource like that
define checkxml(
$account = '',
$pwd = template('abc/abc.erb'),
){
if(empty($pwd)){
fail('pwd empty')
}
}
I call it via :
checkxml{"$agtaccount":
account => $agtaccount,
}
I want to get the value of $pwd. The $pwd will get is value by Template. If i try to show the value in my resource definition it's ok, I get the right value, so the Template works fine.
My problem is to get access this value after calling the ressource. I saw the getparam of stdlib but doesn't work for me.
getparam(Checkxml["$agtaccount"],"pwd")
If i try to get the account parameters instead of pwd it's ok. I think as i doesn't declare the pwd i can't get him back
How can i get him ?
Thanks for your help
Ugh, this looks dangerous. First off I'd recommend to steer clear of that function and the concept it embodies. It faces you with evaluation order dependencies, which can always lead to inconsistent manifest behavior.
As for the retrieval of the value itself - that will likely not work if the default is used. That's because on a catalog building level, there is not yet a value that is being bound to the parameter, if that makes any sense.
The resolution of final parameter values is rather involved, so there are lots of things that can go wrong with a manifest that relies on such introspective functionality.
I recommend to retrieve the desired value in a more central location (that depends on your manifest structure) and use it both when declaring the Checkxml["$agtaccount"] resource as well as its other uses (for which you are currently trying to extract it).
I am using the following method to convert string type to a generic type
public static T Parse<T>(string value)
{
// or ConvertFromInvariantString if you are doing serialization
return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(value);
}
I have to call it like this
Parse<Int32>(Some string value);
Parse<DateTime>(Some string value);
I am trying that instead of giving the result type explicitly, i can give it like
Parse<Type.GetType("Int32")>(Some string value);
Generics are off the table here. Primary issue is that you are trying to take a shortcut around type identity. The name of a type is not just the type name that you use in a program. It also includes the namespace it is declared in, the display name of the assembly in which it is stored, the version number of the assembly and the public key token for the assembly's strong name. In other words, the Type.AssemblyQualifiedName.
Which requires you to write your code similar to this:
Parse(Type.GetType("System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089""), SomeStringValue);
That will work just fine. But I'd guess that you are not going to enjoy writing that. Otherwise gives you insight in what a compiler does when it reads "Int32" in your program. It will look in its symbol table that was primed with the reference assemblies you added and notes what possible matches there may be in that table, considering what using directives are in effect.
You'd have to implement something similar in your program. The equivalent of the compiler's symbol table is a Dictionary<string, Type>. You can prime it by populating it with the kind of types that you prefer to use with a short string name. Like
LookupTable.Add("Int32", typeof(int));
LookupTable.Add("String", typeof(string));
// etc...
Now you can write:
Parse(LookupTable["Int32"], SomeStringValue);
That will work just fine. But I'd guess that you are not going to enjoy writing that. Pretty hard to beat the compiler.
I think that if you need to specify the type at runtime instead of compile time (as in your example where you have specified "Int32" as a string) then first you need to rewrite your code with something like:
public static object Parse(Type destinationType, string value)
{
return TypeDescriptor.GetConverter(destinationType).ConvertFromString(value);
}
Now you can call this new method writing:
var myValue = Parse(Type.GetType("System.Int32"), "33243");
Type.GetType requires you to specify the full namespace and the assembly name (Assembly qualified name), but for mscorlib types (like all primitive types) or for the currently executing assembly types you only need to specify the full namespace, like System.Int32 or System.DateTime. See MSDN.
Consider also that there are other option to convert primitive types to and from string. I suggest you to use Convert.ChangeType. This method basically check if the specified type support the IConvertible interface. Basically you can write just:
var myValue = Convert.ChangeType("23423", typeof(Int32));
or
var myValue = Convert.ChangeType("23423", Type.GetType("System.Int32"));
It also support InvariantCulture:
var myValue = Convert.ChangeType("23423", typeof(Int32), CultureInfo.InvariantCulture);
There is also a good library that combine IConvertible feature and TypeConverter, see Code Project: Universal Type Converter. This library as many useful features and it is free, also available on nuget.
I'm working on a C++ Metro style app and have to pass a string by reference (somehow). At first, I passed the String^ which doesn't work because strings are immutable how I have found out.
What would be a proper way to pass a string by reference?
Edit: OK, it seems that it's not that easy since the answers and comments suggest to use return values. But as far as I think this is not applicable in my situation: In this Metro app I have two pages and a string should be "shared" across those two pages.
So in the main page I do this in a click event:
this->Frame->Navigate(newPage, this->TestString);
In the OnNavigatedTo event of the second page I convert the second parameter to a String^ and change it. Then I use this->Frame->GoBack() to navigate back to the first page. There I'd like to have access to the changed string. Unfortunately, GoBack() doesn't allow to pass any parameters as far as I know.
You can use a tracking reference:
void ModifyTheParameter(String^% value) {
value = gcnew String("Blah");
}
That would modify the original variable you passed in as parameter (see MSDN for more info and examples). It would then be used just as any other method taking a String^ parameter.
But if possible, avoid using tracking references as parameters. I'd recommend just returning a String^ and assigning that to the original variable.
Yet another possibility: You could just create some kind of View-agnostic DataModel that contains your String (and possibly other data that you work with). You could then pass that DataModel to your method. Since the DataModel variable isn't changed (just a property of it), you wouldn't need to pass a reference to it.
See below an example of a function f which takes as a parameter a reference to a std::string.
std::string someString;
void f(std::string& s);
f(someString);