If there is no concept of running them for me I want to load certain scripts
and run them myself. I have tried using RunspaceInvoke(myRunspace) with the
Profile variable set in the session and that does strange and unatural things
that I have been unable to debug or catch [puts up my dialog from within the
append call without returning to the mainform_load call].
I have tried the below code with variations on the path separation
characters. As soon as I execute the append statement, my forms dialog comes
up and I never actually make it to the 2nd statement which creates the
RunspaceInvoke object. My call stack shows me in some werid kind of inner
message loop with the last call being
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop.
mRunspace.RunspaceConfiguration.InitializationScripts.Append(new
ScriptConfigurationEntry(@"C:\\Users\\[MyUserid]\\Documents\\WindowsPowerShell\\Microsoft.PowerShell_profile.ps1", "Profile script"));
RunspaceInvoke lRunspaceInvoke = new RunspaceInvoke(mRunspace);
The MSDN doc is no help as it refers to skin and bone examples that do not
use these methods. I would love to know how to use RunspaceInvoke,
RunspaceConfiguration, ScriptConfigurationEntry etc. in general but
specifically to run some profile scripts. Seems these methods will get me
what I want but how to use them is not readily apparent to me or does not
work.
Thanks, Dave
// open the runspace and run the profile
mRunspace.Open();
RunspaceInvoke lRunspaceInvoke = new RunspaceInvoke(mRunspace);
lRunspaceInvoke.Invoke(@"C:\\Users\\[myuserid]\\Documents\\WindowsPowerShell\\Microsoft.PowerShell_profile.ps1");
Let me start by pointing you at a blog post I wrote about
RunspaceConfiguration. My conclusion was that you can't actually create
a custom RunspaceConfiguration.
http://huddledmasses.org/is-powershell-shellid-too-big-a-burden/
As far as I can tell, profile scripts are not InitializationScripts. The
documentation on this stuff leaves MUCH to be desired, of course: there
are NO samples, and for the most part I suspect the only people who
understand the docs work at Microsoft ;)
I can point you to what I did, but it's rather complicated compared to
what you actually "have" to do (especially if you're not trying to
create an interactive host):
http://poshconsole.codeplex.com/SourceControl/changeset/view/30329#356218
But I've talked to most of the guys that have worked on PowerShell
hosts, and as far as I know, we're all agreed that you have to just run
the profile script(s) yourself, and if you want it to be "like
powershell.exe" then you need to make sure you:
1) dot-source them
2) don't put them in the history
--
Joel
As I posted in the earlier reply to myself, I did manage to run my scripts
by invoking them in the runspace and was quite happy till I realized that
anything they did had gone out of scope when I invoked my main script in the
pipeline create. My application is basically running a script and saving the
output and I do not have an interactive shell but have implemented UI and
RawUI.
I'm quite new to PowerShell and understand that when you "dot-source" one
script from another it is like you included the cmdlets in your outer script
and so circumvent the scope issue compared to invoking it. What I'm not sure
about is how, within a single pipeline, to run some profile scripts ahead of
my main script I want to run. Basically I guess I would have to "dot-source"
any profile script I wanted to run and then add my own script to the pipeline
so will play around with that. I seem to remember I could not add multiple
scripts as only the last was executed and produced output. Ideally, there
would be some way to "dot-source" the profile script in the runspace and have
that environment presented to the pipeline as I will ultimately run several
scripts one by one but would love to share the runspace and a common profile
execution. Maybe not possible. I will try ways to do something with the
runspace as well. Do you know if there any concept of scope in the runspace
that is inerited by the pipeline or is sessionstate pretty much all it gets?
Yes, the documentation is woefully inadequate when a method such as
RunspaceFactory.CreateRunspace gives you the pearl of wisdom that merely says
it creates a Runspace (duh) and refers you to a skin and bones example that
does not use that method much less any of the other signatures that have the
desired optional parameters. And no intellisense... The whole concept of
PowerShell is generally great though!
Would love your .02 on my other post regarding BufferSize, line wrapping and
what I feel is a hosting bug where PS pads out most WriteLine calls with
blanks to meet the BufferSize.
Thanks again, Dave
// add the profile scripts if any
foreach (FileInfo lProfileFileInfo in lProfileFileInfos)
{
lScriptName = string.Format(". '{0}'", lProfileFileInfo.FullName);
mPipeline.Commands.AddScript(lScriptName, false); // does not work if
local scope
}
// add our main script
lScriptName = string.Format(". '{0}'", pScriptCommand);
mPipeline.Commands.AddScript(lScriptName, false); // do not use local scope
here either but does not seem to matter either way
List<string> existingProfiles = new List<string>();
string myDocs =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
foreach (var path in new[]{
Path.GetFullPath(Path.Combine(Environment.SystemDirectory,
@"WindowsPowerShell\v1.0\profile_exit.ps1")),
Path.GetFullPath(Path.Combine(Environment.SystemDirectory,
@"WindowsPowerShell\v1.0\PoshConsole_profile_exit.ps1")),
Path.GetFullPath( Path.Combine( myDocs,
@"WindowsPowerShell\profile_exit.ps1")),
Path.GetFullPath( Path.Combine( myDocs,
@"WindowsPowerShell\PoshConsole_profile_exit.ps1")),
}) {
if (File.Exists(path)) {
existingProfiles.Add(path);
}
}
Then, you add your script to that, and turn them all into a single
script. Something like this:
mPipeline.Commands.AddScript(
". '" +
String.Join("'\n. '", existingProfiles.ToArray()) +
"'\n" +
yourScriptFullName );
If you're getting a console window flash, it's probably because you're
running a legacy console app in your script. You can't avoid opening a
"real" (read "legacy") console window, exactly, but you CAN hide it.
I released that part of PoshConsole under a LOT of different Open Source
licenses, including BSD or MIT, so you should feel free to borrow my
NativeConsole.cs ...
http://poshconsole.codeplex.com/SourceControl/changeset/view/30329#139099
--
Joel
CodeSlinger wrote:
> Well I sort of got it working with the following but get the horrible cmd.exe
> shell type black screen flash when I run the scripts which include one user
> profile and my main script I want to run. Any way to get rid of that flash???
> Dave
...
...
And thanks for the offer on the nativeconsole. Indeed, I found out the
"flash" was not from my profile per se but rather from calling a WMI related
function I had defined in my profile. I thought it was due to the profile
since it only happened once and not on subsequent calls. I removed the
function out of the profile and just define and call the function in my main
script invoked by the pipeline, not the runspace, and still get the "flash"
there as well. Nothing to do with profiles. It was a snippet I picked up at
someone's WMI blog though I forget who...
### The call of this function flashes the first time it is executed but not
subsequent times
function Get-MyLoggedOnUsers
{
param([string]$Computer)
if ($computer -eq "")
{
$computer = hostname
}
Get-WmiObject Win32_LoggedOnUser -ComputerName $Computer | Select
Antecedent -Unique | %{"{0}/{1}" -f $_.Antecedent.ToString().Split(’"‘)[1],
$_.Antecedent.ToString().Split(’"‘)[3]}
}
"`nShow logged on users..."
Get-MyLoggedOnUsers
If you read about_profiles the helpfile leads one to believe that
$pshome\profile.ps1 will be ran for all users and hosts. Have you tried this?
Based on what both you two are saying I'm taking that its up to the host to
run these explicitly.
just curious
bob
All UI code ends up using the good ol Windows Message pump eventually. I
would have thought a modal dialog would have behaved regardless however seem
to recall people having problems with the POSH Console host and WPF the
reason is its free-threaded.
> > characters. As soon as I execute the append statement, my forms dialog comes
> > up and I never actually make it to the 2nd statement which creates the
> > RunspaceInvoke object. My call stack shows me in some werid kind of inner
> > message loop with the last call being
1. "All users" profile is loaded from "<Installation Directory>\profile.ps1"
2. "All users," host-specific profile is loaded from "<Installation
Directory>\Microsoft.PowerShell_profile.ps1"
3. Current user profile is loaded from "<My
Documents>\WindowsPowerShell\profile.ps1"
4. Current User, host-specific profile is loaded from "<My
Documents>\WindowsPowerShell\Microsoft.PowerShell_profile.ps1"
Dave
Collection<PSObject> output = lRunspaceInvoke.Invoke(lScriptName, null, out
errors);