Getting source code in Main

Ask your PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
This topic is 2 years and 4 months old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked
User avatar
akincer
Posts: 43
Last visit: Thu Mar 14, 2024 7:53 am

Getting source code in Main

Post by akincer »

Product, version and build: Powershell Studio 2021 build 5.8.196
Operating system: n/a
PowerShell version(s): n/a

I feel like there might be a better way to do this but I think I've found a way. I'm trying to capture the source of class files I'm building so I can inject class code into script blocks at run time for jobs that will get spun off when needed so I don't have to copy/paste into a defined script block any needed classes.

The current way I've found to do this:

1. Set class files to content
2. Use dot sourcing in Main to get access to the classes
3. Get the file content of the subsequent class files

This is not ideal. I don't want class files just hanging around in the install directory. I really just want the executable. Is there a way to grab the class file code some other way as text having it as an included file and not content?

Note if my only option is to get the entire compiled script code of all files that's perfectly fine. I'll just parse it.
User avatar
brittneyr
Site Admin
Posts: 1672
Last visit: Tue Apr 16, 2024 2:47 pm
Answers: 39
Been upvoted: 31 times

Re: Getting source code in Main

Post by brittneyr »

Have you tried the any of the following:

- For the class files, if you set them to Build = Include and Shared = true, you should be able to use them across the files also set as Include.
From there, please try refer to the following:
https://www.reddit.com/r/PowerShell/com ... _to_a_job/

- From SAPIEN Script Packager, you can try to resolve and include external scripts:
Packager_ResolveExternalScripts.png
Packager_ResolveExternalScripts.png (67.52 KiB) Viewed 2466 times
- If the files can not be added to the initial ps1 file before creating the executable, you can also make a module with these class files then use the 'using' statement to import the module classes into your script blocks. Then I would recommend making an installer.
Brittney
SAPIEN Technologies, Inc.
User avatar
akincer
Posts: 43
Last visit: Thu Mar 14, 2024 7:53 am

Re: Getting source code in Main

Post by akincer »

I'm not certain I understand you completely. I understand how to use script blocks. That's not the issue. The issue is how I can both have an object class file set to include and share but also grab the source to inject into a Scriptblock like this.

Code: Select all


file Hello.ps1
--------
class Hello {

}
--------

file World.ps1
--------
class World {

}
--------

file Main.ps1
--------
$hello = <fancy method to grab the shared and included Hello.ps1 source>
$world = <fancy method to grab the shared and included world.ps1 source>
$jobCode = <job scriptblock>
$helloWorld = [ScriptBlock]::create($hello + $world + $jobCode.ToString())
Start-Job -ScriptBlock $helloWorld
User avatar
brittneyr
Site Admin
Posts: 1672
Last visit: Tue Apr 16, 2024 2:47 pm
Answers: 39
Been upvoted: 31 times

Re: Getting source code in Main

Post by brittneyr »

[Topic moved by moderator to PowerShell Forum]
Brittney
SAPIEN Technologies, Inc.
User avatar
brittneyr
Site Admin
Posts: 1672
Last visit: Tue Apr 16, 2024 2:47 pm
Answers: 39
Been upvoted: 31 times

Re: Getting source code in Main

Post by brittneyr »

I've moved this to the PowerShell Forum as this is more of a PowerShell question as I don't believe there is a way to achieve this through PowerShell Studio project settings.
Based off what I understand you are trying to accomplish, the only other way I can think of to have both is to have a herestring of the class file and a copy of the the class file in project set to Include and Shared. Though that would mean maintaining that the file and string. That is not ideal or practical.
Brittney
SAPIEN Technologies, Inc.
User avatar
akincer
Posts: 43
Last visit: Thu Mar 14, 2024 7:53 am

Re: Getting source code in Main

Post by akincer »

I think I see what you're saying. I'll experiment a bit.
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Getting source code in Main

Post by jvierra »

Here is a quick demo of how to use a Here-String to compile a class and use it. Useful for embedding in PowerShell Job script blocks.
  1. $classtext = @'
  2.     class HtmlHead{
  3.         [string] Render(){ return "<title>Some Title</title>" }
  4.     }
  5. '@
  6. Invoke-Expression $classtext  # compliles the text into a class
  7. $classinstance = [HtmlHead]::New()   # create an instance
  8. $classinstance.Render()    # call an instance method
The here strings should be placed anywhere that is global to the overall script or project. Copying a global string into a scriptblock will require dynamically creating the scriptblock using the "[scriptblock]' type's "Create" method. It is also possible to use type methods to inject string and other variables into an existing script block. All primitives can be injected after a scriptblock has been created but not as text unless you manage everything as strings which is unnecessary.
User avatar
akincer
Posts: 43
Last visit: Thu Mar 14, 2024 7:53 am

Re: Getting source code in Main

Post by akincer »

OK I've now figured out how to do this but it does come with one trade-off that I haven't found a workaround for but given that jobs will be very important I can live with it -- in Main.ps1 you lose type hinting for everything related to your class in Powershell Studio due to the way the object is instantiated. But interestingly you maintain it in your job script block. Here's the solution in case anyone else needs to know how to do this.

1. In your MyClass.ps1 file define your entire class to a global variable (use your own naming convention):

Code: Select all

$global:classMyClass = {
	class MyClass {
		<class code>
	}
}
2. In Main to instantiate an instance of the object:

Code: Select all

New-Module 'ClassMyClassModule' $global:classMyClass | Import-Module
$myClassVariable= & (Get-Module 'ClassMyClassModule') { [MyClass]::new() }
3. Create your script block and use the classes in it like they are already there. Then add the classes you need like this:

Code: Select all

$myScriptBlock = {
	$myclass = [MyClass]::new()
}
$finalScriptBlock = [scriptblock]::create($Global:classMyClass.ToString() + $Global:classMyClass2.ToString() + $myScriptBlock.ToString())
4. Run your job with the new script block.

Code: Select all

Start-Job -ScriptBlock $finalScriptBlock
I don't know what it would take for you folks to add to Powershell Studio the ability to get the raw text of class files whenever desired or what that would even look like, but I'd love to see it added.
User avatar
akincer
Posts: 43
Last visit: Thu Mar 14, 2024 7:53 am

Re: Getting source code in Main

Post by akincer »

jvierra wrote: Mon Dec 13, 2021 2:54 pm Here is a quick demo of how to use a Here-String to compile a class and use it.
Thanks. I found Here-Strings not really desirable since you lose all IDE capabilities for that code block in Powershell Studio. The classes I'm building are not small in the least so using them isn't really a workable solution.
User avatar
Alexander Riedel
Posts: 8488
Last visit: Tue Apr 16, 2024 8:42 am
Answers: 20
Been upvoted: 37 times

Re: Getting source code in Main

Post by Alexander Riedel »

I am not sure why you do classes this way, that's for you to decide. But I do have to point out that the prescribed way to share code amongst otherwise unrelated items is to make them into a module.
Alexander Riedel
SAPIEN Technologies, Inc.
This topic is 2 years and 4 months old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked