How to publish file from subfolder to main application folder? - visual-studio

I have a WinForms NET4.8 desktop app that I publish using ClickOnce. I have a dll file in a project subfolder that I need published to the same directory as the main app. I have the following in my csproj file:
<PropertyGroup>
<UnreferencedDlls>lib\twaindsm.dll</UnreferencedDlls>
</PropertyGroup>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="AfterBuild">
<Message Text="Copying unreferenced DLLs to bin" Importance="High" />
<CreateItem Include="$(UnreferencedDlls)">
<Output TaskParameter="Include" ItemName="_UnReferencedDLLs" />
</CreateItem>
<Copy SourceFiles="#(_UnReferencedDLLs)" DestinationFolder="$(OutputPath)\%(RecursiveDir)" SkipUnchangedFiles="true" />
</Target>
<Target Name="CustomCollectFiles">
<Message Text="Publishing unreferenced DLLs" Importance="High" />
<ItemGroup>
<_CustomFiles Include="$(UnreferencedDlls)" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>$(OutputPath)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
The file is published to the subfolder.
I change this line:
<DestinationRelativePath>$(OutputPath)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
to:
<DestinationRelativePath>$(OutputPath)\%(Filename)%(Extension)</DestinationRelativePath>
But it still doesn't work.
How can I force the file to be published to the same folder as the app?

I don't know if it can help you: %(RecursiveDir)
If the Include attribute contains the wildcard **, this metadata
specifies the part of the path that replaces the wildcard.
Maybe you can try to change the path of the dll. I put it into ProjectDir\lib\Debug\ and here is my code:
<PropertyGroup>
<UnreferencedDlls>lib\**\ClassLibrary1.dll</UnreferencedDlls>
</PropertyGroup>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="AfterBuild">
<Message Text="Copying unreferenced DLLs to bin" Importance="High" />
<CreateItem Include="$(UnreferencedDlls)">
<Output TaskParameter="Include" ItemName="_UnReferencedDLLs" />
</CreateItem>
<Copy SourceFiles="#(_UnReferencedDLLs)" DestinationFolder="bin\%(RecursiveDir)" SkipUnchangedFiles="true" />
</Target>
<Target Name="CustomCollectFiles">
<Message Text="Publishing unreferenced DLLs" Importance="High" />
<ItemGroup>
<_CustomFiles Include="$(UnreferencedDlls)" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>bin\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
You can also refer to this page hope it can help you.

Related

Building web project causes web config to be updated setting 'environmentVariable' to 'Development'

Time back I created a .net core with react SPA project from a template, ever since I have been unable to identify what is causing the web.config to be update each time I build.
Well, to be precise it is updated only adding back the environment variables tags, setting the environment to Development.
Can anyone please tell me how to prevent this?
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
Here is the csproj file content:
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
<IsPackable>false</IsPackable>
<SpaRoot>ClientApp\</SpaRoot>
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OData" Version="8.0.12" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="6.0.13" />
<PackageReference Include="Minded" Version="0.1.3" />
[...]
<ItemGroup>
<!-- Don't publish the SPA source files, but do show them in the project files list -->
<Content Remove="$(SpaRoot)**" />
<None Remove="$(SpaRoot)**" />
<None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules\**" />
</ItemGroup>
<ItemGroup>
<Folder Include="ClientApp\src\components\" />
</ItemGroup>
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
<!-- Ensure Node.js is installed -->
<Exec Command="node --version" ContinueOnError="true">
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
</Exec>
<Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
</Target>
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />
<!-- Include the newly-built files in the publish output -->
<ItemGroup>
<DistFiles Include="$(SpaRoot)build\**" />
<ResolvedFileToPublish Include="#(DistFiles->'%(FullPath)')" Exclude="#(ResolvedFileToPublish)">
<RelativePath>%(DistFiles.Identity)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</ResolvedFileToPublish>
</ItemGroup>
</Target>

Need help in understanding CustomFilesToInclude property in MSbuild

I have a issue in copying html files to deploy location using MSBuild.
Please help me in understanding the following:
<Target Name="CustomCollectFiles">
<ItemGroup>
<FilesForPackagingFromProject Include="#(CustomFilesToInclude)">
<DestinationRelativePath>%(CustomFilesToInclude.Dir)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<Target Name="CustomCollectFiles">
<ItemGroup>
<FilesForPackagingFromProject Include="#(CustomFilesToInclude)">
<DestinationRelativePath>%(CustomFilesToInclude.Dir)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<FilesForPackagingFromProject Include="#(CustomFilesToIncludeSkipExistingCheck)">
<DestinationRelativePath>%(CustomFilesToIncludeSkipExistingCheck.Dir)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
<Error Text="Custom file exists in project files already: %(CustomFilesToInclude.FullPath)"
Condition="Exists('$(MainProjectRootDir)\%(CustomFilesToInclude.Dir)\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
DefineCustomFiles;
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
I've never used MSDeploy.
But I'd say it just adds DestinationRelativePath metadata to item and injects targets DefineCustomFiles and CustomCollectFiles to be called before existing CopyAllFilesToSingleFolderForPackageDependsOn targets.
I see it can be used by Microsoft.Web.Publishing.targets.
The code sample you've provided is not complete to say what's going on.
It looks like this: http://sedodream.com/2010/03/10/WebDeploymentToolIncludingOtherFiles.aspx

Visual Studio Post build command line Deployment

In Visual Studio am creating a post-build event for Deploying using
md "$(SolutionDir)Deploy\bin"
which created the bin folder inside Deploy folder, inside my Solution.
How do I point this to the folder in some remote machine (where I have the web server)?
$(SolutionDir) to some other folder on a remote machine?
It may look simple to you. :) This is the first time am trying this stuff.
Thanks
The easiest way is to replace $(SolutionDir) with \\server\share
Just as an alternative, I like to keep my .sln and .csproj files "clean".
Then use a second (mini) .msbuild ( which is just a .xml file) to build the .sln, and then do these copy type events as a second action.
Here is a basic example:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="AllTargetsWrapper">
<PropertyGroup>
<WorkingCheckout>.</WorkingCheckout>
<WorkingOutputs>m:\working\outputs</WorkingOutputs>
</PropertyGroup>
<Target Name="AllTargetsWrapper">
<CallTarget Targets="Clean" />
<CallTarget Targets="Build" />
<CallTarget Targets="CopyItUp" />
</Target>
<Target Name="Clean">
<RemoveDir Directories="$(WorkingOutputs)" />
<MakeDir Directories="$(WorkingOutputs)" />
<Message Text="Cleaning done" />
</Target>
<Target Name="Build">
<MSBuild Projects="$(WorkingCheckout)\MySolution.sln" Targets="Build" Properties="Configuration=$(Configuration)">
<Output TaskParameter="TargetOutputs" ItemName="TargetOutputsItemName"/>
</MSBuild>
<Message Text="Build completed" />
</Target>
<!-- -->
<Target Name="CopyItUp" >
<ItemGroup>
<MyExcludeFiles Include="$(WorkingCheckout)\**\SuperSecretStuff.txt" />
<MyExcludeFiles Include="$(WorkingCheckout)\**\SuperSecretStuff.doc" />
</ItemGroup>
<ItemGroup>
<MyIncludeFiles Include="$(WorkingCheckout)\MyCsProject\bin\$(Configuration)\**\*.*" Exclude="#(MyExcludeFiles)"/>
</ItemGroup>
<Copy
SourceFiles="#(MyIncludeFiles)"
DestinationFiles="#(MyIncludeFiles->'$(WorkingOutputs)\%(RecursiveDir)%(Filename)%(Extension)')"
/>
</Target>
</Project>

MsBuild: Add text or custom information to the files

The below code works fine to copy the files from Source to the Destination folder. I want to make the copied files in order for example 1.zip.exe 2.NetFx.exe etc... or I.zip.exe II.NetFx.exeetc....
Basically I want to tell the user to install the tools in order. How can I do this??? Please give me some idea...!
<PropertyGroup Condition="'$(OutDir)'==''">
<OutDir>..\..\..\OutputSetup\</OutDir>
</PropertyGroup>
<ItemGroup>
<SourceFiles Include="..\tools\zip\**\*.*"/>
<SourceFiles Include="..\tools\NetFx\**\*.*"/>
</ItemGroup>
<Target Name="CopyTools">
<Copy SourceFiles="#(SourceFiles)" DestinationFiles="#($(OutDir)\%(RecursiveDir)%(Filename)%(Extension)" />
</Target>
I hope you can solve this issue as following a code like below:
<PropertyGroup Condition="'$(OutDir)'==''">
<OutDir>..\..\..\OutputSetup\</OutDir>
</PropertyGroup>
<ItemGroup>
<SourceFiles Include="..\tools\zip\**\*.*">
<Number>1</Number>
</SourceFiles>
<SourceFiles Include="..\tools\NetFx\**\*.*">
<Number>2</Number>
</SourceFiles>
</ItemGroup>
<Target Name="CopyTools">
<Copy SourceFiles="#(SourceFiles)" DestinationFiles="#($(OutDir)\%(SourceFiles.Number)%(RecursiveDir)%(Filename)%(Extension)" />
</Target>

Setting Visual Studio to automatically minifying using Ajax Minifier

I use VS 2010 I would like at the pressing of Build Button have all CSS and .JS files minified.
Following this article all is working great for JS... adding some extra code for the CSS (pasted below) I'm not able to Minifying the CSS. What I'm doing wrong here?
Thanks for your time.
<Import Project="$(MSBuildExtensionsPath)\Microsoft\MicrosoftAjax\ajaxmin.tasks" />
<Target Name="AfterBuild">
<ItemGroup>
<JS Include="**\*.js" Exclude="**\*.min.js;Scripts\*.js" />
<JS Include="**\*.css" Exclude="**\*.min.css;Scripts\*.css" />
</ItemGroup>
<AjaxMin SourceFiles="#(JS)" SourceExtensionPattern="\.js$" TargetExtension=".min.js" />
<AjaxMin SourceFiles="#(CSS)" SourceExtensionPattern="\.css$" TargetExtension=".min.css" />
</Target>
I found out the solution to my problem, more resource here
Unable to run Ajax Minifier as post-build in Visual Studio
http://ajaxmin.codeplex.com/wikipage?title=AjaxMinTask
Also very interesting:
http://www.codeproject.com/Articles/81317/Automatically-compress-embedded-JavaScript-resourc.aspx?msg=3802401&display=Mobile
<Import Project="$(MSBuildExtensionsPath)\Microsoft\MicrosoftAjax\ajaxmin.tasks" />
<Target Name="AfterBuild">
<ItemGroup>
<JS Include="**\*.js" Exclude="**\*.min.js;Scripts\*.js" />
</ItemGroup>
<ItemGroup>
<CSS Include="**\*.css" Exclude="**\*.min.css" />
</ItemGroup>
<AjaxMin
JsSourceFiles="#(JS)" JsSourceExtensionPattern="\.js$" JsTargetExtension=".min.js"
CssSourceFiles="#(CSS)" CssSourceExtensionPattern="\.css$" CssTargetExtension=".min.css" />
</Target>
On my project file I used "UsingTask" instead of "Import" and it's working:
<UsingTask TaskName="AjaxMin" AssemblyFile="$(MSBuildProjectDirectory)\..\..\packages\AjaxMin.5.14.5506.26202\tools\net40\AjaxMinTask.dll" />
<Target Name="AfterBuild">
<ItemGroup>
<JS Include="**\*.js" Exclude="**\*.min.js;Scripts\*.js" />
</ItemGroup>
<ItemGroup>
<CSS Include="**\*.css" Exclude="**\*.min.css" />
</ItemGroup>
<AjaxMin
JsSourceFiles="#(JS)" JsSourceExtensionPattern="\.js$" JsTargetExtension=".min.js"
CssSourceFiles="#(CSS)" CssSourceExtensionPattern="\.css$" CssTargetExtension=".min.css" />
</Target>

Resources