Troubleshooting writing help for my PowerShell modules in PowerShell - caching

I have an assortment of PowerShell modules written in PowerShell (as opposed to C#) and I include documentation-comments in the code so that users get a full API description from Get-Help.
As I was writing a new module the help text seemed to get stuck at some point in time; any subsequent updates I have done to the help text in that file have not shown up after I saved the file, re-imported the module, or even restarted PowerShell then re-imported the module.
I next created a test module to see if I could replicate the issue. I set up psm1 and psd1 files, imported the module, and ran get-help, seeing the help from the psm1 file. I then added one line of text to the psm1 file, saved it, re-imported it... and the new line appeared in get-help!
I vaguely recall reading some time ago that you must bump the version in the psd1 file for new help to be recognized but my test case showed that is not necessarily needed (and I really don't want to have to bump the version).
I also vaguely recall reading that imported modules are cached somewhere and one could just delete the cached files to get it to recognize the new text--but I cannot recall where to find these.
So my goal is to be able to see the revised help text saved in the psm1 file in my real module without incrementing the module version. Ideas?

I was having similar issues when renaming and updating functions in some of my modules. A bit of searching turned up http://www.powertheshell.com/how-module-command-discovery-works-in-psv3/. In particular, the last bit about outdated caches mentions
PS> Get-Module -ListAvailable -Refresh
Running that solved my caching woes
PS> Get-Help Get-Module -Parameter Refresh
-Refresh [<SwitchParameter>]
Refreshes the cache of installed commands. The command cache is created when the session starts. It enables
the Get-Command cmdlet to get commands from modules that are not imported into the session.
This parameter is designed for development and testing scenarios in which the contents of modules have
changed since the session started.
When the Refresh parameter is used in a command, the ListAvailable parameter is required.

If you import a module that was already imported, it won't replace the functions that were previously imported. You need to remove the module first with Remove-Module, then import it again. I find it convenient to have this function in my profile:
function reload {
param(
[parameter(Mandatory=$true)]$Module
)
Write-Host;
try {
Remove-Module $Module -ea Stop;
} catch {
Write-Warning $error[0].Exception.Message;
Write-Host;
} finally {
Import-Module $Module -Verbose;
}
Write-Host;
}

Related

Joomla "Fatal error: Cannot redeclare jblogerror() in on line 0"

Here is a weird problem i'm facing; after updating Joomla to the latest version, website failed to up load but, as i've made a backup manually from these folders:
administrator
bin
cli
components
includes
layouts
libraries
modules
plugins
yt-assets
and all the root files, after restoring the backup still the website is not loading and just says
"Fatal error: Cannot redeclare jblogerror() in on line 0" !
Any suggestion? Thank you.
Apparently, the version of jBlog you are using is loading its attempting to load its own classes twice.
Let's assume the jBlog developers already fixed it and you carelessly ignored the warning to ensure all your extensions are compatible before updating.
Are you able to access administrator? Simply go there and upgrade jBlog including any modules.
Else, the issue lies within a plugin. In order to access the administrator and perform the update, you will need to manually disable the offending plugin.
A simple way is to rename its folder: start from plugins/system then plugins/content hopefully you'll have spotted it by then. Look into the subfolders of each and spot any that may be relevant to jBlog (or grep through the folder to locate the specific string)
If you have console access, simply run
# grep -rl jblogerror plugins/system
and you should see all the files that include such string, just rename their main plugin folder. But you could also do all this through ftp and guessing.

Workaround for an API not allowing require a specific library (luasocket) and not able to include it via moving DLL

I am using an API called Piepan, which allows me to write Lua scripts for Mumble bots. For context, it is written in Golang using an alternative mumble implementation called Gumble. Piepan scripts are executed via cmd prompt through a piepan.exe.
I can require most libraries, like inspect.lua, and I can easily require luasocket in non-piepan scripts (scripts executed via lua.exe), but if I try to require luasocket (or what I really want, a redis library that depends on luasocket), I get an error. This is less of an error and more of a missing feature from the API, which the creator acknowledges. The creator suggests to someone else with this problem that they simply use Gumble, but I cannot do that as I am only a Lua programmer.
Here's the code of me just trying to require luasocket:
local socket = require ("include-test.socket")
(I've also tried include-test.socket.core and just socket.core)
In accordance with this stackoverflow answer, I moved my files to resemble the user's own directory, so it looks like this:
Piepan folder
-piepan exe and dlls (not luasocket dlls)
-include-test (folder)
--Script for piepan
--socket.lua
--socket folder
---core.dll
Despite the directory looking how I imagine it should based on other users' Q/As, I get this error:
.\include-test\socket.lua:13: module socket.core not found:
no field package.preload['socket.core']
Lstat : The system cannot find the path specified.
GetFileAttributesEx .\socket\core.lua: The system cannot find the path specified.
GetFileAttributesEx C:\Users\Michael\piepan\lua\socket\core.lua: The system cannot find the path specified.
GetFileAttributesEx C:\Users\Michael\piepan\lua\socket\core\init.lua: The system cannot find the path specified.
GetFileAttributesEx C:\Program Files (x86)\Lua\5.1\lua\socket\core.luac: The system cannot find the path specified.,
I've also tried including the following line, inspired by this stackoverflow answer.
package.cpath = package.cpath .. ';include-test/?.dll'
to no avail.
I am looking for any available solution, whether that be moving around dlls or compiling the original Piepan w/ extra files as needed.
(To clarify, I need a workaround that allows me to require the redis library within the same script I run through piepan. Using an outside script with the redis library to then, say, launch piepan and do something there, is not helpful to me.)

How do I set up TeamCity CI so that it unpacks Xamarin components?

In Visual Studio everything works and a Components directory is created with the appropriate dlls. However, TeamCity is not able to retrieve the Android Support Library dlls because the trigger for the restore is a Xamarin VS plugin that runs when loading the solution. The equivalent of nuget package restore for Xamarin is xamarin-component. I have placed the xamarin-component.exe in my C:\Windows directory. To configure TeamCity, I prepended a Command Line build step with
Command executable: xamarin-component
Command parameters: restore mysolution.sln
TeamCity runs as NT Authority\System. So using PsExec,
psexec -i -s %SystemRoot%\system32\cmd.exe
If I then run 'xamarin-component login'
INFO (login): Computed cookie jar path: C:\Windows\system32\config\systemprofile\.xamarin-credentials
INFO (login): Computed cookie jar path: C:\Windows\system32\config\systemprofile\.xamarin-credentials
INFO (login): Credentials successfully stored.
When I go to my solution in cmd and attempt the restore, I get an attempt to download the componet, and then a Json parsing error. This is the same error I get in TeamCity.
I get the error if I use 'Administrator' (which stores the credential in C:\Users\Administrator. Earlier when I was using my personal account, it did work. However, once I deleted the C:\Users\tim\AppData\Local\Xamarin\Cache\Components, the same issue emerged. Fiddler shows that rather than getting Json back (as we do when we enter an invalid token) we are getting a 302 redirect that says Object moved here. And here is the xamarin
login page - obviously not Json.
Tried.
1. Set COOKIE_JAR_PATH to C:\Users\tim.xamarin-credentials - xpkg picks up but same error
2. Copy .xamarin-credentials from Config\system32 to D:\, set COOKIE_JAR_PATH to D:.xamarin-credentials - xpkg picks up but same error
3. Move .xamarin-credentials to C:\, set COOKIE_JAR_PATH - same error
4. Re-login in NT Authority with COOKIE_JAR_PATH to C:.xamarin-credentials - same error
My temporary idea now is to figure out where the NT Authority xamarin-component looks for Cache and put the files there.
C:\Windows\system32\config\systemprofile\AppData\Local\Xamarin\Cache\Components\xamandroidsupportv4-18-4.18.1.xam
The version of my xamarin-component is 0.99 - for 100, we try harder...
I’ve had trouble actually getting the cookie jar to load correctly from the system32 path. I think this is a path virtualization issue that I just don't understand well enough to make heads or tails of.
I ended up adding an environment variable that the tool will read from (I'm its principal author at Xamarin :-) that specifies the cookie jar path to read from, and this solved the problem for others using TeamCity. The environment variable is COOKIE_JAR_PATH.
You can set it from TeamCity's environment settings to point to a cookie jar path outside of the system32 profile directory (I think in my original testing, I put it in the root of the C: drive, but it can be anywhere, really).
As a hack, I copied the Cache folder from
C:\Users\tim\AppData\Local\Xamarin
to
C:\Windows\system32\config\systemprofile\AppData\Local\Xamarin\
That bypassed communication with the Xamarin server.
Update. I suspect it might be a bad link or setup on their server side. When xamarin-component restore is called, a call is made to
GET /api/available_versions?alias=xamandroidsupportv4-18 HTTP/1.1
which returns "Object moved to here" where "here" is nowhere.
If you start Visual Studio after deleting the Cache and Components folder (next to the solution), Xamarin makes a call to
GET /api/download/xamandroidsupportv4-18/4.18.1 HTTP/1.0
which has a similar looking Object moved to, but this time it directs you to xamarin-components.s3.amazonaws.com/
GET /fdca922d2b77799fe208a08c9f3444fe/xamandroidsupportv4-18-4.18.1.xam HTTP/1.0
Perhaps something changed, or the available_versions API has changed.
Thanks very much for this question and your answers to it. I didn't really like the idea of storing an auth cookie on the build node or having to copy a cache there manually, so I came up with my own solution so I hacked around this problem with a quick Powershell script that mimics the behaviour of the xamarin-component.exe restore action:
param
(
[Parameter(Mandatory=$true)]
$authCookie,
[Parameter(Mandatory=$true)]
$componentDirectory,
[Parameter(Mandatory=$true)]
$project
)
[void]([System.Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem'))
$xml = [xml] $(cat $project);
$components = $xml.Project.ItemGroup.XamarinComponentReference | ? { $_.Include.Length -gt 0 } | % { $_.Include };
if (!(test-path $componentDirectory))
{
echo "$componentDirectory didn't exist, so it was created.";
[void](mkdir $componentDirectory);
}
foreach ($component in $components)
{
$source = "http://components.xamarin.com/download/$component";
$destination = "$componentDirectory\$component.zip";
if (test-path $destination)
{
echo "$destination already exists, skipping...";
continue;
}
echo "Downloading $component from $source to $destination...";
$client = New-Object System.Net.WebClient
$client.Headers.Add([System.Net.HttpRequestHeader]::Cookie, "XAM_AUTH=$authCookie");
try
{
$client.DownloadFile($source, $destination);
}
catch
{
# The error message will be on one of these lines hopefully:
write-error "Failed to download! Errors are below:";
write-error $_
write-error $_.Exception
write-error $_.Exception.InnerException
write-error $_.Exception.InnerException.InnerException
exit 1;
}
if (!(test-path $destination))
{
write-error "$destination doesn't exist - the download must have failed!";
exit 1;
}
echo "Decompressing $source to $componentDirectory"
[System.IO.Compression.ZipFile]::ExtractToDirectory($destination, $componentDirectory)
echo ""
}
echo "Done!";
The -authCookie parameter can be extracted from either the XAM_AUTH cookie in your browser or from the .xamarin-credentials "cookiejar" in your home directory. It's nice to have it parameterised like this so you can store it as a secret variable in TeamCity.
The componentDirectory parameter must be the full path to the component directory - it will be created if it doesn't exist.
The project parameter should be the path to your project that you want to restore packages for - if you have multiple projects that need this then you'll have to execute the script for each one. Don't specify your solution as it won't work.
Unfortunately, this isn't very resilient to Xamarin's whims - a simple API change could render this useless, so obviously the best solution is to wait for Xamarin to fix this. I e-mailed Xamarin support to complain about this problem but I don't imagine I'll get a timely response (they seem very very busy these days). I hope this is useful!
Create directory and put that directory path in environment variable XAMARIN_CACHEPATH

WiX can'f find my file : unable to load file, error LGHT0103

I am using WiX 3.5 and making an installer. I have used heat.exe to bundle all the files.
It produced a WiX file. I referred in main wxs files as componentgroup ref. When I build my installer, it throws the following exception.
light.exe : error LGHT0103 : The system cannot find the file
'..........\target\tmp-release\jboss-eap-5.0\jboss-as\server\all\deploy\httpha-invoker.sar\invoker.war\WEB-INF\classes\org\jboss\invocation\http\servlet\ReadOnlyAccessFilter.class'
with type ''.
It is able load many files from this location, except the above file, even though the file is present.
Looks like you've hit the linker bug. As far as I can see, it was already reported to the WiX team, and was scheduled for v4.0. The comment to the issue states the path is more than 255 characters, so a possible workaround for you is to re-work the files/folders layout to avoid the paths of that length.
Hope this helps.
The answer of Ravz1234 works ! I used it with a environment variable e.g. env.SourcePath.
1) Set an environment variable to show on your Source Dir e.g. C:\SourceDir
2) On heat.exe add the argument -var env.SourcePath along with the other arguments
I used the variable for the directory, sys.SOURCEFILEDIR, and it worked well.

Path Error running CakePHP's "cake" console utility in Windows

A while ago when I started with Cake, I managed to get the console running in my Windows environment, and I have no idea how. I'm now having problems to make it work again in another computer.
This is what I've done in the new machine:
Downloaded my Cake code from source control (so all the files are exactly the same as the computer where it worked, including the configuration files)
Added PHP and "c:\my_cake_path\cake\console" to the path
If I run "cake OneOfMyShells", either standing on the /app, or in /cake/console directories, I get the following error:
Warning: get_object_vars() expects parameter 1 to be object, null given in C:\my_cake_path\cake\libs\model\connection_manager.php on line 199
Error: Missing Database Connection. Try 'cake bake'
"cake Bake", if run normally, when I try to get it to do the DB config ends up throwing another error (which is not that relevant to this)
However, if I run: cake bake -app "c:\my_cake_path\app"
Then bake works, I can do the database config, and it writes the DB config file (which is useless at this point, since I already had one)
Then, of course: cake OneOfMyShells -app "c:\my_cake_path\app"
does work perfectly well.
So, everything's working fine, I just need to manually specify the path to "app" every single time, which is very annoying.
How can I get around this? Where is Cake looking for to find the path to app?
Thanks!
Daniel
Not much of a difference in the sense you still need to type but you can run cake from the app dir like this: C:\XXX\project\app> ..\cake\console\cake.bat
To make it smaller you can put that line on a .bat or just add the \cake\console dir the windows path

Resources