<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alex</title>
    <description>The latest articles on DEV Community by Alex (@runner2022).</description>
    <link>https://dev.to/runner2022</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3841757%2Febf8eafa-81b6-45a6-ad6f-8e564444d14f.webp</url>
      <title>DEV Community: Alex</title>
      <link>https://dev.to/runner2022</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/runner2022"/>
    <language>en</language>
    <item>
      <title>WPF - Make Source Code Harder to Mess With</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Wed, 25 Mar 2026 16:09:48 +0000</pubDate>
      <link>https://dev.to/runner2022/wpf-make-source-code-harder-to-mess-with-5ek9</link>
      <guid>https://dev.to/runner2022/wpf-make-source-code-harder-to-mess-with-5ek9</guid>
      <description>&lt;h2&gt;
  
  
  Context, Please
&lt;/h2&gt;

&lt;p&gt;How can you make your WPF project harder to copy elsewhere, decompile, and modify?&lt;/p&gt;

&lt;h2&gt;
  
  
  Assumptions
&lt;/h2&gt;

&lt;p&gt;You know what WPF is and have made a WPF project before.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/answers/questions/1749958/how-to-protect-a-wpf-application-from-reverse-engi" rel="noopener noreferrer"&gt;Stealing information from this&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Application Protection
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Disclaimer
&lt;/h3&gt;

&lt;p&gt;If your program is installed entirely on someone's PC, you can't prevent them from stealing, decompiling, and copying your code. The only thing you &lt;em&gt;can&lt;/em&gt; do slow them down by making things more difficult.&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 1: Encryption Algorithms
&lt;/h3&gt;

&lt;p&gt;Use encryption algorithms (AES, DES, etc.) for sensitive info such as passwords. (Where would you store the key?)&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 2: Dynamic Code Generation
&lt;/h3&gt;

&lt;p&gt;Not sure what this one is&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Obfuscation
&lt;/h2&gt;

&lt;p&gt;Basically, making the code harder to read. Not ideal, but could slow a bad actor down.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dotfuscator
&lt;/h3&gt;

&lt;p&gt;This is the &lt;a href="https://learn.microsoft.com/en-us/visualstudio/ide/dotfuscator/?view=vs-2022" rel="noopener noreferrer"&gt;native service that comes with Visual Studio&lt;/a&gt;. If you're making commercial software this will cost money.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Methods
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Method 1: Strong name
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Method 2: Compile relevant method int unmanaged code
&lt;/h3&gt;

&lt;p&gt;According to the post where this case from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Function: Unmanaged code is generally not decompilable by current decompilation tools.&lt;/p&gt;

&lt;p&gt;Condition: You must use VC++.NET unmanaged mode to write dll, and then use VC++ managed mode to build a project to introduce this native code dll. Finally, a Dotnet assembly dll is generated. Then this assembly contains both managed code and unmanaged code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/cpp/dotnet/mixed-native-and-managed-assemblies?view=msvc-170&amp;amp;redirectedfrom=MSDN" rel="noopener noreferrer"&gt;I think this post is talking about this.&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>nRF Connect Set Up Board</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Wed, 25 Mar 2026 14:41:08 +0000</pubDate>
      <link>https://dev.to/runner2022/nrf-connect-set-up-board-4jl1</link>
      <guid>https://dev.to/runner2022/nrf-connect-set-up-board-4jl1</guid>
      <description>&lt;h2&gt;
  
  
  Context, Please
&lt;/h2&gt;

&lt;p&gt;nRF Connect is a development platform for microcontroller boards from Nordic.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Install Nordic nRF Connect for VS Code</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Wed, 25 Mar 2026 13:22:17 +0000</pubDate>
      <link>https://dev.to/runner2022/install-nordic-nrf-connect-for-vs-code-fe9</link>
      <guid>https://dev.to/runner2022/install-nordic-nrf-connect-for-vs-code-fe9</guid>
      <description>&lt;p&gt;&lt;strong&gt;Table of Contents&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Context, Please&lt;/li&gt;
&lt;li&gt;Assumptions&lt;/li&gt;
&lt;li&gt;1. Installation&lt;/li&gt;
&lt;li&gt;2. Creating an application&lt;/li&gt;
&lt;li&gt;3. Building an Application&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Context, Please
&lt;/h2&gt;

&lt;p&gt;Nordic is a company that makes embedded Microcontrollers. nRF Connect is their development platform which you can install on the text editor VSCode. This post shows how to do that part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Assumptions
&lt;/h2&gt;

&lt;p&gt;I am assuming you have worked with VSCode before and know about VSCode extensions.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Installation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install nRF Command line tools

&lt;ul&gt;
&lt;li&gt;May be asked to install segger jlink driver - check yes to that&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Install nRF Connect SDK

&lt;ul&gt;
&lt;li&gt;This is now done through the VS Code extension&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Install SDK

&lt;ul&gt;
&lt;li&gt;Under the VS Code extension you just installed&lt;/li&gt;
&lt;li&gt;Click Manage SDKs -&amp;gt; install SD&lt;/li&gt;
&lt;li&gt;tag release to install - keep in simple&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Enable for workspace only

&lt;ul&gt;
&lt;li&gt;extensions icon on sidebar -&amp;gt; gear icon on nrfConnect for VS Code Extension Pack&lt;/li&gt;
&lt;li&gt;Disable -&amp;gt; Enable (workspace)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Creating an application
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open nRF connect extension. Here are your options

&lt;ul&gt;
&lt;li&gt;Manage toolchains - install new toolchains or revert to old toolchains&lt;/li&gt;
&lt;li&gt;Manage SDKs - install new SDK or revert to old SDK&lt;/li&gt;
&lt;li&gt;Open an existing application&lt;/li&gt;
&lt;li&gt;Create a new application&lt;/li&gt;
&lt;li&gt;Create a new board&lt;/li&gt;
&lt;li&gt;Browse samples&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Will "create a new application" for this

&lt;ul&gt;
&lt;li&gt;Options

&lt;ul&gt;
&lt;li&gt;Create a blank application&lt;/li&gt;
&lt;li&gt;Copy a sample&lt;/li&gt;
&lt;li&gt;Browse application index&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Select "copy a sample"

&lt;ul&gt;
&lt;li&gt;Can sort by the module (to the right of "Create New App from sample")&lt;/li&gt;
&lt;li&gt;Can filter by boards compatible with the sample&lt;/li&gt;
&lt;li&gt;Search for the name&lt;/li&gt;
&lt;li&gt;Will be copying blinky for this&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Enter the directory where you want to create the project&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Building an Application
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create a build configuration

&lt;ul&gt;
&lt;li&gt;Tells the compiler which board files to include in your build&lt;/li&gt;
&lt;li&gt;This making the output compatible with your board&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzzbf7pa5e3og484pcqgs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzzbf7pa5e3og484pcqgs.png" alt=" " width="522" height="134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Under "Add Build Configuration"

&lt;ul&gt;
&lt;li&gt;Select your development kit&lt;/li&gt;
&lt;li&gt;The configuration for your board is stored in a prj.conf file (which is generated based on your board selection)

&lt;ul&gt;
&lt;li&gt;Can add extra configurations with the "Add Fragments" button&lt;/li&gt;
&lt;li&gt;Can add arguments with the "Add argument" button&lt;/li&gt;
&lt;li&gt;Can leave the build directory name as "build"&lt;/li&gt;
&lt;li&gt;Can enable debugging with "Enable debug options"&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;Here's how you build
&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9uumc8j16wwvwbh8u7xa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9uumc8j16wwvwbh8u7xa.png" alt=" " width="520" height="134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can also save the build configuration&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>zephyr</category>
      <category>nordic</category>
      <category>embedded</category>
    </item>
    <item>
      <title>A Rant about Windows and Printers</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Tue, 24 Mar 2026 17:50:43 +0000</pubDate>
      <link>https://dev.to/runner2022/a-rant-about-windows-and-printers-35ao</link>
      <guid>https://dev.to/runner2022/a-rant-about-windows-and-printers-35ao</guid>
      <description>&lt;p&gt;Reading about the history of windows and printer drivers was...enlightening&lt;/p&gt;

&lt;h3&gt;
  
  
  Windows V3 Printer Driver
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This is the classic scenario where you download the printer driver onto your computer&lt;/li&gt;
&lt;li&gt;And the printer manufacturers would each create their own (crappy) driver that follows the V3 model&lt;/li&gt;
&lt;li&gt;These were fine I guess but vulnerable to this "PrintNightmare" vulnerability so Windows freaked out and made the...&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Windows V4 Printer Drivers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Then there was V4 which were apparently more secure but a pain in the BUTT&lt;/li&gt;
&lt;li&gt;The way these work is the driver stuff is located on the &lt;em&gt;printer/printer server&lt;/em&gt;, not your computer

&lt;ul&gt;
&lt;li&gt;Instead Windows will grab the needed driver stuff from the printer/print server&lt;/li&gt;
&lt;li&gt;If Windows says a printer has the &lt;strong&gt;"Microsoft enhanced Point and Print driver"&lt;/strong&gt;, that's what that means&lt;/li&gt;
&lt;li&gt;I think you can have a V4 driver on your computer locally if the driver on your computer is the &lt;em&gt;exact&lt;/em&gt; same as the printer/print server?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;This is honestly confusing&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Internet Printing Protocol (the GOAT)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The newest is the "Internet Printing Protocol", which shouldn't require any drivers at all&lt;/li&gt;
&lt;li&gt;IPP is from IEEE, not Windows&lt;/li&gt;
&lt;li&gt;As of 2026 Windows prefers IPP over V3/V4

&lt;ul&gt;
&lt;li&gt;Microsoft's WPP and Universal Print are related to IPP (I think)&lt;/li&gt;
&lt;li&gt;Windows stopped packaging V3/V4 third-party drivers with Windows updates&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;This is what Apple's AirPrint is based on&lt;/li&gt;

&lt;li&gt;The problem is that:

&lt;ul&gt;
&lt;li&gt;not all printers support IPP (though most do)&lt;/li&gt;
&lt;li&gt;some printers you have to enable IPP manually&lt;/li&gt;
&lt;li&gt;if there are any settings that the printer manufacturer excluded from IPP then GOOD LUCK BUDDY&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;In case you can't tell I'm biased towards this one&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;TLDR; For a while the default was that each printer manufacturer made their own crappy drivers that the user had to deal with. IPP should (hopefully) fix this by being a universal standard. Kinda like RCS but for printing. Just my opinion, subject to change.&lt;/p&gt;

</description>
      <category>ipp</category>
      <category>windows</category>
      <category>printer</category>
    </item>
    <item>
      <title>Publish WPF Project with Azure DevOps Pipeline</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Tue, 24 Mar 2026 14:25:24 +0000</pubDate>
      <link>https://dev.to/runner2022/azure-pipeline-5gkm</link>
      <guid>https://dev.to/runner2022/azure-pipeline-5gkm</guid>
      <description>&lt;p&gt;&lt;strong&gt;Table of Contents&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Does Any Of This Mean?&lt;/li&gt;
&lt;li&gt;trigger, pool, variables&lt;/li&gt;
&lt;li&gt;
DotNetCoreCLI@2

&lt;ul&gt;
&lt;li&gt;command&lt;/li&gt;
&lt;li&gt;projects&lt;/li&gt;
&lt;li&gt;zipAfterPublish&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Publish Artifacts aka Spit Out The Files You Want

&lt;ul&gt;
&lt;li&gt;Step 1: Publish Output&lt;/li&gt;
&lt;li&gt;Step 2: PublishBuildArtifacts@1&lt;/li&gt;
&lt;li&gt;Settings UI&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;PowerShell@2&lt;/li&gt;

&lt;li&gt;

Troubleshooting

&lt;ul&gt;
&lt;li&gt;Can't create two projects at a time&lt;/li&gt;
&lt;li&gt;Not found PathToPublish&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Context, Please
&lt;/h2&gt;

&lt;p&gt;For context, Azure DevOps is a service from Microsoft that lets you store the history of your code (version control) and add processes for automatically publishing software files (e.g. .exe files) to download.&lt;/p&gt;

&lt;p&gt;A pipeline is how you can add automated steps to build your project, and publish .exe files that your computer can run, for example.&lt;/p&gt;

&lt;p&gt;This post is for creating a pipeline using YAML in Azure DevOps, specifically, YAML being a file type. I'm assuming you've gotten to the point where you have a blank or template YAML file for your pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Assumptions
&lt;/h2&gt;

&lt;p&gt;I am assuming you know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Git is&lt;/li&gt;
&lt;li&gt;What Git branches are&lt;/li&gt;
&lt;li&gt;Developing in .NET WPF&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am also assuming you have Azure DevOps set up.&lt;/p&gt;

&lt;h2&gt;
  
  
  trigger, pool, variables
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;

&lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Default&lt;/span&gt;
  &lt;span class="na"&gt;demands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Agent.OS -equals Windows_NT&lt;/span&gt;

&lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;solution&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**/*.sln'&lt;/span&gt;
  &lt;span class="na"&gt;buildPlatform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Any&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;CPU'&lt;/span&gt;
  &lt;span class="na"&gt;buildConfiguration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Release'&lt;/span&gt;
  &lt;span class="na"&gt;buildRuntime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;win-x64'&lt;/span&gt;
  &lt;span class="na"&gt;buildFramework&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;net10.0-windows10.0.19041.0'&lt;/span&gt;
  &lt;span class="na"&gt;system.debug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;true'&lt;/span&gt; 
  &lt;span class="c1"&gt;# setting system.debug to true will let you see more output info&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Trigger&lt;/strong&gt; - specifies which branch will cause the pipeline to run &lt;br&gt;
&lt;strong&gt;pool&lt;/strong&gt; - a pool contains a collection of agents, each agent is a piece of software running on a machine, virtual or otherwise (this is set up for my at my company, though setting this up is probably an article of its own)&lt;br&gt;
&lt;strong&gt;demands&lt;/strong&gt; - basically saying the agent pool HAS to be able to handle these things (Windows_NT in this case)&lt;br&gt;
&lt;strong&gt;variables&lt;/strong&gt; - don't overthink this; it's literally just variables. These will get used later&lt;/p&gt;
&lt;h2&gt;
  
  
  DotNetCoreCLI@2
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DotNetCoreCLI@2&lt;/span&gt;
  &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Publish&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Example&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Project'&lt;/span&gt;
  &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;publish&lt;/span&gt;
    &lt;span class="na"&gt;projects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;*/Example_Project_Name.csproj'&lt;/span&gt;
    &lt;span class="na"&gt;publishWebProjects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="na"&gt;arguments&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;--configuration&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;$(buildConfiguration)&lt;/span&gt; 
      &lt;span class="s"&gt;--runtime&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;$(buildRuntime)&lt;/span&gt; 
      &lt;span class="s"&gt;--framework&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;$(buildFramework)&lt;/span&gt;
      &lt;span class="s"&gt;--self-contained&lt;/span&gt; 
      &lt;span class="s"&gt;--output&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;$(Build.ArtifactStagingDirectory)'&lt;/span&gt;
    &lt;span class="na"&gt;zipAfterPublish&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;According to Microsoft, DotNetCoreCLI@2 is used to: "Build, test, package, or publish a .NET application, or run a custom .NET CLI command." &lt;/p&gt;

&lt;p&gt;The @2 is the version number for this command. It used to be @1 and may change to @3 at some point.&lt;/p&gt;

&lt;p&gt;There are quite a few options to put under this:&lt;br&gt;&lt;br&gt;
command | projects | custom | arguments | restoreArguments | zipAfterPublish | publishTestResults | nuGetFeedType | configuration | requestTimeout | publishWebProjects | modifyOutputPath&lt;/p&gt;
&lt;h3&gt;
  
  
  command
&lt;/h3&gt;

&lt;p&gt;Options for command include:&lt;br&gt;&lt;br&gt;
build | push | pack | publish | restore | run | test | custom&lt;/p&gt;
&lt;h3&gt;
  
  
  projects
&lt;/h3&gt;

&lt;p&gt;According to Microsoft:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;projects - Path to project(s) or solution(s)&lt;br&gt;
string. Optional. Use when command = build || command = restore || command = run || command = test || command = custom || publishWebProjects = false.&lt;/p&gt;

&lt;p&gt;The path to the .csproj or .sln file(s) to use. You can use wildcards (e.g. **/*.csproj for all .csproj files in all subfolders). For more information, see the file matching patterns reference.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If there are multiple projects in the solution, put "**/placeholder_text.csproj", otherwise put "*/placeholder_text.csproj". I think, not 100% sure here. You may have to play around with this and you may throw a "can't create two projects at a time" error.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This path is relative to the root of the repository regardless of the workingDirectory setting.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By default, workingDirectory is $(System.DefaultWorkingDirectory)&lt;/p&gt;
&lt;h3&gt;
  
  
  zipAfterPublish
&lt;/h3&gt;

&lt;p&gt;Set this to true, unless you have another dedicated way you would like to publish this.&lt;/p&gt;
&lt;h2&gt;
  
  
  Publish Artifacts aka Spit Out The Files You Want
&lt;/h2&gt;

&lt;p&gt;There are two arguments involved with publishing the artifacts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The "publish" command

&lt;ol&gt;
&lt;li&gt;Will build and publish the project&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;"output" argument&lt;/strong&gt; tells the command where to place the files&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;The "PublishBuildArtifacts" task

&lt;ol&gt;
&lt;li&gt;Will pick up and spit out the specified files onto the "Build Artifacts" area (where you can download them!)&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;"pathToPublish"&lt;/strong&gt; input tells the task where to pick up the files&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both the &lt;strong&gt;"output" argument&lt;/strong&gt; and the &lt;strong&gt;"pathToPublish"&lt;/strong&gt; should be based on the "$(Build.ArtifactStagingDirectory).&lt;/p&gt;

&lt;p&gt;To figure out where the build/publish command is placing files, check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The "output" argument for the build/publish command&lt;/li&gt;
&lt;li&gt;The command line output for the build/publish step on the DevOps page
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AbbottLabsControllerTester -&amp;gt; C:\agent_filepath_goes_here\s\...
AbbottLabsControllerTester -&amp;gt; C:\agent_filepath_goes_here\a\output_argument_will_be_here

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The location for the ArtifactStagingDirectory is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\agent_filepath_goes_here\a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 1: Publish Output
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DotNetCoreCLI@2&lt;/span&gt;
  &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Publish&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;project'&lt;/span&gt;
  &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;publish'&lt;/span&gt;
    &lt;span class="na"&gt;projects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$(project)'&lt;/span&gt;
    &lt;span class="na"&gt;publishWebProjects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="na"&gt;arguments&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;--configuration&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;$(buildConfiguration)&lt;/span&gt; 
      &lt;span class="s"&gt;--runtime&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;$(buildRuntime)&lt;/span&gt; 
      &lt;span class="s"&gt;--self-contained&lt;/span&gt; 
      &lt;span class="s"&gt;--output&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;$(Build.ArtifactStagingDirectory)\Example_Project_V$(Build.BuildNumber)&lt;/span&gt;
      &lt;span class="s"&gt;--framework&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;$(buildFramework)'&lt;/span&gt;
    &lt;span class="na"&gt;zipAfterPublish&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;modifyOutputPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I recommend setting "modifyOutputPath" to false. If &lt;a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/dotnet-core-cli-v2?view=azure-pipelines#inputs" rel="noopener noreferrer"&gt;"modifyOutputPath"&lt;/a&gt; is set to true, the .zip folder will just have the project name and not the custom name you may want to have.  StackOverflow post to back me up&lt;/p&gt;

&lt;p&gt;If modifyOutputPath: true&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...\a\Abbott_Labs_Tester_V20260324.26\AbbottLabsControllerTester\

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ExampleProject Published Files

&lt;ul&gt;
&lt;li&gt;Example_Project_V20260324.30

&lt;ul&gt;
&lt;li&gt;ExampleProjectName.zip (project files are in here)
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;If modifyOutputPath: false&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...\a\Abbott_Labs_Tester_V20260324.32\

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ExampleProject Published Files

&lt;ul&gt;
&lt;li&gt;Example_Project_V20260324.30

&lt;ul&gt;
&lt;li&gt;Example_Project_V20260324.30.zip (project files are in here)
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: PublishBuildArtifacts@1
&lt;/h3&gt;

&lt;p&gt;It's not enough to just publish/create the outputs, you need to tell the pipeline to spit them out for you to download.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PublishBuildArtifacts@1&lt;/span&gt;
  &lt;span class="s"&gt;inputs&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;pathToPublish&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$(Build.ArtifactStagingDirectory)'&lt;/span&gt;
    &lt;span class="na"&gt;artifactName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ExampleProject&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Published&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Files'&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0t2q9e00897tn0ifud9t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0t2q9e00897tn0ifud9t.png" alt=" " width="296" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Important notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;pathToPublish&lt;/strong&gt; tells the pipeline where to &lt;strong&gt;look&lt;/strong&gt; for the files

&lt;ul&gt;
&lt;li&gt;if there's nothing there it will throw a warning and there will be no artifacts&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Both the "pathToPublish" and "artifactName" are required. &lt;/li&gt;

&lt;li&gt;Note! Don't forget the "." in &lt;a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&amp;amp;tabs=yaml#build-variables-devops-services" rel="noopener noreferrer"&gt;Build.ArtifactStagingDirectory&lt;/a&gt;!&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Settings UI
&lt;/h3&gt;

&lt;p&gt;You can also add tasks through the UI on DevOps.&lt;br&gt;
If you click on the little gray "settings" text above yaml commands it will show you the settings for said command.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcn1qv0132fg6u5qz3tk3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcn1qv0132fg6u5qz3tk3.png" alt=" " width="263" height="75"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  PowerShell@2
&lt;/h2&gt;

&lt;p&gt;I'm not worrying about this for my project but I figured I'd write it down at least.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PowerShell@2&lt;/span&gt;
  &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Build&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Setup'&lt;/span&gt;
  &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;         
    &lt;span class="na"&gt;targetType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;filePath'&lt;/span&gt;
    &lt;span class="na"&gt;filePath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$(Build.Repository.LocalPath)\DTC&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Software\AW_DTC\buildSetup.ps1'&lt;/span&gt;
    &lt;span class="na"&gt;arguments&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-publishDirPath&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"$(Build.ArtifactStagingDirectory)\PLACEHOLDER_TEXT"&lt;/span&gt;
      &lt;span class="s"&gt;-publishZipPath&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"$(Build.ArtifactStagingDirectory)\Zip"&lt;/span&gt;
      &lt;span class="s"&gt;-publishSetupPath&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"$(Build.ArtifactStagingDirectory)\Setup"&lt;/span&gt; 
      &lt;span class="s"&gt;-nsiFilePath&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"$(Build.Repository.LocalPath)\DTC&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Software\AW_DTC\AW_DTC.nsi"'&lt;/span&gt;
    &lt;span class="na"&gt;workingDirectory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$(Build.ArtifactStagingDirectory)'&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The parameters such as publishZipPath are custom to the powershell file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can't create two projects at a time
&lt;/h3&gt;

&lt;p&gt;Under your publish step, make sure the filepath to your .csproj file is correct. &lt;/p&gt;

&lt;h3&gt;
  
  
  Not found PathToPublish
&lt;/h3&gt;

&lt;p&gt;The PublishBuildArtifacts has a "pathToPublish" input that tells PublishBuildArtifacts where to look. If the path specified in "pathToPublish" does not exist, this will get thrown.&lt;/p&gt;

</description>
      <category>wpf</category>
      <category>azuredevops</category>
      <category>cicd</category>
    </item>
  </channel>
</rss>
