Open .sln file from cmder? - cmder

Is it possible to launch devenv.exe and open a .sln file from cmder? After I clone a git repo from the command line, I'd like to quickly open the solution in Visual Studio without having to leave cmder.

Danny is correct, you simply type xxx.sln.
I'm a bit lazy and developed the script below to be able to type vs and it will find and open the first sln file it finds in the current directory.
Here are some example commands:
vs - Will open the first sln file it finds, if it doesn't find one it will just open Visual Studio without a solution. I default to opening with Visual Studio 2017. Just change the default case in the Get-VisualStudioCommand function if you'd rather default to a different version.
vs 15 - I have a bunch of versions of Visual Studio on my machine, so this will open similarly to vs, but will open with Visual Studio 2015.
vs 13 'helloWorld.sln' - this will open a specific sln file, i.e., helloWorld.sln. One of the projects I worked on recently had multiple solutions in the same directory.
vs -WhatIf -Verbose - this will show you what the script would do if it ran and will print out the Write-Verbose messages. Handy for debugging. I show and example of this in the image below.
For this solution, I'm assuming that you're using a PowerShell console. If so, you can define a .ps1 file that will run before the console opens via the -File option. It's like defining a different PowerShell profile with different commands per console window (very powerful).
See the image below where I show going to settings and modify the PowerShell:PowerShell task to execute PowerShell -NoExit -NoLogo -File C:\src\ps\Cmder\general_setup.ps1 -new_console:d:"C:\src"
Here is the image (note, although I use an alias for ls that outputs in PowerShell like a Linux ls command...this is a PowerShell console):
If you add the following script to the C:\src\ps\Cmder\general_setup.ps1 file (or wherever you want to put it)...you can then type in vs and it will execute. Notice in the Get-VisualStudioCommand function, I've put all the file paths...not the most elegant looking code, but if your file paths to devenv.exe are different than mine, just change them there.
Note, you could also get fancy and add a pass-through to the -ArgumentList or flag for the /SafeMode command to be able to open Visual Studio in safe mode when needed, I've just created these as a quick and dirty shortcut.
function Get-VisualStudioCommand
{
[CmdletBinding()]
param ( [AllowNull()][String] $vsVersion )
$vs10 = """${env:ProgramFiles(x86)}\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe"""
$vs13 = """${env:ProgramFiles(x86)}\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe"""
$vs15 = """${env:ProgramFiles(x86)}\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe"""
$vs17 = """${env:ProgramFiles(x86)}\Microsoft Visual Studio\2017\Professional\Common7\IDE\devenv.exe"""
switch ($vsVersion)
{
'10' {$vs10}
'13' {$vs13}
'15' {$vs15}
'17' {$vs17}
default {$vs17}
}
}
function Get-SolutionName
{
[CmdletBinding()]
param ( [AllowNull()][String] $Name )
if (!$Name)
{
$Name = Get-ChildItem -Filter *.sln
}
if ($Name)
{
$Name = ('"{0}"' -f $Name)
}
return $Name
}
function Start-VisualStudioProcess
{
[CmdletBinding(SupportsShouldProcess=$true)]
param([String]$Version, [String]$Sln)
$VsCommand = Get-VisualStudioCommand -vsVersion $Version
$Sln = Get-SolutionName -Name $Sln
Write-Verbose -Message ('Starting: command={0} solutionName={1}' -f $VsCommand, $Sln)
if ($PSCmdlet.ShouldProcess($VsCommand, 'Start-Process'))
{
if ($Sln)
{
Start-Process -FilePath $vsCommand -ArgumentList $sln
}
else
{
Start-Process -FilePath $vsCommand
}
}
}
Set-Alias -Name vs -Value Start-VisualStudioProcess
Let me know if you have any questions. I hope it helps.

Run this command in your prompt(cmd, cmder, etc.)
reg add "HKCU\Software\Microsoft\Command Processor" /v Autorun /d "doskey vs=for /f \"delims=\" %a IN ('dir /b *.sln') do start %a" /f
Write "vs" for open the first *.sln in folder of Solution and be happy!

Related

Build agent no DotNetFramework MSBuild and VSTest capability in Team Foundation Server 2017

Since a while I discovered some of my buildagent doesn't have the necessary capabilities anymore to build a .NET Framwork web application. When I installed these build agents a few months ago it worked perfect. For some misterious reasons these capabilities went away. Since a week we have VS2017 installed on that machine. A reboot of the machine where the build agent is running doesn't help. Even we rebooted the Team Foundation Server machine. Can any help me with this problem?
Please try below items to let the agent to identify the capabilities:
Restart the Agent service to identify the capabilities
Add User Capabilities manually:
Settings >> AgentPools >> Select the pool >> select the specific Agent >> Capabilities >> Add capability under USER CAPABILITIES
Register capabilities to the machine following below steps, thus all the agents will automatically pick up the capabilities.
Control Panel >> System >> Advanced System Settings >> Environment Variables >> New System Variable >> Enter the variable name and value listed below >> OK >>
After doing so, restart the agents services will have each of them automatically pick up new capabilities.
Below capabilities for your reference (based on your environment and installed version):
DotNetFramework C:\Windows\Microsoft.NET\Framework64\v4.0.30319
DotNetFramework_4.6.1 C:\Windows\Microsoft.NET\Framework\v4.0.30319
DotNetFramework_4.6.1_x64 C:\Windows\Microsoft.NET\Framework64\v4.0.30319
MSBuild C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\
MSBuild_15.0 C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\
MSBuild_15.0_x64 C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\amd64\
VSTest C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow
VSTest_15.0 C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow
VisualStudio C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\
VisualStudio_15.0 C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\
VisualStudio_IDE_15.0 C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\
I followed your step regarding adding the settings as user capalbility. The build agents pick up the build task now. But when the solution was build an error is returned from the build task. Exit code -1073741502 returned from process: file name 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe', arguments '-NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command ". ([scriptblock]::Create('if (!$PSHOME) { $null = Get-Item -LiteralPath ''variable:PSHOME'' } else { Import-Module -Name ([System.IO.Path]::Combine($PSHOME, ''Modules\Microsoft.PowerShell.Management\Microsoft.PowerShell.Management.psd1'')) ; Import-Module -Name ([System.IO.Path]::Combine($PSHOME, ''Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1'')) }')) 2>&1 | ForEach-Object { Write-Verbose $_.Exception.Message -Verbose } ; Import-Module -Name 'C:\AgentV2_work_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca411ecda\1.119.0\ps_modules\VstsTaskSdk\VstsTaskSdk.psd1' -ArgumentList #{ NonInteractive = $true } -ErrorAction Stop ; $VerbosePreference = 'SilentlyContinue' ; $DebugPreference = 'SilentlyContinue' ; Invoke-VstsTaskScript -ScriptBlock ([scriptblock]::Create('. ''C:\AgentV2_work_tasks\VSBuild_71a9a2d3-a98a-4caa-96ab-affca411ecda\1.119.0\VSBuild.ps1'''))"'.

TFS 2015 build vNext update file version with commit id

Do you know how inject commit id into file version, so every assembly would heve version like 2.0.6565.0 where 6565 is related to C6565commit ID in TFS ?
It looks some power shell script is needed.
If your question is similar to your another post TFS 2015. the $(var.SourceLocation) variable is not available at gated-check in, that want to get the changeset id that hasn't checked in during gated check-in, then it's impossible in a single build.
If you don't use gated check in, then you can use $Env:BUILD_SOURCEVERSION in a powershell script to set the AssemblyVersion. Here is already a script at the website below, you can refer to it:
https://github.com/wulfland/ScriptRepository/blob/master/TFSBuild/TFSBuild/AssemblyVersion/Set-AssemblyVersion/Set-AssemblyVersion.ps1
Finally I created my own PS script based on this post.
The idea update version in all files with assembly info
$CommitId = ([string]$env:BUILD_SOURCEVERSION) -replace "[^0-9]+", ""
$AllVersionFiles = Get-ChildItem $SourceDir AssemblyInfo.cs -recurse
$regexToFindVersion = "Version\(""([0-9]+)\.([0-9]+).+"""
foreach ($file in $AllVersionFiles)
{
Write-Host "Processing " $file.FullName
(Get-Content $file.FullName) |
%{$_ -replace $regexToFindVersion, ('Version("$1.$2.0.' + $CommitId + '"') } |
Set-Content $file.FullName -Force
}
Full script can be found here.
The script must be placed before building project:

Installing Malware Bytes from Powershell

I'm trying to create a script to install malware bytes through powershell silently. This is what I have got so far:
$down = New-Object System.Net.WebClient
$url = 'http://downloads.malwarebytes.org/file/mbam/mbam-setup-2.0.2.1012.exe';
$file = 'c:\Program Files\malwaresetup.exe';
$down.DownloadFile($url,$file);
c:\Program Files\malwaresetup.exe /install=agent /s;
This downloads and starts the install but then the user then has to at there end finish off the installation (Selecting language location etc) is there anyway of completely silently installing the software so the user doesn't have to do anything?
When you run malwaresetup.exe /?, you'll get list of accepted command line parameters. You can write:
c:\Program Files\malwaresetup.exe /install=agent /verysilent
for no GUI whatsoever, or:
c:\Program Files\malwaresetup.exe /install=agent /silent /suppressmsgboxes
for unattended GUI installation (showing progress bar).

Programatically delete [permenantly] a TFS work item

Whilst I'm aware that there is a command line tool to permenantly delete a TFS work item. (e.g. How to delete Work Item from Team Foundation Server)
Has anyone been able to achieve the same action programatically using the TFS 2010 API DLLs?
Shai Raiten has blogged about this here, where he makes use of DestroyWorkItems(ids).
It is advisable that you proceed with extra caution in your implementation, since this can severely mess your installation. One could argue that constructing such a tool deviates from best practices.
You can also use PowerShell to bulk delete work items:
Copy and paste below script in a PowerShell file (with .ps1
extension), update the variable values mentioned in the list #4 below
and run the command from a machine where witadmin tool is installed
(Generally available after visual studio installation). Open
PowerShell command window and execute the script.
Note: Account running below script should have team foundation administrator or collection administrator access.
########TFS Work Items Bulk Destroy Automation Script##########
#Notes:
#1) This script requires to setup file/folder path, validate the file/folders path before running the script
#2) start the powershell window as Administrator and run the script
#3) This script requires share and admin access on the destination server, make sure your account or the account under which script is
# executing is member of admin group on the destination server
#4) Update following:
# 4.1: $CollectionURL
# 4.2: $WitAdmin tool location
# For VS 2015, Default location is C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE
# For VS 2013, Default location is C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE
# 4.3: $WI_List
# 4.4: $logfile
####################
$CollectionURL = "http://tfs:8080/tfs/CollectionName"
$WitAdminLocation = "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE"
$WI_List = Get-Content "C:\WI_List.txt"
$logfile="C:\log.txt"
$ExecutionStartTime = Get-Date
$WICount = 0
"## Starting WI Destroy # $ExecutionStartTime ##"| Out-File $logfile -Append
"Collection URL: $CollectionURL" | Out-File $logfile -Append
foreach ($WIID in $WI_List)
{
CD $WitAdminLocation
.\witadmin destroywi /collection:$CollectionURL /id:$WIID /noprompt
"WI ID: $WIID Destroyed" | Out-File $logfile -Append
$WICount = $WICount + 1
Write-Host "$WICount Work Items Deleted"
}
$ExecutionEndTime = Get-Date
"## WI Destroy Command Completed # $ExecutionEndTime ##"| Out-File $logfile -Append
$TotalExecutionTime = $ExecutionEndTime - $ExecutionStartTime
"Total Work Items Deleted: $WICount" | Out-File $logfile -Append
" Total Execution Time: $TotalExecutionTime" | Out-File $logfile -Append
##End of script##

How can I bulk rename files using PowerShell?

I'm trying to recursively rename a bunch of TFS folders using tf rename, PowerShell and a regular expression but I'm having some issues with PowerShell as I haven't spent much time with it. This is what I've put together so far to replace a leading 5 with 2.3.2 but it isn't working:
dir | foreach { tf rename $_ { $_.Name -replace '^5', '2.3.2' } }
Actual result:
Unrecognized command option 'encodedCommand'.
Unrecognized command option 'encodedCommand'.
Unrecognized command option 'encodedCommand'.
Unrecognized command option 'encodedCommand'.
...etc.
Update:
I got a little closer by doing the following instead:
dir | foreach { $newname = $_.Name -replace "^5", "2.3.2"; tf rename $_ $newname }
My next goal is to make this recurse subdirectories but this seems a bit more challenging (changing it to dir -recurse makes it quit after the parent folders for some reason).
I would first filter by 5* so you only process names that start with 5. Also, in this case since tf.exe isn't a PowerShell cmdlet, you don't want to use a scriptblock to determine a new name. Just use a grouping expression like so:
dir -filter 5* | foreach { tf rename $_ ($_.Name -replace '^5', '2.3.2')}
BTW, when you are trying to debug parameter passing to a native EXE like this it is immensely helpful to use the echoargs.exe utilty from the PowerShell Community Extensions. This is what it told me about your original approach:
6# dir -filter 5* | foreach { echoargs rename $_ { $_.Name -replace '^5', '2.3.2' } }
Arg 0 is <rename>
Arg 1 is <5foo.txt>
Arg 2 is <-encodedCommand>
Arg 3 is <IAAkAF8ALgBOAGEAbQBlACAALQByAGUAcABsAGEAYwBlACAAJwBeADUAJwAsACAAJwAyAC4AMwAuADIAJwAgAA==>
Arg 4 is <-inputFormat>
Arg 5 is <xml>
Arg 6 is <-outputFormat>
Arg 7 is <text>
Notes:
TFS has native cmdlets -- no need for tf.exe in most cases.
The time complexity of workspace operations depends on the number of pending renames already in the workspace. In TFS 2005/2008 it's significantly worse than linear. Bottom line, you should really consider batching up renames into multiple checkins if you have a large # of items, otherwise every single "tf rename" (or New-TfsPendingChange -Rename if using the cmdlets) will start taking minutes.
Try this:
dir . | foreach { $newname = $_.Name -replace "^5", "2.3.2"; tf rename $_ $newname }
Running the above commands requires the tf.exe to have been aliased as 'tf'.. or it did on my machine at least.
Run this command:
Set-Alias tf "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\tf.exe"
Update the path to tf.exe as appropriate
Also consider adding the line to your profile for future use
notepad $PROFILE

Resources