Powershell Pre-Build script failing from msbuild - powershell

I have a Powershell script that executes as a pre-build call for a Xamarin mobile app. The script changes the package name to match the build type e.g. Debug, Release.
To enable different "flavours" of the app to be created, I have written a batch file to replace the config file of the app with one matching the requested build type.
When I build from within Visual Studio, the powershell script runs as I expect and changes what I expected. However when the batch file runs I get an error message appearing:
Here is the content of the batch file, this was my first attempt at writing a batch file to build a code project:
#ECHO OFF
set buildVer=%1
set path=XamarinTestApp\XamarinTestApp
set msBuildDir=%WINDIR%\Microsoft.NET\Framework\v4.0.30319
echo %buildVer%
IF "%buildVer%"=="Release" (
goto :releaseBuild)
IF "%buildVer%"=="Test" (
goto :testBuild)
IF "%buildVer%"=="Dev" (
goto :devBuild)
:releaseBuild
set buildType=Release
copy /-y %path%\app.Release.config %path%\app.Config
goto :builder
:testBuild
set buildType=Release
copy /-y %path%\app.Test.config %path%\app.Config
goto :builder
:devBuild
set buildType=Debug
copy /-y %path%\app.Debug.config %path%\app.Config
goto :builder
:builder
call %msBuildDir%\msbuild.exe
C:\Projects\%path%\XamarinTestApp.Droid\XamarinTestApp.Droid.csproj /property:Configuration=%buildType% /target:SignAndroidPackage /verbosity:diag
I'm looking for any advice on either the error message I am getting, or some advice on how to get configurable information into my app.
Thanks.

Do not use path as user-variable. It is predefined by the system to locate executables.
Change that name to mypath - almost anything other than path.
from the prompt, use the command
set
to see a partial list of the names of variables that are set by the system

Related

How to upload a lot of files at once using FileZilla (possibly using a file containing the list of files to publish)?

Is there a way, using FileZilla, to publish many files at once (currently I have to choose them one by one every time, because they can be in different directories and I can't publish the whole directory)?
The ideal solution I am looking for is to use a single .txt file where I can paste the list of paths I want to publish and then somehow tell FileZilla to use it and publish each file to the remote server.
FileZilla lets you export the list of the files you have published with File -> Export in XML format. I am looking for something like this but I need to do the opposite operation.
If someone has some insights on it, please share them with me. Thanks!
P.S.: currently, I also use NetBeans IDE and publish files with it by clicking with the right button of the mouse and selecting Upload. If there's a way to do the same with NetBeans, that would be great (I write PHP code).
Thanks for the attention.
FileZilla does not allow any kind of automation.
See How do I send a file with FileZilla from the command line?
But you can use any other command-line FTP client.
For example WinSCP FTP client has Uploading a list of files example that exactly covers your task:
You may use following batch file that calls WinSCP script:
#echo off
set SESSION=ftp://user:password#example.com/
set REMOTE_PATH=/home/user/
echo open %SESSION% >> script.tmp
rem Generate "put" command for each line in list file
for /F %%i in (list.txt) do echo put "%%i" "%REMOTE_PATH%" >> script.tmp
echo exit >> script.tmp
winscp.com /script=script.tmp
set RESULT=%ERRORLEVEL%
del script.tmp
rem Propagating WinSCP exit code
exit /b %RESULT%

How to deploy to multiple environments with webpack using msdeploy

I've got a .NET WebAPI solution, and a UI built in Angular2 RC4 (angular-cli webpack version). I'm confused about how to deploy these to different environments, especially configuration parameters - there seems to be a mismatch between the .NET way and the UI way of doing things, which I don't quite get.
Here's how I've got it currently in TeamCity. The WebAPI solution is built once only, and is configured at deploy time. The various configuration parameters the project needs (such as connection strings, endpoints etc.) are stored in web.config. When I deploy to my test environment using MSDeploy, I pass in setParam arguments to the MSDeploy command line which replaces the connection strings and endpoints in the web.config with those values. When I deploy to production, I use the same build but pass in different arguments to the setParam in the command line.
This approach makes sense to me because I know that the exact same build is going from one environment to the next, the only difference being the parameters I specifically told it to set for each environment. Super.
With Angular2 and webpack it looks like a different approach is needed. When I build my project (with ng build -prod) it minimizes and bundles my HTML and Javascript files into 3 or 4 files, along with gzipped versions of those files. This is great for reducing file size and increasing speed of my website, but there is no way to "inject" configuration parameters into these gzip files like there is with MSDeploy's setParam. Everywhere I've seen that mentions webpack is showing webpack.dev.config.js and webpack.prod.config.js. But doesn't that mean we need to build a different bundle for each environment? And actually with Angular2 the webpack bit is considered "a black box" and it's not possible to supply your own webpack.config file anyway.
The only workaround I can think of is to use TeamCity's "File Content Replacer" on the "main.1234abcd6946c6a08519.bundle.js" to replace my configuration parameters with the values for that environment, then gzip that file - overwriting the one created by webpack.
But this is horrible, so I'm looking for any better suggestions?
I don't have any experience with webpack or if this is better than your workaround but you can use the TextFile kind of setParam entry to alter any file in your project using Regex find/replace at deploy time.
https://technet.microsoft.com/en-us/library/dd569084(v=ws.10).aspx
I went with creating a separate package for each environment. I added a build step that replaces my API URL on localhost in src\app\environment.ts, with the appropriate URL for that environment, then it runs npm build -prod and then MSDeploy to create the package. I do this for all environments I want to target.
Here's the script:
REM =====CREATE TEST PACKAGE==================================================
REM backup the environment file
ren src\app\environment.ts environment.ts.bak
copy /Y src\app\environment.ts.bak src\app\environment.ts
REM replace localhost in environment file with the TEST environment URL
"%env.FART%" src\app\environment.ts http://localhost:12345 %TEST.api.url%
REM build using this environment
call npm run build-prod
REM restore backup environment file
del /Q src\app\environment.ts
ren src\app\environment.ts.bak environment.ts
REM create TEST package
"%env.MSDEPLOY%" ^
-verb:sync ^
-source:contentPath="%teamcity.build.workingDir%\dist" ^
-dest:package="%teamcity.build.checkoutDir%\Package_TEST.zip"
REM =====CREATE PROD PACKAGE==================================================
REM backup the environment file
ren src\app\environment.ts environment.ts.bak
copy /Y src\app\environment.ts.bak src\app\environment.ts
REM replace localhost in environment file with the PROD environment URL
"%env.FART%" src\app\environment.ts http://localhost:12345 %PROD.api.url%
REM build using this environment
call npm run build-prod
REM restore backup environment file
del /Q src\app\environment.ts
ren src\app\environment.ts.bak environment.ts
REM create PROD package
"%env.MSDEPLOY%" ^
-verb:sync ^
-source:contentPath="%teamcity.build.workingDir%\dist" ^
-dest:package="%teamcity.build.checkoutDir%\Package_PROD.zip"
By the way, %env.FART% is the location of fart.exe which is a great find/replace tool that I use to replace one string in a file with another.

Add registry key during vsix installation

Is there any way to dynamically add a registry key while installing from a vsix?
For example:
Say we have SomeExtension.vsix.
It should check for a AnExisting.dll under
C:\Program Files (x86)\Existing\AnExisting.dll
C:\Program Files (x86)\Existing2\AnExisting.dll
Say it finds under Existing folder
Then add
[HKEY_CURRENT_USER\Software]
"C:\Program Files (x86)\Existing"=""
I know of pkgdef, but it seems to be taking a constant value i.e. we cannot get it to dynamically change on the machine it is being installed.
Or is it possible to get an environment variable on the machine it is being installed say we set PRODUCT_HOME accordingly for the vsix to add the value to registry?
This is the easiest way we can do this, although I do not know what side effects it can have. The following is a batch file snippet:
rem generate a pkgdef with the appropriate value
echo [HKEY_CURRENT_USER\Software] > MyBindingPaths.pkgdef
echo "%PRODUCT_HOME%"="" >> MyBindingPaths.pkgdef
rem *** Copy to VS extensions folder, this is a known location to look for pkgdef files ***
copy MyBindingPaths.pkgdef "%DEVENVDIR%Extensions"
echo *** Installing our VSIX ***
"%DevEnvDir%\vsixinstaller" -q SomeExtension.vsix
Other better suggestions welcome.

Open file by name only, no extension

How can I open any type of file in a .bat by providing only a name of the file, no extension?
I want to let windows decide the application to use.
example:
%SystemRoot%\explorer.exe E:\SomeFolder\
%SystemRoot%\explorer.exe E:\SomeFolder\file1
Use START command:
start "Any title" E:\SomeFolder\
start "Any title" E:\SomeFolder\file1
Taken from Start help:
If Command Extensions are enabled, external command invocation
through the command line or the START command changes as follows:
.
non-executable files may be invoked through their file association just
by typing the name of the file as a command. (e.g. WORD.DOC would
launch the application associated with the .DOC file extension).
See the ASSOC and FTYPE commands for how to create these
associations from within a command script.
.
When searching for an executable, if there is no match on any extension,
then looks to see if the name matches a directory name. If it does, the
START command launches the Explorer on that path. If done from the
command line, it is the equivalent to doing a CD /D to that path.
Note that previous description imply that the pure filename must also execute the right application, with no START command. To pick up the first file with a given name:
for %%f in (name.*) do set "filename=%%f" & goto continue
:continue
... and to execute it:
%filename%
PS - Note that you want "to let windows decide the application to use", but in your example you explicitly select %SystemRoot%\explorer.exe as the application to use. So?

Tool for commandline "bookmarks" on windows?

Im searching a tool which allows me to specify some folders as "bookmarks" and than access them on the commandline (on Windows XP) via a keyword. Something like:
C:\> go home
D:\profiles\user\home\> go svn-project1
D:\projects\project1\svn\branch\src\>
I'm currently using a bunch of batch files, but editing them by hand is a daunting task. On Linux there is cdargs or shell bookmarks but I haven't found something on windows.
Thanks for the Powershell suggestion, but I'm not allowed to install it on my box at work, so it should be a "classic" cmd.exe solution.
What you are looking for is called DOSKEY
You can use the doskey command to create macros in the command interpreter. For example:
doskey mcd=mkdir "$*"$Tpushd "$*"
creates a new command "mcd" that creates a new directory and then changes to that directory (I prefer "pushd" to "cd" in this case because it lets me use "popd" later to go back to where I was before)
The $* will be replaced with the remainder of the command line after the macro, and the $T is used to delimit the two different commands that I want to evaluate. If I typed:
mcd foo/bar
at the command line, it would be equivalent to:
mkdir "foo/bar"&pushd "foo/bar"
The next step is to create a file that contains a set of macros which you can then import by using the /macrofile switch. I have a file (c:\tools\doskey.macros) which defines the commands that I regularly use. Each macro should be specified on a line with the same syntax as above.
But you don't want to have to manually import your macros every time you launch a new command interpreter, to make it happen automatically, just open up the registry key
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun and set the value to be doskey /macrofile "c:\tools\doskey.macro". Doing this will make sure that your macros are automatically predefined every time you start a new interpreter.
Extra thoughts:
- If you want to do other things in AutoRun (like set environment parameters), you can delimit the commands with the ampersand. Mine looks like: set root=c:\SomeDir&doskey /macrofile "c:\tools\doskey.macros"
- If you prefer that your AutoRun settings be set per-user, you can use the HKCU node instead of HKLM.
- You can also use doskey to control things like the size of the command history.
- I like to end all of my navigation macros with \$* so that I can chain things together
- Be careful to add quotes as appropriate in your macros if you want to be able to handle paths with spaces in them.
I was looking for this exact functionality, for simple cases. Couldn't find a solution, so I made one myself:
#ECHO OFF
REM Source found on https://github.com/DieterDePaepe/windows-scripts
REM Please share any improvements made!
REM Folder where all links will end up
set WARP_REPO=%USERPROFILE%\.warp
IF [%1]==[/?] GOTO :help
IF [%1]==[--help] GOTO :help
IF [%1]==[/create] GOTO :create
IF [%1]==[/remove] GOTO :remove
IF [%1]==[/list] GOTO :list
set /p WARP_DIR=<%WARP_REPO%\%1
cd %WARP_DIR%
GOTO :end
:create
IF [%2]==[] (
ECHO Missing name for bookmark
GOTO :EOF
)
if not exist %WARP_REPO%\NUL mkdir %WARP_REPO%
ECHO %cd% > %WARP_REPO%\%2
ECHO Created bookmark "%2"
GOTO :end
:list
dir %WARP_REPO% /B
GOTO :end
:remove
IF [%2]==[] (
ECHO Missing name for bookmark
GOTO :EOF
)
if not exist %WARP_REPO%\%2 (
ECHO Bookmark does not exist: %2
GOTO :EOF
)
del %WARP_REPO%\%2
GOTO :end
:help
ECHO Create or navigate to folder bookmarks.
ECHO.
ECHO warp /? Display this help
ECHO warp [bookmark] Navigate to existing bookmark
ECHO warp /remove [bookmark] Remove an existing bookmark
ECHO warp /create [bookmark] Navigate to existing bookmark
ECHO warp /list List existing bookmarks
ECHO.
:end
You can list, create and delete bookmarks. The bookmarks are stored in text files in a folder in your user directory.
Usage (copied from current version):
A folder bookmarker for use in the terminal.
c:\Temp>warp /create temp # Create a new bookmark
Created bookmark "temp"
c:\Temp>cd c:\Users\Public # Go somewhere else
c:\Users\Public>warp temp # Go to the stored bookmark
c:\Temp>
Every warp uses a pushd command, so you can trace back your steps using popd.
c:\Users\Public>warp temp
c:\Temp>popd
c:\Users\Public>
Open a folder of a bookmark in explorer using warp /window <bookmark>.
List all available options using warp /?.
With just a Batch file, try this... (save as filename "go.bat")
#echo off
set BookMarkFolder=c:\data\cline\bookmarks\
if exist %BookMarkFolder%%1.lnk start %BookMarkFolder%%1.lnk
if exist %BookMarkFolder%%1.bat start %BookMarkFolder%%1.bat
if exist %BookMarkFolder%%1.vbs start %BookMarkFolder%%1.vbs
if exist %BookMarkFolder%%1.URL start %BookMarkFolder%%1.URL
Any shortcuts, batch files, VBS Scripts or Internet shortcuts you put in your bookmark folder (in this case "c:\data\cline\bookmarks\" can then be opened / accessed by typing "go bookmarkname"
e.g. I have a bookmark called "stack.url". Typing go stack takes me straight to this page.
You may also want to investigate Launchy
With PowerShell you could add the folders as variables in your profile.ps1 file, like:
$vids="C:\Users\mabster\Videos"
Then, like Unix, you can just refer to the variables in your commands:
cd $vids
Having a list of variable assignments in the one ps1 file is probably easier than maintaining separate batch files.
Another alternative approach you may want to consider could be to have a folder that contains symlinks to each of your projects or frequently-used directories. So you can do something like
cd \go\svn-project-1
cd \go\my-douments
Symlinks can be made on a NTFS disk using the Junction tool
Without Powershell you can do it like this:
C:\>set DOOMED=c:\windows
C:\>cd %DOOMED%
C:\WINDOWS>
Crono wrote:
Are Environment variables defined via "set" not meant for the current session only? Can I persist them?
They are set for the current process, and by default inherited by any process that it creates. They are not persisted to the registry. Their scope can be limited in cmd scripts with "setlocal" (and "endlocal").
Environment variables?
set home=D:\profiles\user\home
set svn-project1=D:\projects\project1\svn\branch\src
cd %home%
On Unix I use this along with popd/pushd/cd - all the time.