NuGet: Find and delete code using Powershell / uninstall.ps1 - powershell

I have a few NuGet packages that I've put together, with one of them being a common project referenced by all the others.
This common project inserts a configuration class into the App_Start folder, and a method on this class is then invoked by WebActivator.
For one of the other packages I wish to add one more line of code to this method and I achieve this using install.ps1 (using code from this SO post).
To be a diligent NuGet package developer, I should probably remove this line of code if the NuGet package is uninstalled.
To do this removal I've tried using the FindPattern method of the FileCodeModel to find the line of code, but haven't had any luck in getting it to work.
This is what I have so far:
$app_start = $project.ProjectItems.Item("App_Start")
$item = $app_start.ProjectItems.Item("my-config-file.cs")
$namespace = $item.FileCodeModel.CodeElements | ? {$_.Kind -eq 5}
$class = $namespace.Members.Item("My-Config-Class")
$method = $class.Members.Item("My-Method-Name")
$startPoint = $method.GetStartPoint([EnvDTE.vsCMPart]::vsCMPartBody)
$startPoint = $startPoint.CreateEditPoint()
$endPoint = $method.GetEndpoint([EnvDTE.vsCMPart]::vsCMPartBody)
$endPoint = $endpoint.CreateEditPoint()
$startPoint.FindPattern("known-line-of-code", [EnvDTE.vsCMPart]::vsFindOptionsFromStart, ref $endPoint)
Specifically, it's that last line, FindPattern, that I'm having trouble with. The docs list another optional parameter, and judging by Visual Studio's exception message...
Exception calling "FindPattern" with "3" argument(s): "Type mismatch.
...I guess I'm supposed to supply this parameter. But what do I supply it with?
And even if I could find the line of code, how do I then delete it?
Or is FindPattern the wrong way to proceed? Is there another way to remove a known line of code?

Related

TFS API: Clone Build Definition Environment

I want to clone an existing environment within a build definition.
This is possible through the TFS GUI, but it doesn't seem like the API natively supports it.
So far, I've tried the following (in PowerShell):
Download build definition and deserialize
[void][System.Reflection.Assembly]::LoadFile("$pwd\Newtonsoft.Json.dll")
$TargetDefinitionName = "Name"
$TargetDefinitionID = ($DefinitionsOverview | Where-Object { $_.name -eq $TargetDefinitionName } | Select-Object -First 1).id
$TargetDefinitionURL = "$TfsUri/$TargetDefinitionID"
$TargetDefinitionJSON = Invoke-WebRequest -Uri "$TargetDefinitionURL" -UseDefaultCredentials
$DeserializedBuildDefinition = [Newtonsoft.Json.JsonConvert]::DeserializeObject($TargetDefinitionJSON.Content)
$DeserializedBuildDefinition.ToString()
Duplicate JSON block that represents environment, change unique properties
$NewEnvironmentString = $DeserializedBuildDefinition.environments[4].ToString()
$DeserializedBuildDefinition.environments.Add(5)
$DeserializedBuildDefinition.environments[5] = $NewEnvironmentString
$DeserializedBuildDefinition.environments[5].name.value = "NewEnvironment"
$DeserializedBuildDefinition.environments[5].rank.value = "6"
$DeserializedBuildDefinition.environments[5].id.value = "1665"
$DeserializedBuildDefinition.revision.value = "20"
Serialize JSON and post back (with new environment)
$SerializedBuildDefinition = [Newtonsoft.Json.JsonConvert]::SerializeObject($DeserializedBuildDefinition)
$PostData = [System.Text.Encoding]::UTF8.GetBytes($SerializedBuildDefinition)
$Headers = #{ "Accept" = "api-version=2.0-preview" }
$Response = Invoke-WebRequest -UseDefaultCredentials -Uri
$TargetDefinitionURL -Headers $Headers `
-Method Put -Body $PostData -ContentType "application/json"
$Response.StatusDescription
PROBLEM: $Response.StatusDescription gives "OK," but no new environment appears in the build definition.
One thought is that, in addition to 'name,' 'ID,' and 'rank, there are other values that need to be unique per environment that I'm missing.
I've also tried cloning the environment manually, saving the JSON representation of the definition, deleting the environment, and posting the JSON back. The new environment still doesn't show up.
Any help would be appreciated.
Future: Yaml based build definitions as code are well on their way, at least to VSTS. This won't help an immediate need but probably offers a better and more lightweight future approach.
When you copy an environment, you need to change "id", "name", and "rank". And the “id” need to be changed to "0". Also, try to use api-version=2.3-preview.1.
Then use the api of update a release definition to update the definition:
PUT http://tfs2015:8080/tfs/teamprojectcollection/teamProject/_apis/release/definitions?api-version=2.3-preview.1
{
……
}
I have tested with TFS 2015 Update 4. Api could clone an environment successfully.
I created a tool for cloning TFS builds, as (with TFS 2015 update 1 at least) the web 'clone' function does not clone the 'Repository' or 'Triggers' tab. Some of our build steps were a little complicated so I also wrote some simple transforms to automatically set the values according to the target branch.
I used the BuildHttpClient object in Microsoft.TeamFoundation.Build2.WebApi assembly to get the original build definition (BuildDefinition object, using GetDefinitionAsync() method), transform any build steps values, then call CreateDefinitionAsync() on BuildHttpClient to create the new build.
Works very reliably and under the hood it appears to use the TFS REST API.
If there was any interest, I'd be happy to create a more in depth tutorial on this.

Cudafy chapter 3 example has path issue how to fix?

Using Cudafy version 1.29, which can be downloaded from here
I am executing the examples that are found in the install folder CudafyV1.29\CudafyByExample\
Specifically, "chapter 3" example that begins line 42 of program.cs calls the following:
simple_kernel.Execute();
which is this:
public static void Execute()
{
CudafyModule km = CudafyTranslator.Cudafy(); // <--exception thrown!
GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId);
gpu.LoadModule(km);
gpu.Launch().thekernel(); // or gpu.Launch(1, 1, "kernel");
Console.WriteLine("Hello, World!");
}
The indicated line throws this exception:
Compilation error: CUDAFYSOURCETEMP.cu
'C:\Program' is not recognized as an internal or external command,
operable program or batch file. .
Which is immediately obvious that the path has spaces and the programmer did not double quote or use ~ to make it operational.
So, I did not write this code. And I cannot step through the sealed code contained within CudafyModule km = CudafyTranslator.Cudafy();In fact I don't even know the full path that is causing the exception, it is cut-off in the exception message.
Does anyone have a suggestion for how to fix this issue?
Update #1: I discovered where CUDAFYSOURCETEMP.cu lives on my computer, here it is:
C:\Users\humphrt\Desktop\Active Projects\Visual Studio
Projects\CudafyV1.29\CudafyByExample\bin\Debug
...I'm still trying to determine what the program is looking for along the path to 'C:\Program~'.
I was able to apply a workaround to bypass this issue. The workaround is to reinstall all components of cudafy in to folders with paths with no ' ' (spaces). My setup looks like the below screenshot. Notice that I also installed the CUDA TOOLKIT from NVIDIA in the same folder - also with no spaces in folder names.
I created a folder named "C:\CUDA" and installed all components within it, here is the folder structure:

Calling Openoffice from Perl throws NoSuchElementexception

I try to convert odt-Files to doc-Files using OpenOffice. Installed Version is 3.1.1 and can't be changed at the moment. Perl Version is 5.18.
The Perl-module OpenOffice::UNO is used for this conversion. Unfortunately in newer Versions of OpenOffice/LibreOffice do not support Perl anymore.
The Script calls OpenOffice headless using xvfb.
Here is the code used:
`# Launch OpenOffice.org as a server
$ ooffice \
"-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"
use OpenOffice::UNO;
# connect to the OpenOffice.org server
$uno = OpenOffice::UNO->new;
$cxt = $uno->createInitialComponentContext('file:///.../path/perluno');
$sm = $cxt->getServiceManager;
$resolver = $sm->createInstanceWithContext
("com.sun.star.bridge.UnoUrlResolver", $cxt);
$rsm = $resolver->resolve
("uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager");
# get an instance of the Desktop service
$rc = $rsm->getPropertyValue("DefaultContext");
$desktop = $rsm->createInstanceWithContext("com.sun.star.frame.Desktop", $rc);
.....`
On the last included line to create $desktop i get following Error message:
terminate called after throwing an instance of 'com::sun::star::container::NoSuchElementException'
Is there any way to fix this problem? Tried to understand the Code of the UNO-interface, especially UNO.xs but there has not been any information about the call "createInstanceWithContext".
Looking through the OpenOffice-documentation does not provide any information about this either.
It would also help just to get the complete java error message, to make sure what element is missing.
The file "perluno" has the content:
[Bootstrap]
UNO_TYPES=/usr/lib64/openoffice.org//program/types.rdb
UNO_SERVICES=/usr/lib64/openoffice.org//program/services.rdb

Failing to compile MonoGame on Boo compiler

SharpDevelop compiles fine, but trying to compile through booc doesn't work.
Boo Compiler version 0.9.4.9 (CLR 2.0.50727.8000)
Program.boo(4,8): BCE0021: Namespace 'Microsoft.Xna.Framework' not found, maybe
you forgot to add an assembly reference?
booc -resource:"C:\test\" Program.boo , the command used in Windows cmd tool.
Thank you. Alisa.
Sharpdevelop most likely already references the libraries to the compiler for you. What that means is, when you manually invoke the booc command line compiler, you will have to tell the compiler where exactly the MonoGame library is. I haven't been able to check myself yet, but I did have a quick look at the command lines and the Boo source code, and I think you have to do the following:
-lib:C:/Path/To/MonoGame/Libraries
This will tell the compiler where to look for additional libraries.
The next thing you should then do is add the libraries you want, eg:
-r:Microsoft.Xna.Framework.dll,Microsoft.Xna.Framework.Game.dll
Add these two additional compiler options to your command line and I think it should work.
I haven't compiled this myself really, because I found it rather tedious. Instead, I decided to create my own build script in Boo itself in order to compile my Boo programs. That way I still had to add the library path and reference the libraries, as in the following snippet:
def CompileEngine() as bool:
"""Compiles the engine and puts it in ./lib/SpectralEngine.dll"""
compiler = BooCompiler()
compiler.Parameters.Pipeline = CompileToFile()
compiler.Parameters.OutputType = CompilerOutputType.Library
compiler.Parameters.Ducky = true
compiler.Parameters.LibPaths.Add("./lib")
compiler.Parameters.OutputAssembly = "./lib/SpectralEngine.dll"
# Add libraries.
compiler.Parameters.References.Add(compiler.Parameters.LoadAssembly("OpenTK.dll"))
compiler.Parameters.References.Add(compiler.Parameters.LoadAssembly("NAudio.dll"))
compiler.Parameters.References.Add(compiler.Parameters.LoadAssembly("Boo.Lang.dll"))
compiler.Parameters.References.Add(compiler.Parameters.LoadAssembly("Boo.Lang.Parser.dll"))
compiler.Parameters.References.Add(compiler.Parameters.LoadAssembly("Boo.Lang.Compiler.dll"))
# Take all boo files from the Engine source directory.
files = (Directory.GetFiles(Directory.GetCurrentDirectory() + """/src/Engine""", "*.boo", SearchOption.AllDirectories)
.Where({file as string | return not file.Contains("Gwen")})) # Filter out old GWEN files.
for file in files:
print "Adding file: " + file
compiler.Parameters.Input.Add(FileInput(file))
print "Compiling to ./lib/SpectralEngine.dll"
context = compiler.Run()
if context.GeneratedAssembly is null:
print "Failed to compile:\n" + join(e for e in context.Errors, "\n")
return false
else:
return true
I've put two of these build scripts at here and here. It's perhaps a bit overkill for you, though.

From Msi , how to get the list of files packed in each feature?

We have used wix to create Msi. Each Msi will be having 1 or 2 or 3 features such as Appserver feature, Webserver feature and DB server feature.
Now i was asked to get the list of config files presented in each feature.
It is tough to find the list of web.config files associated with each feature through wxs file.
Is it possible find the list of files associated with a feature with particular search pattern?
For ex. Find all the web.config files packed in Appserver feature.
Is there any way easy way ( querying or some other automated script such as powershell) to get the list?
Wix comes with a .NET SDK referred to as the DTF ("deployment tools foundation"). It wraps the windows msi.dll among other things. You can find these .NET Microsoft.Deployment.*.dll assemblies in the SDK subdirectory of the Wix Toolset installation directory. The documentation is in dtf.chm and dtfapi.chm in the doc subdirectory.
As shown in the documentation, you can use this SDK to write code which queries the msi database with SQL. You will be interested in the Feature, FeatureComponents and File tables.
If you haven't explored the internals of an MSI before, you can open it with orca to get a feel for it.
You can do it by making slight modifications to the Get-MsiProperties function described in this PowerShell article.
Please read the original article and create the prescribed comObject.types.ps1xml file.
function global:Get-MsiFeatures {
PARAM (
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,HelpMessage="MSI Database Filename",ValueFromPipeline=$true)]
[Alias("Filename","Path","Database","Msi")]
$msiDbName
)
# A quick check to see if the file exist
if(!(Test-Path $msiDbName)){
throw "Could not find " + $msiDbName
}
# Create an empty hashtable to store properties in
$msiFeatures = #{}
# Creating WI object and load MSI database
$wiObject = New-Object -com WindowsInstaller.Installer
$wiDatabase = $wiObject.InvokeMethod("OpenDatabase", (Resolve-Path $msiDbName).Path, 0)
# Open the Property-view
$view = $wiDatabase.InvokeMethod("OpenView", "SELECT * FROM Feature")
$view.InvokeMethod("Execute")
# Loop thru the table
$r = $view.InvokeMethod("Fetch")
while($r -ne $null) {
# Add property and value to hash table
$msiFeatures[$r.InvokeParamProperty("StringData",1)] = $r.InvokeParamProperty("StringData",2)
# Fetch the next row
$r = $view.InvokeMethod("Fetch")
}
$view.InvokeMethod("Close")
# Return the hash table
return $msiFeatures
}