Publishing ASP .NET Core App through Windows Power Shell - asp.net

How can I publish correctly ASP .NET Core App through Windows Power Shell?
Write-Host ==== START PUBLISHING APP ==== -ForegroundColor Red
$msbuild = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe"
$options = "/p:DeployOnBuild=true /p:PublishProfile='FolderProfile'"
$apiproj = $BackEndPath + "\DCMT.WebApi.csproj"
# Publish the WebApi to Server...
$build = $msbuild + " $apiproj " + $options
Invoke-Expression $build
Executing that command is giving me an error
error MSB4040: No target element in the project.

# Publish the WebApi to Server...
$pathToCompile = "C:\DCMT\DCMT-INTERNS-SOURCE\DCMT-BackEnd\DCMT.WebApi\DCMT.WebApi\DCMT.WebApi.csproj"
dotnet publish $pathToCompile /p:PublishDir="C:\DCMT\DCMT-INTERNS"
I have changed the command to look like this and it works! :D

Related

With DotNet (Core/Standrad) how do I the project version at build time?

I'm able to set the project version by adding the tag to the .csproj file,
but I'd like to change that value programatically inside the pipeline.
I hacked together a script to do accomplish that, but it feels sloppy.
That's got to be a way to do this through the CLI, but I'm just not finding it.
Is there a command similar to this that I'm overlooking?
dotnet build -project-version 1.2.3
If no command exists, what have you done to set the project build version in your pipelines?
i use the following in my pipeline.
dotnet build -p:VersionPrefix="$(buildNumber)" -p:VersionSuffix="$(buildPipline)"
and in my csproj file i have
<PropertyGroup>
...
<VersionPrefix>1.0.1</VersionPrefix>
<VersionSuffix>local</VersionSuffix>
</PropertyGroup>
to get the version number in code, i use the following
public static string Version => System.Reflection.Assembly.GetEntryAssembly().GetCustomAttribute<System.Reflection.AssemblyInformationalVersionAttribute>().InformationalVersion;
if you're using azure pipelines, you can add a powershell script, which declares the version based on the date & time.
Write-Host "Generating Build Number"
$baseDate = [datetime]"01/01/2019"
$currentDate = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId((Get-Date), 'Eastern Standard Time')
$interval = NEW-TIMESPAN –Start $baseDate –End $currentDate
$days = $interval.Days
$hour = $currentDate.ToString("HH")
$minute = $currentDate.ToString("mm")
$version = "1.0.$days.$hour$minute"
$version_npm = "1.$days.$($currentDate.ToString("Hmm"))"
if($currentDate.ToString("HH") -eq "00")
{
$version_npm = "1.$days.25$($currentDate.ToString("mm"))"
}
Write-Host "Version: $version"
Write-Host "npm Version: $version_npm"
Write-Host "##vso[task.setvariable variable=buildNumber]$version"
Write-Host "##vso[task.setvariable variable=buildNumber_npm]$version_npm"
You may try Assembly Info extension, which can update project AssemblyInfo files and .Net Core / .Net Standard project files .csproj. For detailed instructions on how to configure the extension please see the following link:
https://github.com/BMuuN/vsts-assemblyinfo-task/wiki/Versioning
I found the easiest way to do this is using environment variables in the .csproj file like this:
<PropertyGroup Condition="'$(APPVERSION)' != ''">
<InformationalVersion>$(APPVERSION)</InformationalVersion>
</PropertyGroup>
And then set the environment variables in your build server.

DNX Webjob fails to resolve local project dependencies

We have a Solution created with VS2015.1 that has 3 projects, all of them DNX RC1.
| sln
|+---MVC6 Api
| project.json
| +---ClassLibrary
| Class.cs
| project.json
| \---Webjob
Program.cs
project.json
Both the API and Webjob reference the ClassLibrary in their project.json files.
"frameworks": {
"dnx451": {
"dependencies": {
"ClassLibrary": "1.0.0-*"
}
}
}
We created 2 WebApps, both tied with Continuos Integration to the Solution repo and each with a Project Application Setting that points to the API folder (in one) and the Webjob folder (in the other).
The API project gets deployed without problem, when it tries to resolve the local project dependency it works:
Using Project dependency ClassLibrary 1.0.0 for DNX,Version=v4.5.1
Copying source code from Project dependency ClassLibrary
Source D:\home\site\repository\ClassLibrary\project.json
Target D:\local\Temp\8d32044390806ef\approot\src\ClassLibrary
The Webjob on the other hand, fails, it tries to resolve it as a nuget remote package and fails:
[01/21/2016 19:47:45 > b597c3: INFO] GET https://api.nuget.org/v3-flatcontainer/ClassLibrary/index.json
[01/21/2016 19:47:46 > b597c3: INFO] NotFound https://api.nuget.org/v3-flatcontainer/ClassLibrary/index.json 507ms
[01/21/2016 19:47:46 > b597c3: ERR ] Unable to locate Dependency ClassLibrary >= 1.0.0-*
This last part I had to check it through Kudu, since it's done on the first run of the WebJob apparently and not during the deploy phase (like with the API).
Running the WebJob locally works without issues.
I tried the solution in publish dnx based WebJob with local dependencies but didn't work.
After talking with the Product Team, the 3 project scenario won't work right now by default.
The solution described on publish dnx based WebJob with local dependencies works for a 2 project scenario, but if you need to deploy a WebJob AND a Web App that depend on the same Class Library project and the 3 are on the same repo, you can't make the Webjob deploy from Continuous Integration.
The solution is to set Continuous Integration for your Web App (it will work by default) and manually deploy your WebJob as a zipped file.
Go into your WebJob folder and run dnu publish.
Go into bin/output/approot/src/YourWebJobFolder.
Edit the autogenerated CMD file.
Use this script by customizing line 4:
#ECHO OFF
:: 1. Prepare environment
SET DNX_CONSOLE_APP_PATH=Autocosmos.Trunk.Webjob
SET DNVM_CMD_PATH_FILE="%USERPROFILE%\.dnx\temp-set-envvars.cmd"
:: 2. Install DNX
CALL PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';$CmdPathFile='%DNVM_CMD_PATH_FILE%';& '%SCM_DNVM_PS_PATH%' " install latest
IF ERRORLEVEL 1 GOTO ERROR
:: 3. Put DNX on the path
IF EXIST %DNVM_CMD_PATH_FILE% (
CALL %DNVM_CMD_PATH_FILE%
DEL %DNVM_CMD_PATH_FILE%
)
call :ExecuteCmd dnx --project "%~dp0src\%DNX_CONSOLE_APP_PATH%" --configuration Release %DNX_CONSOLE_APP_PATH% run
goto end
:ExecuteCmd
setlocal
set _CMD_=%*
call %_CMD_%
if "%ERRORLEVEL%" NEQ "0" echo Failed exitCode=%ERRORLEVEL%, command=%_CMD_%
exit /b %ERRORLEVEL%
:error
endlocal
echo An error has occurred during web site deployment.
call :exitSetErrorLevel
call :exitFromFunction 2>nul
:exitSetErrorLevel
exit /b 1
:exitFromFunction
()
:end
endlocal
echo Finished successfully.
Then ZIP bin/output/approot and Upload it to Azure.

How to run an Azure deployment PowerShell script from console

I've downloaded a website publish profile form Azure Portal. After importing the publish profile in Visual Studio I can publish my website without providing credentials by clicking ProjectName > Publish.
Importing produced a series of files
xxxxx - FTP.pubxml
xxxxx - FTP.pubxml.user
xxxxx - FTP-publish.ps1
xxxxx - Web Deploy.pubxml
xxxxx - Web Deploy.pubxml.user
xxxxx - Web Deploy-publish.ps1
I'm wondering if I could use either of the powershell files in my simple deployment process.
When I tried to run xxxxx - Web Deploy-publish.ps1 i got an error:
ps1 : An error occurred during publish. Cannot bind argument to
parameter 'publishProperties' because it is null.
I guess I'm missing some parameters. Can somebody provide me with an example how to run it properly?
Here is a sample Powershell that you can use to deploy your Web App to Azure.
You need to set the Params and point to your publish settings to get the deploy password etc..
# How to run the script
# deploy-azure-website-devbox-webdeploy.ps1 -ProjectFile
# Define input parameters
Param(
[Parameter(Mandatory = $true)]
[String]$ProjectFile, # Point to the .csproj file of the project you want to deploy
[Switch]$Launch # Use this switch parameter if you want to launch a browser to show the website
)
# Begin - Actual script -----------------------------------------------------------------------------------------------------------------------------
# Set the output level to verbose and make the script stop on error
$VerbosePreference = "Continue"
$ErrorActionPreference = "Stop"
$scriptPath = Split-Path -parent $PSCommandPath
# Mark the start time of the script execution
$startTime = Get-Date
# Build and publish the project via web deploy package using msbuild.exe
Write-Verbose ("[Start] deploying to Windows Azure website {0}" -f $websiteName)
# Read from website-environment.xml to get the environment name
[Xml]$envXml = Get-Content ("{0}\website-environment.xml" -f $scriptPath)
$websiteName = $envXml.environment.name
# Read from the publish settings file to get the deploy password
$publishXmlFile = "{0}\{1}.pubxml" -f $scriptPath, $websiteName
[Xml]$xml = Get-Content ("{0}\{1}.publishsettings" -f $scriptPath, $websiteName)
$password = $xml.publishData.publishProfile.userPWD.get(0)
# Run MSBuild to publish the project
& "$env:windir\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" $ProjectFile `
/p:VisualStudioVersion=11.0 `
/p:DeployOnBuild=true `
/p:PublishProfile=$publishXmlFile `
/p:Password=$password
Write-Verbose ("[Finish] deploying to Windows Azure website {0}" -f $websiteName)
# Mark the finish time of the script execution
$finishTime = Get-Date
# Output the time consumed in seconds
Write-Output ("Total time used (seconds): {0}" -f ($finishTime - $startTime).TotalSeconds)
# Launch the browser to show the website
If ($Launch)
{
Show-AzureWebsite -Name $websiteName
}
# End - Actual script -------------------------------------------------------------------------------------------------------------------------------

How to check whether ASP.NET 4.0 registered on IIS 7.5

Is there any reliable way how to check whether ASP.NET 4.0 registered on IIS 7.5 programmatically? I need to test it in the installer as prerequisite, before ASP.NET application installation start.
If ASP.NET 4.0 not registered on the IIS, later during the installation just installed application cannot be run and returns 500 internal server error (and it is too late to solve the problem). Instead, I want to show some warning (and hint how to solve the issue) before any installation steps started. But no reliable solution found yet.
AFAIK, registry entries reading sometimes may not work correctly. So now, I run aspnet_regiis.exe -lv to list versions (as suggested here) and parse the output. But even if .NET not registered correctly my test (falsely) succeeds, because the output is (contains version 4.0):
2.0.50727.0 C:\Windows\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll
4.0.30319.0 C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll
(Win7 32bit)
Running aspnet_regiis.exe -ir can repair it in this case.
It's similar issue as this question, but I need test it programmatically.
Do you have any ideas or experiences?
Using your own answer as a basis, this can also be done using the command line (with elevation):
%WINDIR%\System32\inetsrv\appcmd.exe list apppool /managedRuntimeVersion:v4.0
If anything is returned, ASP.NET 4.0 is registered.
The issue with this approach is that it seems to be possible to create 4.0 application pools manually even if the filter is not installed, and then this method would not work.
EDIT:
I have ended up running these three checks:
aspnet_regiis.exe -lv (should return a line containing "c:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll")
appcmd.exe list apppool /managedRuntimeVersion:v4.0 (should return a line containing "MgdVersion:v4.0")
appcmd.exe list config -section:system.webServer/isapiFilters (should return a line containing "c:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_filter.dll")
Note that I only care about 32bit versions.
If all three checks pass, it can be concluded that ASP.NET 4.0 is registered. Still not 100% false positive-proof though.
This is an old question, but I'm posting an answer because your question is one of the top results on google, and it's unanswered.
The registry key you are looking for is HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\4.0.30319.0. If that key is present, then .Net 4 has been installed and is registered in IIS.
If you just want to check if .Net 4 is installed, you can check HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full.
In Powershell it could be done like this:
# load the IIS-Commandlets
Import-Module WebAdministration
# get the isapi filters currently loaded
Get-WebConfigurationProperty -Filter "/system.webServer/isapiFilters/filter" -name *
An output could look like this:
name : ASP.Net_4.0_32bit<br/>
path : %windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_filter.dll<br/>
enabled : True<br/>
enableCache : True<br/>
preCondition : runtimeVersionv4.0,bitness32<br/>
ItemXPath : /system.webServer/isapiFilters/filter[#name='ASP.Net_4.0_32bit']<br/>
Attributes : {name, path, enabled, enableCache...}<br/>
ChildElements : {}<br/>
ElementTagName : filter<br/>
Methods :<br/>
Schema : Microsoft.IIs.PowerShell.Framework.ConfigurationElementSchema<br/>
name : ASP.Net_4.0_64bit<br/>
path ........
Based on that we could write this code to check and install .NET 4 if needed:
$DotNet4Missing = $true
# lets make sure we got .net 4 correctly setup
$isapiFilters = Get-WebConfigurationProperty -Filter "/system.webServer/isapiFilters/filter" -name *
"/system.webServer/isapiFilters/filter count: {0}" -f $isapiFilters.Count
foreach ($filter in $isapiFilters)
{
"filter.name: {0}" -f $filter.name
if ($filter.name -eq "ASP.Net_4.0_64bit")
{
"-> Found .NET 4 - GREAT!"
$DotNet4Missing = $false
}
}
if ($DotNet4Missing)
{
"Missing .NET 4 IIS integration - running aspnet_regiis.exe"
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "-iru"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
"aspnet_regiis.exe stdout: {0}" -f $stdout
"aspnet_regiis.exe stderr: {0}" -f $stderr
"aspnet_regiis.exe ExitCode: {0}" -f $p.ExitCode
}
Summary: The problem described above occurs on non-server operating system (Win7). The .NET 4.0 is not registered on the IIS even if you install IIS before .NET 4.0 (and so .NET should be registered on IIS correctly). This causes unexpected problems during any ASP.NET application installation -- until aspnet_regiis.exe -ir is ran from the commandline. There is no problem with Win 2008 (i.e. when IIS installed before .NET 4.0 then .NET is registered correctly on IIS and everything works as expected).
So finally my colleague told me what possibly could be solution of the problem. I've verified that following solution works fine (also on Win7). ServerManager from Microsoft.Web.Administration namespace can be employed easily:
public static bool IsAspNetRegistered()
{
using (var mgr = new ServerManager())
{
return mgr.ApplicationPools.Any(pool => pool.ManagedRuntimeVersion == "v4.0");
}
}
In case of successful .NET registration on IIS, there is at least one application pool which runtime version is set to "v4.0" so this fact was used for the check.
Of course, if anybody deletes all application pools, this method can work incorrectly. But this is bit pathological situation I don't care. The main issue is to prevent that although everything is done according our installation recommendations, still not possible to install the application on the machine.

How to replace OpenExeConfiguration in a web context (asp.net mvc 1)

OK so we have something that is currently using OpenExeConfiguration for reading a config file, however this doesn't work when running in the web context.
I've tried a variety of different ways of opening the web.config programmatically but I can't seem to get it to read the correct web.config file. In case it matters I am currently debugging it in VS 2008.
1. config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(System.Web.HttpContext.Current.Request.ApplicationPath);
2. config = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = "web.config" }, ConfigurationUserLevel.None);
3. config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
4. config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(null);
5. System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath);
It either opens up the wrong config file (either the machine config, or the VS /IDE/Web.config) or complains about the error:
{System.Configuration.ConfigurationErrorsException: An error occurred loading a configuration file: Failed to map the path '/'. ---> System.InvalidOperationException: Failed to map the path '/'.
Edit -
OK so a combination of
config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
AND running Visual Studio 2008 As Administrator worked. Am hoping we don't run into security/permission issues when we deploy to our web server / client environments!
So in the end I used this code (had to handle whether the web application was running, or if our unit test code was running).
System.Configuration.Configuration config = null;
if (System.Web.HttpContext.Current != null && !System.Web.HttpContext.Current.Request.PhysicalPath.Equals(string.Empty))
config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
else
config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
Also have to be running Visual Studio in Administrator mode - which I found out you can set as a property on your shortcut so you don't need to remember each time in Windows 7 to right click and run as administrator :)

Resources