NuGet Uninstall.ps1 - remove a project reference - powershell

So in my Install.ps1 I can add a reference like this:
param($installPath, $toolsPath, $package, $project)
$project.Object.References.Add("YourDLL")
How do you remove a project reference in PowerShell?

Here's what we use for Machine.Specifications:
param($installPath, $toolsPath, $package, $project)
$project.Object.References | Where-Object { $_.Name -eq 'Machine.Specifications.TDNetRunner' } | ForEach-Object { $_.Remove() }

There are some casting issues to do this in powershell.
this is the c# to remove a reference.
DTE dte = (DTE)dteObject;
var targetProject = (VSProject)dte.GetProject(target).Object;
var refToRemove = targetProject.References.Cast<Reference>().Where(assembly => assembly.Name.EndsWith(library, System.StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
if (refToRemove != null)
{
refToRemove.Remove();
}
If you want to use the Solution Factory nuget package you can use the powershell command that solution factory adds.
Remove-LibraryReference projectName system.web
Here is a link the the solution factory source http://solutionfactory.codeplex.com/SourceControl/network/Forks/erichexter/PowershellRewrite
Update: new url for solution factory:
https://github.com/erichexter/SolutionFactory

Related

Modify the .exe's AssemblyInfo using PowerShell in TFS 2018 build

I want to use PowerShell to update my application's Assembly info like Product Name, File Description in TFS vNext build. I want to use build variables in build definition and pass it to the script.
I have done the same to update version number with the help of this(https://writeabout.net/2015/11/01/set-assembly-and-app-version-to-a-matching-build-name-in-tfs-2015-or-vso-build-vnext/).
I need help with the script to replace "Product Name" or "Description" value with new value.
You can replace the name & description with a small script:
Param(
[string]$filePath,
[string]$newProductName,
[string]$newProductDesc
)
$patternProductName = '\[assembly: AssemblyProduct\("(.*)"\)\]'
$patternProductDesc = '\[assembly: AssemblyDescription\("(.*)"\)\]'
(Get-Content $filePath) | ForEach-Object{
if($_ -match $patternProductName){
'[assembly: AssemblyProduct("{0}")]' -f $newProductName
}
elseif($_ -match $patternProductDesc){
'[assembly: AssemblyDescription("{0}")]' -f $newProductDesc
}
else{
$_
}
} | Set-Content $filePath
Now during the build call this script and in the arguments send the 3 args: AssmeblyInfo file path, your new product name and your new product description.

How to create nested Solution Folders with envdte

I've tried to create a visual studio solution with nested solution folders through Powershell (envdte). Everything works up to 1 level deep, but nesting a solution folder doesn't seem to work (interface is null). The issue is described in this SO question:
Creating a tree of Solution Folders using DTE and Package Manager Console
Unfortunately that question hasn't been answered yet. I've reachted out to the poster of that question but he had taken another route within his solution so the question is still open.
An excerpt of my code. The Find-Solution method finds the solutionfolder I'm looking for within the given context (= startfolder). When found, it returns this item:
function Find-SolutionFolder {
Param($SearchedFolderName, $StartFolder)
Write-Output "number " $StartFolder.ProjectItems.Count
For ($i = 1; $i -le $StartFolder.ProjectItems.Count; $i++) {
$Item = $StartFolder.ProjectItems.Item($i)
if ($Null -Eq $Item.Object) {
continue;
}
if ($Item.Object.Kind -eq [EnvDTE80.ProjectKinds]::vsProjectKindSolutionFolder) {
if ($Item.Name -Eq $SearchedFolderName) {
return $Item
}
Find-SolutionFolder $SearchedFolderName $Item
}
}
}
The Add-Projects method takes care of saving the structure to the solution. The structure is:
Solution
ModuleTypeFolder (ie. Foundation)
ModuleGroupFolder (optional)
Folder for project
projectfiles
This is a nested structure. Everything works without the ModuleGroupFolder but when the structure has the ModuleGroupFolder it causes the error due to the null result of the Get-Interface. I've confirmed that the correct solution folder is found. It's just the variable $moduleGroupNameFolderInterface is null.
The parameter modulePath is the path on disk
function Add-Projects {
Param(
[Parameter(Position = 0, Mandatory = $True)]
[string]$ModulePath
)
Write-Output "Adding project(s)..."
# For the sake of the example always use a folder named 'Foundation'
$moduleTypeFolder = Get-FoundationSolutionFolder
# When the literal 'Foundation' solution folder does not exist in the solution it will be created.
if (-Not $moduleTypeFolder) {
$dte.Solution.AddSolutionFolder($config.ModuleType)
$moduleTypeFolder = Get-ModuleTypeSolutionFolder
}
$moduleTypeFolderInterface = Get-Interface $moduleTypeFolder.Object ([EnvDTE80.SolutionFolder])
# Add ModuleGroup Folder if needed
if (-Not [string]::IsNullOrWhiteSpace($config.ModuleGroupName)) {
$moduleGroupNameFolder = Find-SolutionFolder $config.ModuleGroupName $moduleTypeFolder
if (-Not $moduleGroupNameFolder) {
$moduleTypeFolderInterface.AddSolutionFolder($config.ModuleGroupName)
$moduleGroupNameFolder = Find-SolutionFolder $config.ModuleGroupName $moduleTypeFolder
}
$moduleGroupNameFolderInterface = Get-Interface $moduleGroupNameFolder.Object ([EnvDTE80.SolutionFolder])
if ($Null -eq $moduleGroupNameFolderInterface) {
Write-Output "moduleGroupNameFolderInterface is null; this is wrong"
} else {
$moduleNameFolder = $moduleGroupNameFolderInterface.AddSolutionFolder($config.ModuleName)
$moduleNameFolderInterface = Get-Interface $moduleNameFolder.SubProject ([EnvDTE80.SolutionFolder])
# Search in the new module folder for csproj files and add those to the solution.
Get-ChildItem -File -Path $ModulePath -Filter "*$csprojExtension" -Recurse | ForEach-Object { $moduleNameFolderInterface.AddFromFile("$($_.FullName)")}
}
} else {
$moduleNameFolder = $moduleTypeFolderInterface.AddSolutionFolder($config.ModuleName)
$moduleNameFolderInterface = Get-Interface $moduleNameFolder.Object ([EnvDTE80.SolutionFolder])
# Search in the new module folder for csproj files and add those to the solution.
Get-ChildItem -File -Path $ModulePath -Filter "*$csprojExtension" -Recurse | ForEach-Object { $moduleNameFolderInterface.AddFromFile("$($_.FullName)")}
}
Write-Output "Saving solution..."
$dte.Solution.SaveAs($dte.Solution.FullName)
}
Note. the example is not optimized (ie. duplicate code)
Can anybody help me solve the issue.
Update - answer to question
I finally figured it out. Apparently when finding a nested solution folder where property Kind has guid {66A26722-8FB5-11D2-AA7E-00C04F688DDE} it's not the correct object yet. You have to use the object within the found item.
So basically you are looking for recursion. You can recurse like this.
For the solutions folder:
function RecurseSolutionFolderProjects(){
param($solutionFolder = $(throw "Please specify a solutionFolder"))
$projectList = #()
for($i = 1; $i -le $solutionFolder.ProjectItems.Count; $i++){
$subProject = $solutionFolder.ProjectItems.Item($i).subProject
if($subProject -eq $null){
continue;
}
if($subProject.Kind -eq [EnvDTE80.ProjectKinds]::vsProjectKindSolutionFolder)
{
$projectList += RecurseSolutionFolderProjects($subProject)
} else {
$projectList += $subProject
}
}
return $projectList
}
For Project Files:
function GetProjectFiles(){
param($project = $(throw "Please specify a project"))
write-debug ("getting project files for " + $project.Name + " "+ $project.ProjectName)
$projectItems = RecurseDescendants($project.ProjectItems)
return $projectItems | Where-Object {$_.Kind -ne [EnvDTE.Constants]::vsProjectItemKindPhysicalFolder}
}
For Project Items:
function GetProjectItems(){
param($project = $(throw "Please specify a project"))
if($project.ProjectItems.count -gt 0){
write-debug "getting project items for '$project.Name' '$project.ProjectName'"
}
#example: GetProjectItems((GetSolutionProjects).get_Item(1))
$result =RecurseDescendants($project.ProjectItems)
return $result
}
Refer the Solution Hierarchy answer where the above functions are neatly explained
You can get the latest version from this GitHub Link
Hope it helps.

Update project property with a powershell script

I want to create a nuget package which will run a Powershell script on restore in a C# project. The script will change the values of the project properties on the project e.g.:
Set value of
<AssemblyVersion>1.0.0.0</AssemblyVersion>
to
<AssemblyVersion>$(ReleaseApplicationVersion)</AssemblyVersion>
and some other properties.
Thanks in advance!
UPDATE-------------------------------------------
This is what I have
param([string]$projectName = $(throw 'csproj file is required'))
$proj = Resolve-Path $projectName
$propAssemblyName = $proj.Properties.Item("AssemblyName")
$propAssemblyName.Value = '$(ReleasedAssemblyName)'
But I obviously dont know how to make this work as I get bunch of issues. Thanks
function Set-Version {
Write-Header "Updating version in .csproj files"
try {
Push-Location ".\csprojLocation"
$versionProjFile = Resolve-Path "*.csproj"
$xml = [xml](Get-Content $versionProjFile)
$xml.Project.PropertyGroup.AssemblyVersion = ${version}
$xml.Save($versionPropsFile)
}
finally {
Pop-Location
}
}
Set-Version

Using PowerShell to create and add class libraries to a solution

I'm trying to automate some of the tasks I perform on each web project. What I want is a PoSH script that I can run on a new solution that will:
load the solution contained in the scripts current directory.
create new projects for the loaded solution and add them to the solution.
create some classes and add them to each of the projects.
So far I have a simple script (shown below) that finds and opens the local solution file.
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
Set-Location $dir
$solution = Get-ChildItem | Where-Object{($_.Extension -eq ".sln")}
if ($solution.Count -eq 0)
{
"Please place this script in the folder containing you solution file."
break;
}
$dteObj = New-Object -ComObject "VisualStudio.DTE"
$dteObj.Solution.Open($solution.FullName)
How can I now create new projects and add them to the solution?
Check out http://studioshell.codeplex.com/ by Jim Christopher.
To create a project , call GetProjectTemplate, and then pass the returned template paths to AddFromTemplate.
Try this in Package Manager Console.
#Create a Console Project
$csTemplatePath = $dte.Solution.GetProjectTemplate("ConsoleApplication.zip", "CSharp")
$csPrjPath = "C:\\Projects\\SolutionName\\ConsoleApplication1"
$dte.Solution.AddFromTemplate($csTemplatePath, $csPrjPath, "ConsoleApplication1", 'false')
#Create a C# class
$itemPath = $dte.Solution.GetProjectItemTemplate("Class.zip", "CSharp")
$prj = Get-Project
$prjItem = $prj.ProjectItems.AddFromTemplate($itemPath, "Project.cs")

How can I write Nuspec for MEF Plugin File

I want to write nuspec for MEF plugin.
I can copy xxx.dll to content directory, like below.
<files>
<file src="Alhambra\bin\Release\Plugins\Alhambra.Plugin.SqlServer.dll" target="content\Plugins\Alhambra.Plugin.SqlServer.dll" />
<file src="Alhambra\bin\Release\Alhambra.dll" target="lib\Alhambra.dll" />
</files>
but I can't set file property in user project to copy output directory.
Thanks for any suggestions or code snippets.
My approach would be to add the plugin to the project as a separate file. For that you need an install script (see NuGet docs for this).
My solution for this is the following script:
param($installPath, $toolsPath, $package, $project)
Function add_file($file)
{
$do_add = 1
foreach($item in $project.DTE.ActiveSolutionProjects[0].ProjectItems)
{
if ($item -eq $file)
{ $do_add = 0 }
}
if ($do_add -eq 1)
{
$added = $project.DTE.ItemOperations.AddExistingItem($file)
$added.Properties.Item("CopyToOutputDirectory").Value = 2
$added.Properties.Item("BuildAction").Value = 0
}
}
add_file(<file1>)
add_file(<file2>)
Of course, when the user uninstalls the package, you need to clean up:
param($installPath, $toolsPath, $package, $project)
Function remove_file($file)
{
foreach($item in $project.DTE.ActiveSolutionProjects[0].ProjectItems)
{
if ($item.Name -eq $file)
{
$item.Delete()
}
}
}
remove_file(<file1>)
remove_file(<file2>)