Jenkins build blocks because of a windows form - c#

We have a .net application where it checks whether the build is on release mode and open up a simple windows form to input the version as a pre build event. I made this form to automatically close in 10 seconds if the user does not give an input. But unfortunately, in Jenkins, the build gets stuck on this step without going forward. So my guess was since Jenkins runs on command line it waits until the user input for continue. But even when I add automatically close the form it does not continue. Is there a way to build this job without UI blocking Jenkins?

You are not using Jenkins in the optimal way. Here are a few tips to help you out:
Get rid of your windows form to increment version
Add a CommonAssemblyInfo.cs in your visual studio solution with an initial version number
Force Jenkins to increment the version automatically [described below]
Commit the file by jenkins using git publisher or using svn.exe with commit flag
Reading Version number using powershell:
param([string]$assemblyInfoPath, [string]$workSpace)
$contents = [System.IO.File]::ReadAllText($assemblyInfoPath)
$versionString = [RegEx]::Match($contents,"(AssemblyFileVersion\("")(?:\d+\.\d+\.\d+\.\d+)(""\))")
Write-Host ("AssemblyFileVersion: " +$versionString)
$version = gc $assemblyInfoPath | select-string -pattern "AssemblyVersion"
$version -match '^\[assembly: AssemblyVersion\(\"(?<major>[0-9]+)\.(?<minor>[0-9]+)\.(?<revision>[0-9]+)\.(?<build>[0-9]+)\"\)\]'
$BuildVersionNumber = $matches["major"]+"."+$matches["minor"]+"."+$matches["revision"]+"."+$matches["build"]
Write-Host ("WorkSpace: " + $env:WORKSPACE.ToString()+"\version.txt")
#[Environment]::SetEnvironmentVariable("BUILD_NUMBER", $BuildVersionNumber, "Machine")
$path = $env:WORKSPACE.ToString() + "\version.txt"
$BuildVersionNumber | out-file -encoding ASCII -filepath $path
Increment Version using powershell:
#
# This script will increment the build number in an AssemblyInfo.cs file
#
param([string]$assemblyInfoPath, [string]$workSpace)
$contents = [System.IO.File]::ReadAllText($assemblyInfoPath)
$versionString = [RegEx]::Match($contents,"(AssemblyFileVersion\("")(?:\d+\.\d+\.\d+\.\d+)(""\))")
Write-Host ("AssemblyFileVersion: " +$versionString)
#Parse out the current build number from the AssemblyFileVersion
$currentBuild = [RegEx]::Match($versionString,"(\.)(\d+)(""\))").Groups[2]
Write-Host ("Current Build: " + $currentBuild.Value)
#Increment the build number
$newBuild= [int]$currentBuild.Value + 1
Write-Host ("New Build: " + $newBuild)
#update AssemblyFileVersion and AssemblyVersion, then write to file
Write-Host ("Setting version in assembly info file ")
$contents = [RegEx]::Replace($contents, "(AssemblyVersion\(""\d+\.\d+\.\d+\.)(?:\d+)(""\))", ("`${1}" + $newBuild.ToString() + "`${2}"))
$contents = [RegEx]::Replace($contents, "(AssemblyFileVersion\(""\d+\.\d+\.\d+\.)(?:\d+)(""\))", ("`${1}" + $newBuild.ToString() + "`${2}"))
[System.IO.File]::WriteAllText($assemblyInfoPath, $contents)
$version = gc $assemblyInfoPath | select-string -pattern "AssemblyVersion"
$version -match '^\[assembly: AssemblyVersion\(\"(?<major>[0-9]+)\.(?<minor>[0-9]+)\.(?<revision>[0-9]+)\.(?<build>[0-9]+)\"\)\]'
$BuildVersionNumber = $matches["major"]+"."+$matches["minor"]+"."+$matches["revision"]+"."+$matches["build"]
Write-Host ("WorkSpace: " + $env:WORKSPACE.ToString()+"\version.txt")
#[Environment]::SetEnvironmentVariable("BUILD_NUMBER", $BuildVersionNumber, "Machine")
$path = $env:WORKSPACE.ToString() + "\version.txt"
$BuildVersionNumber | out-file -encoding ASCII -filepath $path
Usage in Jenkins:
Version Format in CommonAssembly: 1.0.0.0
After incrementing: 1.0.0.1

As Tom mentioned in the comments, you should look add the option to start your forms application with a parameter that indicates that the main form should not be shown and some magic should happen. For example, check for a "/s" and let the application run silently if it is present:
MyWinformsApplication.exe /s
Also, as Tom mentioned, a console application can still open a window and this is really useful to have in Jenkins as you can then write insightful messages to the console which will be logged by Jenkins. You can always use these at a later stage to check if something went wrong.
As an additional note - if you add Console.WriteLine() to your WinForms application, Jenkins will pick the string up and add it to the console log.

Related

Get git result from commad using powershell and pipeline in c#

Hi I am trying to create some sort of hybrid using power shell and c# as managing tool, so simple script in powershell that checks repo status
$git_status = git status
Write-Output $git_status
Now using Pipeline and Run
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(powershellScript);
pipeline.Commands.Add("Out-String");
Collection<PSObject> results = pipeline.Invoke();
runspace.Close();
StringBuilder output = new StringBuilder();
foreach (PSObject obj in results)
{
output.AppendLine(obj.ToString());
}
return output.ToString();
}
But I am getting empty result, when I run script in IDE power shell result looks like for example:
Write-Host "$git_status"
On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed:
(use "git reset HEAD ..." to unstage) modified: DeviceDatabase/Platforms.xml
What can i do to get that response back to c# procedure?
Write-Host will only print output to terminal, but it will not pass it to stdout. If you want to get the output - use Write-Output.
Write-Host is there to build UX: change output text color, etc. For anything else use Write-Output if you want to have your scripts as tools that can be combined to solve larger problems.
You can find a better explanation here. I'll use example code from the link to expand a little:
function Receive-Output
{
process
{
# catch input from pipe and print it in green
Write-Host $_ -ForegroundColor Green
}
}
# this will print green text, because it was passed to Receive-Output
Write-Output "this is a test" | Receive-Output
# this will print white text, because it was not passed to Receive-Output
# there's a good chance "this is a test" will already be printed by the time Receive-Output gets called
Write-Host "this is a test" | Receive-Output
Edit:
As git status prints a colorful text we can safely assume it's using Write-Host in PowerShell. Based on how Posh-Git reads git status into an object I've compiled a little example code that should solve your problem:
> $status = (git -c color.status=false status)
> Write-Output $status
This is the output I get (Windows 10, PowerShell Core 6.0):

How to update url stored in Sharepoint add-in app file?

I created an High-Trust add-in for SharePoint 2013 with custom ribbon action and custom menu action.
For this, I have an ASP.NET MVC WebSite with the methods in the controller which match with the virtual urls put as custom action url. So, in the different elements.xml files, I filled action urls using the token 'remoteUrl', so no problem with the mapping.
When i create a package with VS2013, I write the url of my website which is on VM reachable from SP Server, and the client ID (I got from SP while registring my app). When I click on 'Finish', VS2013 generates a file '.app' which can be imported in SP online store or SP internal store.
Here is my problem, if I need to change the address of my website (which is stored in the app file, VS2013 just replaces the token 'RemoteUrl' with the url I give to it), is there any clean way to update the app file or may be if possible, directly the app stored in the SP application store (local to the server) ?
I found nothing for this problem. I saw few things about updating app with events and web services, but I didn't understood.
[EDIT] : I didn't understood that I have to change app version each time I need to update it that's why It didn't worked. Also, it seems that there is no other way to update the url in app file than modifying the AppManifest.xml in app file (which is a zip).
In one of my projects we used to do it with the following PowerShell script. It extracted the app file (it's just a ZIP) and modified multiple nodes in the manifest XML.
For packaging it uses a local copy of 7zip.
function ModifyAppPackage($appPackagePath, $applicationUrl, $clientId){
[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem");
$item = get-item $appPackagePath;
$zipFilePath = Join-Path $item.Directory.FullName $($item.BaseName + ".zip");
Copy-Item $item $zipFilePath;
$unzipDirectory = Join-Path $PSScriptRoot "\Temp";
New-Item -ItemType Directory -Force -Path $unzipDirectory;
if (Test-Path -Path $unzipDirectory\*)
{
Remove-Item $unzipDirectory\* -Force -Confirm:$false -Recurse:$true;
}
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipFilePath, $unzipDirectory);
$modifiedFile = Join-Path $unzipDirectory "modified.txt"
if (Test-Path -Path $modifiedFile)
{
$modifiedContent = Get-Content $modifiedFile
if ($modifiedContent -eq $applicationUrl)
{
Remove-Item $unzipDirectory -Confirm:$false -Recurse:$true;
Remove-Item $zipFilePath;
return;
}
Remove-Item $modifiedFile;
}
$modifiedFileContent = $applicationUrl;
$modifiedFileContent >> $modifiedFile;
$manifestFileName = "AppManifest.xml";
$manifestFilePath = Join-Path $unzipDirectory $manifestFileName;
$manifestXml = [xml](get-content $manifestFilePath);
$nameSpaceManager = New-Object System.Xml.XmlNamespaceManager($manifestXml.NameTable);
$nameSpaceManager.AddNamespace("ns", $manifestXml.DocumentElement.NamespaceURI);
$startPageElement = $manifestXml.SelectSingleNode("/ns:App/ns:Properties/ns:StartPage", $nameSpaceManager);
$StartPage = $applicationUrl + "?{StandardTokens}"
$startPageElement.'#text' = $StartPage
$InstalledEventEndpointElement = $manifestXml.SelectSingleNode("/ns:App/ns:Properties/ns:InstalledEventEndpoint", $nameSpaceManager);
$InstalledEventEndpoint = $applicationUrl + "/Services/AppEventReceiver.svc"
$InstalledEventEndpointElement.'#text' = $InstalledEventEndpoint
$clientIdElement = $manifestXml.SelectSingleNode("/ns:App/ns:AppPrincipal/ns:RemoteWebApplication", $nameSpaceManager);
$clientIdElement.ClientId = $clientId;
$manifestXml.Save($manifestFilePath);
if (Test-Path -Path $zipFilePath)
{
Remove-Item $zipFilePath;
}
$pathToZipExe = $("$PSScriptRoot\7za.exe");
[Array]$arguments = "a", "-tzip", "$zipFilePath", "$unzipDirectory\*.*", "-r";
& $pathToZipExe $arguments;
# Cleanup
Remove-Item $unzipDirectory -Confirm:$false -Recurse:$true;
Remove-Item $appPackagePath -Confirm:$false;
# Rename new zip to .app
Rename-Item $zipFilePath $appPackagePath -Force -Confirm:$false;
return $true;
}
I think it would be possible to store the url in one of custom list in the app. Refer the url from the list. Whenever you need to change the url it can be done from the app itself.

Parse into Website

I have a file (text or csv) that I generate that has a list of part numbers. I need to take this list, and download some spec sheets for these parts automatically and then print. Once on the website, I need to input the part number, then print the results. What's the best way to do this?
Okay everyone, here's what I was doing before, but it would take over an hour to process on a progress 4gl (version 9.1) database into a QAD environment v8.6e on a Unix Red-Hat server:
FNAME=`date +%y%m%d%H%M%S`
echo requiredmcpartno=$1 | lynx -accept_all_cookies -nolist -dump -post_data 75.144.##.###/specdata/specdata.asp 2>&1 | tee $FNAME | lp -d$2 >>/apps/proedi/####/ftp/log/brownart.log
grep "Unit of Issue" $FNAME | cut --delimiter=: --fields=2 | awk '{print $1}'
grep -q "PACKAGING SPEC IS OBSOLETE FOR THIS PART NUMBER" "$FNAME"
if [ $? -eq 0 ]; then
echo 0
echo nopic
exit
fi
cd /apps/proedi/####/ftp/ftpscripts
rm -fr 184.168.##.###/ 75.144.##.###/ www.google-analytics.com/ 2>&1 >>/apps/proedi/####/ftp/log/brownart.log
wget -p -m -k -K -E -H --cookies=on --post-data="requiredmcpartno=$1" 75.144.##.###/specdata/specdata.asp >/dev/null 2>&1
/apps/proedi/####/ftp/ftpscripts/printspec.sh $1 $2 >>/tmp/printspec.log 2>&1
cat /apps/proedi/####/ftp/ftpscripts/"$1".pt
rm -f /apps/proedi/####/ftp/ftpscripts/"$1".pt
>>/apps/proedi/####/ftp/log/brownart.log
rm $FNAME 2>&1 >>/apps/proedi/ford/ftp/log/brownart.log
Then printspec.sh script:
file=184.168.70.174/partandpackagingphotos/PhotoDetailsSpecdata.aspx\?p\=$1.html
if [ ! -f "$file" ]; then
echo nopic >/apps/proedi/ford/ftp/ftpscripts/"$1".pt
exit
fi
grep -q "No Pictures Available for this Part Number" "$file"
if [ $? -eq 0 ]; then
echo nopic >/apps/proedi/ford/ftp/ftpscripts/"$1".pt
exit
fi
html2ps -i .7 184.168.70.174/partandpackagingphotos/PhotoDetailsSpecdata.aspx\?p\=$1.html | lp d$2 -s
echo picfnd >/apps/proedi/ford/ftp/ftpscripts/"$1".pt
The wget command takes way to long to process in Unix. Our customer may send us a conveyance file with 150-200 parts 8-9 times a day, and we need to download all of the pictures associated with each part every time we receive parts.
I was thinking of just making a flat file(text or csv), then have the user run a batch file on their windows computer to connect to the unix server, and download the file to their computer. After this, then have either the same batch job, or an excel template or something on the windows side download the pictures and print the spec sheets to their default printer.
Sorry for not posting all of this initially.
The first thing that I would try is to break the process into two or more independent pieces and run them in parallel. The scripts above appear to take a part number as a parameter. I would guess that whatever is feeding them the part number is working from a list (the "conveyance file"?) That list would be the obvious place to make the split.
If you do it in such a way that the number of concurrent processes is configurable it should be simple to find the "sweet spot". Supposing that the list of parts to be downloaded is in a table called "part" with fields "needsDownload" and "partNum". For the sake of simplicity we will assume that partNum is an integer and that the actual part numbers needing download are randomly distributed. If you are driving this process with Progress 4GL code you might write a control program something like this:
/* control.p
*
* to run two "threads":
*
* _progres -b dbName -p control.p -param "1,2" > control.1.log 2>&1 & # 1 of 2
* _progres -b dbName -p control.p -param "2,2" > control.2.log 2>&1 & # 2 of 2
*
*
*/
define variable myThread as integer no-undo.
define variable numThreads as integer no-undo.
myThread = integer( entry( 1, session:parameter )) - 1. /* this just allows the "1 of 2" stuff to be more "human sensible" */
numThreads = integer( entry( 2, session:parameter )).
for each part exclusive-lock where needsDownload = true and (( partNum modulo numThreads ) = myThread ):
os-command value( "getpart.sh " + string( partNum )).
needsDownload = false.
end.
Of course the problem might be that the external system is too slow. No amount of programming on your end will fix that.

Powershell change taskbar icon of running console application

I'm using code from this post over at Microsoft's TechNet to change the icon of my running PowerShell application. This works great for the icon that is displayed in the Powershell window itself, but it doesn't change the Taskbar's icon. I changed the function a bit an hoped that it would also change the icon displayed in the Taskbar.
# Set the icon of the current console window to the specified icon.
#
# AUTHOR: Aaron Lerch <http://www.aaronlerch.com/blog>
# COPYRIGHT: © 2009 Aaron Lerch
# LINK: http://gallery.technet.microsoft.com/scriptcenter/9d476461-899f-4c98-9d63-03b99596c2c3
#
# PARAM:
# -IconFile
# Absolute path to the icon file.
# RETURN:
# $null
function Set-ConsoleIcon {
Param(
[parameter(Mandatory = $true)] [string] $IconFile
)
[System.Reflection.Assembly]::LoadWithPartialName('System.Drawing') | Out-Null
# Verify the file exists
if ([System.IO.File]::Exists($iconFile) -eq $true) {
$ch = Invoke-Win32 'kernel32' ([IntPtr]) 'GetConsoleWindow'
$i = 0;
$size = 16;
while ($i -ne 4) {
$ico = New-Object System.Drawing.Icon($iconFile, $size, $size)
if ($ico -ne $null) {
Send-Message $ch 0x80 $i $ico.Handle | Out-Null
}
if ($i -eq 4) {
break
}
$i += 1
$size += 16
}
}
else {
Write-Host 'Icon file not found' -ForegroundColor 'Red'
}
}
I'm providing the icon in the sizes 16 (wParam 1), 32 (wParam 2), 48 (wParam 3), and 64 (wParam 4).
I also tried to change the Icon from my launching C# application (based on this Stackoverflow discussion) but that didn't work at all.
If you'd like to see the complete code have a look at the following:
the C# class that starts the Powershell process
the Powershell PS1 script
This might not be possible. Here are more details about the "group icon" in the taskbar:
Change icon of group in taskbar (Win7)
Update:
You can change the application ID of your window. Since the icon primarily comes from the application ID, by changing it Explorer doesn't know the default icon anymore and will use the actual window icon. This also ungroups the window from other CMD windows to make the individual icon visible at all. (There's a taskbar animation like for closed/new windows when you do this in an existing console window.) There's an MSDN article, look for "application ID" in it:
https://msdn.microsoft.com/en-us/magazine/dd942846.aspx
Here's the relevant code from it (C++):
#define WINVER 0x601
#define _WIN32_WINNT 0x601
#include <Propvarutil.h>
#include <propkey.h>
#include <Shellapi.h>
PROPVARIANT pv;
InitPropVariantFromString(L"MyAppID", &pv);
IPropertyStore* pps;
VERIFY(SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&pps)));
VERIFY(pps->SetValue(PKEY_AppUserModel_ID, pv));
VERIFY(pps->Commit());
(Linked libs: shlwapi.lib)
The Windows API Code Pack should also have managed wrapper code for this. Didn't look it up because I currently use this function in a C++ application. But I found other questions about it here.
For your PowerShell script that probably won't help much either. Since it's all native code wrapped with more complex managed code, I think your best bet would be a little native helper tool. I am currently integrating this function into my FlashConsoleWindow tool that can do some more things to console windows like flashing or displaying a taskbar progress state.
An easy alternative is to create a shortcut to the powershell exe. Change the icon of the shortcut to whatever you want.
Then whenever you call your script, use the shortcut instead of the PS exe. So instead of
powershell.exe -ExecutionPolicy Bypass -File D:\scripts\whatever.ps1
Use
D:\scripts\powershell.lnk -ExecutionPolicy Bypass -File D:\scripts\whatever.ps1
The shortcut powershell.lnk can be "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" or just powershell.exe without the full path (as long as PATH var is set properly for PS on the system)
You can put the PS shortcut anywhere really, but I would recommend you put it with the script for portability.
Now when you launch the script via the shortcut, the taskbar icon will be whatever you defined it as via the shortcut file.
The only caveat is that your window settings in the shortcut will override the PS window, so you should define how you want it to look in the shortcut properties.

Invoking Exchange Management Shell from C#

I'm currently using .NET 3.5 / C# to develop a Windows service that performs automated Exchange operations. This service basically watches a SQL database for operations to perform then spawns PowerShell and redirects the output so that results can be monitored from a UI residing elsewhere. Below is the code I'm using to invoke the process...
Action<object, DataReceivedEventArgs> DataReceived = (sender, data) =>
{
// Log data in SQL
};
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "powershell.exe"
p.StartInfo.Arguments = arguments;
// Arguments are (they're coming from SQL, didn't feel like escaping everything just for this example)
// -command ". 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto; Get-Mailbox –ResultSize unlimited | Search-Mailbox -SearchQuery ... stuff ...
p.StartInfo.LoadUserProfile = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.OutputDataReceived += new DataReceivedEventHandler(DataReceived);
p.Start();
This code can do things like run ping, tracert, nslookup, echo, dir, and all of the usual command-line suspects with behavior identical to as if I typed it into a command prompt. For instance, I could copy-paste the above into the Run box and it would work flawlessly. Whenever I try to run it as above, however, I receive the following:
Get-ItemProperty : Cannot find path 'HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup' because it does not exist.
At C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1:46 char:34
+ $global:exbin = (get-itemproperty <<<< HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup).MsiInstallPath + "bin\"
+ CategoryInfo : ObjectNotFound: (HKLM:\SOFTWARE\...erver\v14\Setup:String) [Get-ItemProperty], ItemNotFo
undException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemPropertyCommand
Get-ItemProperty : Cannot find path 'HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup' because it does not exist.
At C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1:47 char:38
+ $global:exinstall = (get-itemproperty <<<< HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup).MsiInstallPath
+ CategoryInfo : ObjectNotFound: (HKLM:\SOFTWARE\...erver\v14\Setup:String) [Get-ItemProperty], ItemNotFo
undException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemPropertyCommand
Get-ItemProperty : Cannot find path 'HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup' because it does not exist.
At C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1:48 char:38
+ $global:exscripts = (get-itemproperty <<<< HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup).MsiInstallPath + "scri
pts\"
+ CategoryInfo : ObjectNotFound: (HKLM:\SOFTWARE\...erver\v14\Setup:String) [Get-ItemProperty], ItemNotFo
undException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemPropertyCommand
The term 'bin\CommonConnectFunctions.ps1' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1:52 char:2
+ . <<<< $global:exbin"CommonConnectFunctions.ps1"
+ CategoryInfo : ObjectNotFound: (bin\CommonConnectFunctions.ps1:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
A whole slew of other errors follows after this, but from going over the RemoteExchange PowerShell script I've determined that it all comes down to those first three errors: not being able to read from the registry. Does anyone have any idea as to why this might be happening?
Things I've tried to get this to work:
Running this code in a console app as opposed to a service context.
Every time I've run it I've done so as a domain and Exchange admin and I never got an UAC prompts, so I doubt the issue is one of credentials
Checked registry keys... The HKLM key it's looking at also has full read permissions granted to everbody
I've enabled unsigned PowerShell script execution on the server
Putting the command into a PowerShell script and invoking that programmatically
Hardcoding the registry keys' values into the PowerShell script (which just gives me another set of registry read errors further down the line)
Using ShellExecute on the process (this can't be done with output redirection, which I require)
Explicitly setting environment variables on the StartInfo to match the ones in the spawning environment
To anyone that can give me a hand... thanks a billion!
***EDIT: Perhaps I should clarify the hardcoding bit. I already cracked open RemoteExchange.ps1 and set the variables that are erroring out to their correct values (as opposed to using GetProperty or whatever) and I get marginally farther:
Exception calling "TryLoadExchangeTypes" with "2" argument(s): "Unable to determine the installed file version from the
registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ExchangeServer\v14\Setup'."
At C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1:79 char:92
+ $typeLoadResult = [Microsoft.Exchange.Configuration.Tasks.TaskHelper]::TryLoadExchangeTypes <<<< ($ManagementPath, $t
ypeListToCheck)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
From what I'm surmising from looking at like 79 this isn't something I can change. It's trying to load types from a library and to do that it needs to look at the registry still, so I can't just fix a variable.
Just try to compile your program in x64.
I know it is weird but, in x86 managed powershell, some cmdlets can't see registry keys form x64 programs.
(I got the clue from: "One of these things is not like the other | Home Of The Scary DBA" : http://www.scarydba.com/2010/06/30/one-of-these-things-is-not-like-the-other/)
You can open the Exchange.ps1 that resides in \bin, and edit the variables that appear under
## EXCHANGE VARIABLEs ########################################################
Change $global:exbin, $global:exinstall, and $global:exscripts to be hard coded paths to
"C:\Program Files\Microsoft\Exchange Server\V14\bin\"
"C:\Program Files\Microsoft\Exchange Server\V14\"
"C:\Program Files\Microsoft\Exchange Server\V14\scripts\"
This is not an ideal solution, but the workaround should not impact anything else calling these variables.
Had the same problem and actually finally figured it out. My previous answer was completely wrong.
I answered it correctly here.

Categories

Resources