<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title></title>
  <subtitle></subtitle>
  <id>https://www.endpointdev.com/blog/tags/windows/</id>
  <link href="https://www.endpointdev.com/blog/tags/windows/"/>
  <link href="https://www.endpointdev.com/blog/tags/windows/" rel="self"/>
  <updated>2025-05-06T00:00:00+00:00</updated>
  <author>
    <name>End Point Dev</name>
  </author>
  
    <entry>
      <title>Windows 10 End of Life: What Are Your Upgrade Options?</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2025/05/windows-10-end-of-life/"/>
      <id>https://www.endpointdev.com/blog/2025/05/windows-10-end-of-life/</id>
      <published>2025-05-06T00:00:00+00:00</published>
      <author>
        <name>Dan Briones</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2025/05/windows-10-end-of-life/cloudy-sunrise.webp&#34; alt=&#34;The camera looks over houses and green and red trees at a mountains just visible below a thick layer of clouds. In the center of the image is a canyon lit by sunlight, which peeks through the clouds above the canyon.&#34;&gt;&lt;/p&gt;
&lt;!-- Photo by Seth Jensen, 2025. --&gt;
&lt;p&gt;As technology evolves, so do operating systems. Microsoft has announced the end of support for Windows 10, meaning that after October 14, 2025, your device will no longer receive critical security updates. This blog post will discuss what this means for you and your upgrade options to Windows 11.&lt;/p&gt;
&lt;p&gt;You can search for all Microsoft software lifecycles on the &lt;a href=&#34;https://learn.microsoft.com/en-us/lifecycle/&#34;&gt;Microsoft Lifecycle Policy page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Support will end on October 14, 2025, for these editions of Windows 10:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows 10 Enterprise &amp;amp; Education&lt;/li&gt;
&lt;li&gt;Windows 10 Home &amp;amp; Pro&lt;/li&gt;
&lt;li&gt;Windows 10 IoT Enterprise&lt;/li&gt;
&lt;li&gt;Windows 10 Enterprise LTSB 2015&lt;/li&gt;
&lt;li&gt;Windows 10 Team (Surface Hub)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can see a list of all Microsoft products whose support will end in 2025 on &lt;a href=&#34;https://learn.microsoft.com/en-us/lifecycle/end-of-support/end-of-support-2025&#34;&gt;Microsoft&amp;rsquo;s website&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;what-does-end-of-life-mean&#34;&gt;What Does End of Life Mean?&lt;/h3&gt;
&lt;p&gt;End of life (EOL) for an operating system means that the software vendor will no longer provide updates, security patches, or technical support. While your computer will still function, it will be more vulnerable to security threats. Continuing to use an unsupported operating system puts your data at risk.&lt;/p&gt;
&lt;h3 id=&#34;why-upgrade-to-windows-11&#34;&gt;Why Upgrade to Windows 11?&lt;/h3&gt;
&lt;p&gt;Windows 11 is the latest version of Microsoft&amp;rsquo;s operating system. It offers several benefits, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Enhanced Security:&lt;/strong&gt; Windows 11 includes the latest security features to protect your data and privacy. Regular security updates are the biggest reason to upgrade.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Modern Interface:&lt;/strong&gt; A refreshed design intended to offer a more user-friendly experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improved Performance:&lt;/strong&gt; Optimized for better speed and efficiency.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;New Features:&lt;/strong&gt; Access to innovative tools and functionalities.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;options-for-upgrading-to-windows-11&#34;&gt;Options for Upgrading to Windows 11&lt;/h3&gt;
&lt;p&gt;You have a few options when it comes to upgrading from Windows 10 to Windows 11.&lt;/p&gt;
&lt;h4 id=&#34;check-system-compatibility&#34;&gt;Check System Compatibility&lt;/h4&gt;
&lt;p&gt;First, determine if your current computer meets the minimum system requirements for Windows 11. You can use Microsoft&amp;rsquo;s &lt;a href=&#34;https://support.microsoft.com/en-us/windows/how-to-use-the-pc-health-check-app-9c8abd9b-03ba-4e67-81ef-36f37caa7844&#34;&gt;PC Health Check app&lt;/a&gt; to see if your device is compatible. You can download it directly at &lt;a href=&#34;https://aka.ms/GetPCHealthCheckApp&#34;&gt;https://aka.ms/GetPCHealthCheckApp&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;1-upgrade-your-existing-device&#34;&gt;1. Upgrade Your Existing Device&lt;/h4&gt;
&lt;p&gt;If your computer is compatible, you can upgrade to Windows 11 directly. This process involves downloading and installing the new operating system. Ensure you have backed up your important files before starting the upgrade.&lt;/p&gt;
&lt;p&gt;You can download the OS and read more about the upgrade process &lt;a href=&#34;https://www.microsoft.com/en-us/software-download/windows11&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;2-purchase-a-new-device&#34;&gt;2. Purchase a New Device&lt;/h4&gt;
&lt;p&gt;If your current computer does not meet the system requirements, or if you prefer a new device, consider purchasing a new computer with Windows 11 pre-installed. This ensures you have the latest hardware and software.&lt;/p&gt;
&lt;h4 id=&#34;3-bypass-the-hardware-checks&#34;&gt;3. Bypass the Hardware Checks&lt;/h4&gt;
&lt;p&gt;When a computer is relatively new you can use known registry hacks to bypass the hardware in the compatibility checks. I have done this many times. Sometimes it is worth the savings and hassle of migrating to a new PC and sometimes it is not.&lt;/p&gt;
&lt;p&gt;Microsoft has quietly removed information in its support documentation regarding installing Windows 11 via a (not recommended) workaround that allowed the OS to be hosted on a PC that doesn&amp;rsquo;t meet the hardware requirements.&lt;/p&gt;
&lt;p&gt;If you are interested in bypassing the requirement checks, you can read more about it &lt;a href=&#34;https://techcommunity.microsoft.com/discussions/windows11/how-to-bypass-windows-11-system-requirements-during-installation-on-an-old-lapto/4060758&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;considerations-when-upgrading&#34;&gt;Considerations When Upgrading&lt;/h3&gt;
&lt;p&gt;Before making a decision, consider the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cost:&lt;/strong&gt; Upgrading your existing computer may be more cost-effective than buying a new one, but consider the long-term benefits of a new device.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data Backup:&lt;/strong&gt; Always back up your data before any major system changes. If you have a Microsoft Live ID, just make sure your actual data is in our OneDrive Cloud Storage and create a backup of folders like Desktop, Documents, Music, Pictures, Videos, and Downloads. Once you log in to the new computer with your Live ID, all your data and settings should download automatically.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Software Compatibility:&lt;/strong&gt; Ensure your essential applications are compatible with Windows 11, especially business applications like QuickBooks and others, which could be costly to upgrade but necessary.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;The end of life for Windows 10 means it&amp;rsquo;s time to consider upgrading to Windows 11. Whether you upgrade your existing device or purchase a new one, staying up to date with the latest operating system is crucial for security and performance. Evaluate your options, consider your needs, and make the choice that best suits you.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>SSH Key Auth using KeeAgent with Git Bash and Windows CLI OpenSSH</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/"/>
      <id>https://www.endpointdev.com/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/</id>
      <published>2022-08-08T00:00:00+00:00</published>
      <author>
        <name>Ron Phipps</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/street-couch.webp&#34; alt=&#34;A leather couch in surprisingly good condition sits on a patch of grass between the sidewalk and the road. Harsh sunlight casts shadows of trees and buildings on the street and couch.&#34;&gt;&lt;/p&gt;
&lt;!-- Photo by Seth Jensen --&gt;
&lt;p&gt;In a &lt;a href=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/&#34;&gt;previous blog post&lt;/a&gt; we showed how to configure KeePass and KeeAgent on Windows to provide SSH key agent forwarding with confirmation while using PuTTY and other PuTTY agent compatible programs. In this post we’ll expand on that by showing how to use the same key agent to provide SSH key auth when using Git Bash and the Windows command line OpenSSH.&lt;/p&gt;
&lt;h3 id=&#34;git-bash-support&#34;&gt;Git Bash support&lt;/h3&gt;
&lt;p&gt;Open KeePass, click on Tools → Options, select the KeeAgent tab.&lt;/p&gt;
&lt;p&gt;Create &lt;code&gt;C:\Temp&lt;/code&gt; if it does not exist.&lt;/p&gt;
&lt;p&gt;Check the two boxes in the Cygwin/MSYS Integration section.&lt;/p&gt;
&lt;p&gt;Directly after each box, fill in the path: &lt;code&gt;C:\Temp\cygwin-ssh.socket&lt;/code&gt; for the Cygwin compatible socket file, and &lt;code&gt;C:\Temp\msys-ssh.socket&lt;/code&gt; for the msysGit compatible socket file.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/1-options-gitbash.webp&#34; alt=&#34;KeePass options, open to the KeeAgent tab. Highlighted is the Cygwin/MSYS section, with two boxes checked. One reads &amp;ldquo;Create Cygwin compatible socket file (works with some versions of MSYS)&amp;rdquo;. The other reads &amp;ldquo;Create msysGit compatible socket file&amp;rdquo;. After each is the path described above.&#34;&gt;&lt;/p&gt;
&lt;p&gt;Click OK.&lt;/p&gt;
&lt;p&gt;Open Git Bash.&lt;/p&gt;
&lt;p&gt;Create the file &lt;code&gt;~/.bash_profile&lt;/code&gt; with the contents:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;test&lt;/span&gt; -f ~/.profile &amp;amp;&amp;amp; . ~/.profile
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;test&lt;/span&gt; -f ~/.bashrc &amp;amp;&amp;amp; . ~/.bashrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Create the file &lt;code&gt;~/.bashrc&lt;/code&gt; with the contents:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;SSH_AUTH_SOCK&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;C:\Temp\cygwin-ssh.socket&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Close and reopen Git Bash.&lt;/p&gt;
&lt;p&gt;You should now be able to SSH with Git Bash using your loaded SSH key and a dialog box should appear to approve the use of the key.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/2-gitbash-ssh.webp&#34; alt=&#34;Git Bash running ssh to a redacted server, with a dialog box reading &amp;ldquo;(ssh) has requested to use the SSH key (redacted) with fingerprint (redacted). Do you want to allow this?&amp;rdquo; The dialog&amp;rsquo;s &amp;ldquo;No&amp;rdquo; button is selected by default.&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;windows-command-line-openssh-support&#34;&gt;Windows command line OpenSSH support&lt;/h3&gt;
&lt;p&gt;Open KeePass, click on Tools → Options, select the KeeAgent tab.&lt;/p&gt;
&lt;p&gt;Scroll down and click on the box next to “Enable agent for Windows OpenSSH (experimental).”&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/3-options-windowsopenssh.webp&#34; alt=&#34;KeePass options open to the KeeAgent tab. Inside a scrollable list is a checked checkbox reading &amp;ldquo;Enable agent for Windows OpenSSH (experimental)&amp;rdquo;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Click OK.&lt;/p&gt;
&lt;p&gt;Open a Windows Command Prompt.&lt;/p&gt;
&lt;p&gt;You should now be able to SSH with Windows CLI using your loaded SSH key and a dialog box should appear to approve the use of the key.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/4-windows-cli-ssh.webp&#34; alt=&#34;Windows Command Prompt running SSH, with the same KeePass dialog box asking approval for using the loaded SSH key&#34;&gt;&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Windows SSH key agent forwarding confirmation</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/"/>
      <id>https://www.endpointdev.com/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/</id>
      <published>2022-07-26T00:00:00+00:00</published>
      <author>
        <name>Ron Phipps</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/sunset.webp&#34; alt=&#34;A sunset with silhouetted construction equipment&#34;&gt;&lt;/p&gt;
&lt;!-- Photo by Seth Jensen --&gt;
&lt;p&gt;At End Point we use SSH keys extensively, primarily for authentication with servers for remote shell access as well as with Git services including GitHub, GitLab, and Bitbucket. Most of the time the servers we are attempting to reach are blocked from direct access and require that we go through an intermediate “jump server”.&lt;/p&gt;
&lt;p&gt;Because of this need to jump from server to server we utilize SSH key forwarding that allows us to use the private key stored on our local system to authenticate with each of the servers in the chain. When we reach our destination server we can use the same private key to authenticate with the Git hosting service and perform git commands without having to enter a password.&lt;/p&gt;
&lt;p&gt;One of the best practices when using SSH key forwarding is to use an option called key confirmation. When key confirmation is turned on, each time a request is made to use the private key that is loaded in the SSH agent a prompt will appear on your local machine to approve the use of the key. This reduces the ability for an attacker to use your private key without approval.&lt;/p&gt;
&lt;p&gt;For the longest time SSH key confirmation was not available on Windows. One of the most popular SSH clients on Windows is PuTTY and its agent (pageant) does not support the option. Many other SSH key compatible Windows applications use PuTTY’s agent for SSH key caching and as a result these applications also lack the ability for key confirmation.&lt;/p&gt;
&lt;h3 id=&#34;keepass-and-keeagent&#34;&gt;KeePass and KeeAgent&lt;/h3&gt;
&lt;p&gt;To use key confirmation on Windows we need to utilize two programs, KeePass and KeeAgent. KeePass is an open source password manager and KeeAgent is a plugin for KeePass that provides a PuTTY-compatible SSH key agent. It also appears that KeeAgent has support for integration with the Windows shell, Cygwin/MSYS, and Git Bash.&lt;/p&gt;
&lt;p&gt;The instructions below will assume that you already have a SSH key in PuTTY that you’d like to use with key confirmation and that you have previously used PuTTY with key forwarding.&lt;/p&gt;
&lt;p&gt;You should start by &lt;a href=&#34;https://keepass.info/&#34;&gt;installing KeePass&lt;/a&gt;. Then &lt;a href=&#34;https://lechnology.com/software/keeagent/&#34;&gt;install KeeAgent&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once both are installed create a new KeePass database, or use your existing database if you are already a KeePass user.&lt;/p&gt;
&lt;p&gt;Add a new entry to the database and name it SSH key. Enter your SSH key password into the Password and Repeat fields.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/1-add-entry.webp&#34; alt=&#34;KeePass’s Add Entry screen&#34;&gt;&lt;/p&gt;
&lt;p&gt;Then click on the KeeAgent tab and check ‘Allow KeeAgent to use this entry’.&lt;/p&gt;
&lt;p&gt;In the Private Key section select External File and point it at your PuTTY private key. If you have entered the correct password on the first tab you should see your key comment and fingerprint listed. Then press OK.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/2-add-entry.webp&#34; alt=&#34;The KeeAgent tab in Add Entry&#34;&gt;&lt;/p&gt;
&lt;p&gt;Verify that confirmation is enabled by clicking on Tools -&amp;gt; Options and selecting the KeeAgent tab.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/3-options.webp&#34; alt=&#34;A checked box reading &amp;ldquo;Always require user confirmation when a client program requests to use a key&amp;rdquo;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Press OK.&lt;/p&gt;
&lt;p&gt;Then go to File -&amp;gt; Save. Close KeePass and re-open it. You’ll be asked to enter your KeePass password and then you can verify that the agent is loaded with your key by clicking Tools -&amp;gt; KeeAgent.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/4-agent.webp&#34; alt=&#34;KeeAgent in Agent Mode&#34;&gt;&lt;/p&gt;
&lt;p&gt;Now when we use PuTTY or another PuTTY agent-compatible program we’ll be presented with a confirmation dialog. Clicking Yes will allow the key to be used.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/5-confirmation.webp&#34; alt=&#34;KeeAgent’s confirmation dialog&#34;&gt;&lt;/p&gt;
&lt;p&gt;Notice that the default selected option is No. This is different than the standard openssh-askpass on Linux, which defaults to Yes. If you’re typing along in a fury and the confirmation window pops up and you hit Enter or space, it will decline the use of your SSH key, rather than accepting it.&lt;/p&gt;
&lt;p&gt;If you have enabled SSH key forwarding in the PuTTY options for the connection you’ll be using you can then SSH to other servers using the same key and each time you do so the confirmation will be presented to you.&lt;/p&gt;
&lt;p&gt;If you close KeePass the key agent will be closed and unavailable for future connections. Re-opening KeePass will allow the key to be used again.&lt;/p&gt;
&lt;p&gt;If you use Windows and SSH agent forwarding but have never tried agent confirmation to protect against malicious use of your secret key, give KeePass and KeeAgent a try!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>.NET Conf 2021 is coming!</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2021/10/net-conf-2021-is-coming/"/>
      <id>https://www.endpointdev.com/blog/2021/10/net-conf-2021-is-coming/</id>
      <published>2021-10-27T00:00:00+00:00</published>
      <author>
        <name>Juan Pablo Ventoso</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2021/10/net-conf-2021-is-coming/dotnet-conf-2021.jpg&#34; alt=&#34;.NET Conf 2021 is coming!&#34;&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s that time of the year again! It has been almost one year since .NET 5 was launched at &lt;a href=&#34;/blog/2020/11/dotnet-5-released-net-conf-2020/&#34;&gt;.NET Conf 2020&lt;/a&gt;, unifying .NET Framework and .NET Core into a single open-source and cross-platform framework. With .NET 6 around the corner, it&amp;rsquo;s time to prepare for the new edition, &lt;a href=&#34;https://www.dotnetconf.net/&#34;&gt;.NET Conf 2021&lt;/a&gt;, starting on November 9th.&lt;/p&gt;
&lt;p&gt;This edition will be the 11th online conference, and the &lt;a href=&#34;https://www.dotnetconf.net/agenda&#34;&gt;Agenda&lt;/a&gt; will mainly focus on the .NET 6 launch and the new C# 10, along with some coding challenges and community sessions. The event is organized by both the .NET community and Microsoft. The main changes that will likely be discussed at the conference, based on what we&amp;rsquo;ve seen through the previews, might include:&lt;/p&gt;
&lt;h3 id=&#34;mobile-development&#34;&gt;Mobile development&lt;/h3&gt;
&lt;p&gt;We will see several changes to how web mobile app development works under .NET 6. With a smaller, optimized, and optional SDK for mobile based on &lt;a href=&#34;https://dotnet.microsoft.com/apps/xamarin&#34;&gt;Xamarin&lt;/a&gt;, now called Multi-platform App UI or MAUI, developing an app that targets multiple mobile platforms should be simpler than ever.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/10/net-conf-2021-is-coming/dotnet-maui.jpg&#34; alt=&#34;.NET 6 and MAUI&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;hot-reload-after-some-struggling&#34;&gt;Hot reload (after some struggling)&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&#34;https://devblogs.microsoft.com/dotnet/introducing-net-hot-reload/&#34;&gt;Hot Reload feature&lt;/a&gt;, which will allow us to make and apply changes to the code at execution time, will be finally available in .NET 6. There was some noise about it in the past days since Microsoft made a decision to lock it to Visual Studio 2022, which is a Windows-limited mostly-paid product. But after the open source community made it clear they were angry about it, Microsoft &lt;a href=&#34;https://devblogs.microsoft.com/dotnet/update-on-net-hot-reload-progress-and-visual-studio-2022-highlights/&#34;&gt;reversed the change&lt;/a&gt; and the feature will be available for all platforms.&lt;/p&gt;
&lt;h3 id=&#34;blazor-6&#34;&gt;Blazor 6&lt;/h3&gt;
&lt;p&gt;The new version of Blazor will also have improvements. One of the main features is the implementation of &lt;a href=&#34;https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-6-preview-4/#blazor-webassembly-ahead-of-time-aot-compilation&#34;&gt;ahead-of-time compilation&lt;/a&gt;, that allows generating WebAssembly code during the publishing process. That way, the application performance is increased, since it can run natively instead of needing a .NET IL interpreter.&lt;/p&gt;
&lt;h3 id=&#34;lts-long-term-support&#34;&gt;LTS (Long Term Support)&lt;/h3&gt;
&lt;p&gt;.NET 6 is a Long Term Support version, which means that it will have support for at least 3 years after its release. The current version, .NET 5, is a General Availability (GA) version, which means its support will likely end six months after the next release is available.&lt;/p&gt;
&lt;p&gt;Several improvements were introduced to different aspects of the framework, including &lt;a href=&#34;https://www.reddit.com/r/dotnet/comments/o21i5k/webassembly_aot_support_is_now_available_with_net/&#34;&gt;AOT compilation&lt;/a&gt; or the &lt;a href=&#34;https://dotnetcoretutorials.com/2021/07/16/building-minimal-apis-in-net-6/&#34;&gt;Minimal API Framework&lt;/a&gt;. There are also improvements to the build speed as we can see in the chart below. A complete list of breaking changes can be seen &lt;a href=&#34;https://docs.microsoft.com/en-us/dotnet/core/compatibility/6.0&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/10/net-conf-2021-is-coming/dotnet-5-vs-dotnet-6-improvements.jpg&#34; alt=&#34;.NET 5 vs. .NET 6 build improvements&#34;&gt;&lt;/p&gt;
&lt;p&gt;Bonus: Although not part of the event itself, the new version of Visual Studio will also be available from November 8th, and it will be launched on an &lt;a href=&#34;https://visualstudio.microsoft.com/launch/&#34;&gt;online event&lt;/a&gt; that Microsoft is preparing with several presentations from the development team.&lt;/p&gt;
&lt;p&gt;As we did last year, the .NET team at End Point Dev will be listening to the talks and presentations from the conference, and trying out the new features that will be publicly available on November 9th. Exciting days ahead! We hope to see you there.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Automating Windows Service Installation</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2021/04/automating-windows-service-installation/"/>
      <id>https://www.endpointdev.com/blog/2021/04/automating-windows-service-installation/</id>
      <published>2021-04-23T00:00:00+00:00</published>
      <author>
        <name>Daniel Gomm</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/assembly-line.jpg&#34; alt=&#34;Assembly line&#34;&gt;
&lt;a href=&#34;https://unsplash.com/photos/pAzSrQF3XUQ&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://unsplash.com/@scienceinhd&#34;&gt;Science in HD&lt;/a&gt; on Unsplash&lt;/p&gt;
&lt;p&gt;For me, setting up a service started as a clean one-liner that used &lt;code&gt;InstallUtil.exe&lt;/code&gt;, but as time went on, I accumulated additional steps. Adding external files &amp;amp; folders, setting a custom &lt;strong&gt;Service Logon Account&lt;/strong&gt;, and even an SSL cert had to be configured first before the service could be used. An entire checklist was needed just to make sure the service would start successfully. That’s when I realized a proper installation method was needed here. This article will go over how to make a dedicated &lt;code&gt;.msi&lt;/code&gt; installer for a Windows Service that can do all these things and more.&lt;/p&gt;
&lt;p&gt;Creating an installer can be tricky, because not all the available features are easy to find. In fact, the setup project itself is not included by default in Visual Studio; you need to install an extension in order to create one. But once the installer is created, we can use it to do things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Configure the installer to copy the build output of a project to the &lt;code&gt;C:\Program Files (x86)&lt;/code&gt; folder, as well as add custom files &amp;amp; folders to the installation&lt;/li&gt;
&lt;li&gt;Add custom CLI flags to the installer to specify the &lt;strong&gt;Service Logon Account&lt;/strong&gt; at install time&lt;/li&gt;
&lt;li&gt;Add an installer class to the service and use the installation lifecycle hooks to write custom code that gets run at any stage of the installation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;a-note-on-compatibility&#34;&gt;A Note On Compatibility&lt;/h3&gt;
&lt;p&gt;For .NET Core and .NET 5.0 projects, you won’t be able to add an installer class. To use either .NET Core or .NET 5.0 to make a service instead, you’d need to make a different kind of project called a &lt;strong&gt;Worker Service&lt;/strong&gt;. A Worker Service differs from a traditional &lt;strong&gt;Windows Service&lt;/strong&gt; in that it’s more like a console application that spawns off a worker process on a new thread. It &lt;em&gt;can&lt;/em&gt; be configured to run as a Windows service, but doesn’t have to be. So instead of using an installer, for a Worker Service you’d publish the project to an output directory and then use the &lt;code&gt;SC.exe&lt;/code&gt; utility to add it as a Windows service:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bat&#34; data-lang=&#34;bat&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dotnet publish -o C:\&amp;lt;PUBLISH_PATH&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SC CREATE &amp;lt;WORKER_NAME&amp;gt; C:\&amp;lt;PUBLISH_PATH&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;creating-a-windows-setup-project&#34;&gt;Creating a Windows Setup Project&lt;/h3&gt;
&lt;p&gt;In order to create a .msi installer in Visual Studio 2019, you’ll need to install the &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=VisualStudioClient.MicrosoftVisualStudio2017InstallerProjects&#34;&gt;Microsoft Visual Studio Installer Projects&lt;/a&gt; extension. While it’s not provided with a default installation of Visual Studio 2019, it’s an official Microsoft extension. Once you’ve installed it, you’ll be able to create any of the following projects:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/setup-projects-list.jpg&#34; alt=&#34;Setup Project Templates screenshot: Setup Project, Web Setup Projet, Merge Module Project, Setup Wizard&#34;&gt;&lt;/p&gt;
&lt;p&gt;To create an installer, you can create a new &lt;strong&gt;Setup Project&lt;/strong&gt;. The build output from this project will be your &lt;code&gt;.msi&lt;/code&gt; installer. The setup project has a few different views, which you can use to configure what the installer needs to accomplish. These views can be accessed by right-clicking on the project in the Solution Explorer and expanding View from the context menu:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/installer-views.jpg&#34; alt=&#34;Setup Project Views screenshot&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;configuring-the-installation-file-system&#34;&gt;Configuring the Installation File System&lt;/h3&gt;
&lt;p&gt;To configure what files need to be installed, you can use the &lt;strong&gt;File System&lt;/strong&gt; view, which provides a UI with some folders added to it:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/file-system-view.jpg&#34; alt=&#34;File System View screenshot: Application Folder, User&amp;rsquo;s Desktop, User&amp;rsquo;s Programs Menu&#34;&gt;&lt;/p&gt;
&lt;p&gt;Here, clicking on any folder on the left shows its contents over on the right. It also populates the &lt;strong&gt;Properties Window&lt;/strong&gt; with the information about the folder:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/application-folder-properties-window.jpg&#34; alt=&#34;Application Folder Properties screenshot: AlwaysCreate, Condition, DefaultLocation, Property, Transitive&#34;&gt;&lt;/p&gt;
&lt;p&gt;In the above example, we can see that the &lt;strong&gt;Application Folder&lt;/strong&gt; is being output to a folder inside &lt;code&gt;C:\Program Files (x86)&lt;/code&gt;. You can add any folders you want to the file system by right-clicking on the file system to open the Special Folders context menu:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/special-folder-context-menu.jpg&#34; alt=&#34;Special Folder Context Menu screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;Some default folders are shown here for convenience. But let’s say we wanted to make some files get added to the &lt;code&gt;C:\ProgramData&lt;/code&gt; folder. To do this, select “Custom Folder” and give it a name. Then, in the &lt;strong&gt;Properties Window&lt;/strong&gt;, set the value of &lt;code&gt;DefaultLocation&lt;/code&gt; to the correct path:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/program-data-properties-window.jpg&#34; alt=&#34;ProgramData Properties screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;From here, you can use the right half of the view to add additional folders within &lt;code&gt;C:\ProgramData\DotNetDemoService&lt;/code&gt; based on your needs.&lt;/p&gt;
&lt;p&gt;Another thing you’ll likely want to do is put the DLLs from your application into a folder within &lt;code&gt;C:\Program Files (x86)&lt;/code&gt;. You can easily do this by mapping the primary build output of your project to the Application Folder in the installer’s file system. To do this, right-click on the &lt;strong&gt;Application Folder&lt;/strong&gt;, and add project output:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/add-project-output.jpg&#34; alt=&#34;Adding Project Output screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;From there you’ll be prompted to select the project and output type. Select your project, and “Primary Output”:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/add-project-output-dialog.jpg&#34; alt=&#34;Add Project Output Dialog screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;This will copy over the DLLs for your project and all of its dependencies.&lt;/p&gt;
&lt;h3 id=&#34;creating-an-installer-class&#34;&gt;Creating an Installer class&lt;/h3&gt;
&lt;p&gt;You may be wondering if it’s possible to define custom code to be run during the installation process. It is! For any project targeting .NET Framework 4.8 and under, you can add a class that extends &lt;code&gt;System.Configuration.Install.Installer&lt;/code&gt;, and has the &lt;code&gt;[RunInstaller(true)]&lt;/code&gt; attribute applied to it. After doing so, you’ll then be able to hook in and override any of the installation lifecycle methods. Taking a look into the definition of the &lt;code&gt;System.Configuration.Install.Installer&lt;/code&gt; class reveals the list of overridable lifecycle hook methods you can use to add custom logic to the installation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;virtual&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; Commit(IDictionary savedState);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;virtual&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; Install(IDictionary stateSaver);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;virtual&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; Rollback(IDictionary savedState);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;virtual&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; Uninstall(IDictionary savedState);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;protected&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;virtual&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; OnAfterInstall(IDictionary savedState);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;protected&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;virtual&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; OnAfterRollback(IDictionary savedState);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;protected&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;virtual&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; OnAfterUninstall(IDictionary savedState);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;protected&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;virtual&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; OnBeforeInstall(IDictionary savedState);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;protected&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;virtual&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; OnBeforeRollback(IDictionary savedState);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;protected&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;virtual&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; OnBeforeUninstall(IDictionary savedState);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;protected&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;virtual&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; OnCommitted(IDictionary savedState);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;protected&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;virtual&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; OnCommitting(IDictionary savedState);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It also defines event handlers for each of these steps as well:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;event&lt;/span&gt; InstallEventHandler BeforeInstall;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;event&lt;/span&gt; InstallEventHandler Committing;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;event&lt;/span&gt; InstallEventHandler AfterUninstall;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;event&lt;/span&gt; InstallEventHandler AfterRollback;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;event&lt;/span&gt; InstallEventHandler AfterInstall;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;event&lt;/span&gt; InstallEventHandler Committed;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;event&lt;/span&gt; InstallEventHandler BeforeRollback;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;event&lt;/span&gt; InstallEventHandler BeforeUninstall;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To add an installer class to the Windows Service project, there’s a helper you can use by right clicking on the designer view of the service and selecting “Add Installer” from the context menu:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/add-installer.jpg&#34; alt=&#34;Adding an Installer screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;This will add a new file called &lt;code&gt;ProjectInstaller.cs&lt;/code&gt; to your project, which has its own designer view. The designer view has a corresponding &lt;code&gt;ProjectInstaller.Designer.cs&lt;/code&gt; file that amends the &lt;code&gt;ProjectInstaller&lt;/code&gt; class with the code generated by the designer. You’ll notice that this designer view already defines two objects, &lt;code&gt;serviceInstaller1&lt;/code&gt; and &lt;code&gt;serviceProcessInstaller1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/installer-designer-view.jpg&#34; alt=&#34;Installer Designer View screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;These are special installer classes that will handle all the default installation tasks for your service. &lt;code&gt;serviceInstaller1&lt;/code&gt; is of type &lt;code&gt;ServiceInstaller&lt;/code&gt; and handles defining the service name and if it should auto start when the machine boots up. &lt;code&gt;serviceProcessInstaller1&lt;/code&gt; is of type &lt;code&gt;ServiceProcessInstaller&lt;/code&gt; and handles setting up the &lt;strong&gt;Service Logon Account&lt;/strong&gt;, which the service will run with once installed. Both of these are already set up and invoked by the designer generated code in &lt;code&gt;ProjectInstaller.Designer.cs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Since both of these special service installers extend &lt;code&gt;System.Configuration.Install.Installer&lt;/code&gt;, you can add custom code to occur at any point of the installation on these as well. The designer view again provides a GUI helper to add this in. Double-clicking on &lt;code&gt;serviceInstaller1&lt;/code&gt; will automatically add a new method to &lt;code&gt;ProjectInstaller&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; serviceInstaller1_AfterInstall(&lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;object&lt;/span&gt; sender, InstallEventArgs e) { }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It will also put some code into &lt;code&gt;ProjectInstaller.Designer.cs&lt;/code&gt; which adds this method to the &lt;code&gt;AfterInstall&lt;/code&gt; event of &lt;code&gt;serviceInstaller1&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;adding-installer-cli-options&#34;&gt;Adding Installer CLI Options&lt;/h3&gt;
&lt;p&gt;It’s also possible to add custom properties that you can pass to the installer as command line arguments. These can be done by defining &lt;strong&gt;Custom Actions&lt;/strong&gt; on the primary build output of your project. To do this, go to the &lt;strong&gt;Custom Actions&lt;/strong&gt; view of the installer project, right click on “Install” and select “Add Custom Action” from the context menu:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/add-custom-action.jpg&#34; alt=&#34;Add a Custom Action screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;This will open up a dialog that prompts you to select a file in the installer’s file system to define a custom action for. In this case, we want to define a custom action on the primary build output. This way, the custom CLI options we are about to define will be passed to the project’s installer class.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/add-custom-action-dialog.jpg&#34; alt=&#34;Add Custom Action Dialog screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;After you click “OK”, the primary build output will show up in the &lt;strong&gt;Custom Actions&lt;/strong&gt; view. When you click on it, you’ll notice that the properties window has a property called &lt;a href=&#34;https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/2w2fhwzz(v=vs.100)?redirectedfrom=MSDN&#34;&gt;CustomActionData&lt;/a&gt;. In short, you can use it to define custom CLI arguments like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/custom-action-data.jpg&#34; alt=&#34;CustomActionData Definining CLI Arguments screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CustomActionData&lt;/code&gt; has its own syntax, so let’s dive deeper into what this actually does. We’re mapping the value of &lt;code&gt;USERNAME&lt;/code&gt; and &lt;code&gt;PASSWORD&lt;/code&gt; from the installer’s &lt;strong&gt;Properties Collection&lt;/strong&gt; to the &lt;code&gt;InstallContext&lt;/code&gt; of the installer class of your project under the &lt;code&gt;Username&lt;/code&gt; and &lt;code&gt;Password&lt;/code&gt; keys, respectively. The square brackets denote that the value is to be taken from the &lt;strong&gt;Properties Collection&lt;/strong&gt;, and the quotes allow the value of the property to contain spaces. The forward slash denotes that we are adding a new key to the context. Any command line arguments passed to the installer are added to the &lt;strong&gt;Properties Collection&lt;/strong&gt; by default.&lt;/p&gt;
&lt;h3 id=&#34;using-custom-cli-options-in-the-installer-class&#34;&gt;Using Custom CLI Options in the Installer Class&lt;/h3&gt;
&lt;p&gt;Now that we have defined our custom action with the CLI arguments, we can go over to the project’s Installer class and access them via the &lt;code&gt;Context&lt;/code&gt; property. In this example, we’re using the custom properties to define the Logon account for the service, which needs to be set right before the installation happens. We can use the &lt;code&gt;Install(IDictionary stateSaver)&lt;/code&gt; lifecycle hook method for this purpose:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;override&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;void&lt;/span&gt; Install(IDictionary stateSaver)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;// If no username or password is specified, fall back to installing the service to run as the SYSTEM account&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;if&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;string&lt;/span&gt;.IsNullOrEmpty(&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;this&lt;/span&gt;.Context.Parameters[&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;Username&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        || &lt;span style=&#34;color:#888;font-weight:bold&#34;&gt;string&lt;/span&gt;.IsNullOrEmpty(&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;this&lt;/span&gt;.Context.Parameters[&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;Password&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;this&lt;/span&gt;.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;// Otherwise, configure the service to run under the specified account.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;this&lt;/span&gt;.serviceProcessInstaller1.Username = &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;this&lt;/span&gt;.Context.Parameters[&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;Username&amp;#34;&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;this&lt;/span&gt;.serviceProcessInstaller1.Password = &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;this&lt;/span&gt;.Context.Parameters[&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;Password&amp;#34;&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;// Run the base class install after the service has been configured.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;base&lt;/span&gt;.Install(stateSaver);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;conditionally-installing-files&#34;&gt;Conditionally Installing Files&lt;/h3&gt;
&lt;p&gt;It’s also possible to make the installer conditionally install files based on a value from the &lt;strong&gt;Properties Collection&lt;/strong&gt;. One example of how this can be useful would be swapping in the production or development configuration file based on the value of a command line argument. We don’t need to write any additional code to do this, we just have to add a value for the &lt;a href=&#34;https://docs.microsoft.com/en-us/windows/win32/msi/conditional-statement-syntax&#34;&gt;Condition&lt;/a&gt; property in the &lt;strong&gt;Properties Window&lt;/strong&gt; for the file:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2021/04/automating-windows-service-installation/conditional-file-installation.jpg&#34; alt=&#34;Conditionally Installing a File screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;The above condition will make the file &lt;code&gt;settings.production.config&lt;/code&gt; be installed only if the &lt;code&gt;DEBUG&lt;/code&gt; command line argument is not defined or is set to “false”. Like the custom actions, this property is also sourced from the &lt;strong&gt;Properties Collection&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;And that’s it! I found that having a dedicated &lt;code&gt;.msi&lt;/code&gt; installer was handy for making the setup of my Windows Service completely hands-free. While some of the features you need might seem buried within context menus, the flexibility of having the installer handle the service setup is well worth the effort.&lt;/p&gt;
&lt;p&gt;Have any questions? Feel free to leave a comment!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>.NET 5 will be released at .NET Conf 2020</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2020/11/dotnet-5-released-net-conf-2020/"/>
      <id>https://www.endpointdev.com/blog/2020/11/dotnet-5-released-net-conf-2020/</id>
      <published>2020-11-04T00:00:00+00:00</published>
      <author>
        <name>Juan Pablo Ventoso</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2020/11/dotnet-5-released-net-conf-2020/dotnet-5-platform.png&#34; alt=&#34;.NET 5 Platform&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://devblogs.microsoft.com/dotnet/introducing-net-5/&#34;&gt;.NET — A unified platform&lt;/a&gt; by Microsoft&lt;/p&gt;
&lt;p&gt;Last year, at .NET Conf 2019, Microsoft announced that the new .NET 5 will have a base class library that will allow creation of any type of application for any platform — Windows, Linux, Android, iOS, and IoT. And that’s finally about to happen: .NET 5 will be launched at &lt;a href=&#34;https://www.dotnetconf.net/&#34;&gt;.NET Conf 2020&lt;/a&gt;, starting November 10th!&lt;/p&gt;
&lt;p&gt;According to Microsoft, &lt;a href=&#34;https://devblogs.microsoft.com/dotnet/introducing-net-5/&#34;&gt;.NET 5&lt;/a&gt; will take the best of .NET Core, .NET Framework, Xamarin, and Mono and merge them into one framework, offering the same experience for all developers, regardless of the type of application or platform targeted. It will also include two different compiler models: just-in-time (JIT, prepared for client-server and desktop apps) and static compilation with ahead-of-time (AOT, optimized to decrease startup times, ideal for mobile and IoT devices).&lt;/p&gt;
&lt;p&gt;Some of the key features will be:&lt;/p&gt;
&lt;h3 id=&#34;windows-desktop-development-wpfwindows-formsuwp&#34;&gt;Windows Desktop development (WPF/​Windows Forms/​UWP)&lt;/h3&gt;
&lt;p&gt;This was already a part of the current .NET Core 3 release, and it will stay while getting some updates like a Chromium-based WebView control, improvements to the visual designer, and customizable task dialogs. It will also include all the latest features of C# 8.&lt;/p&gt;
&lt;h3 id=&#34;full-stack-web-development-cblazor&#34;&gt;Full-stack web development (C#/​Blazor)&lt;/h3&gt;
&lt;p&gt;This feature is also present on the current .NET Core 3 version, and will be updated for this release. With Blazor, we can write full-stack web applications only using C#, removing the need to use a separate language for the frontend. While it’s still a discussed feature, the advantage of using it will depend on the type of web application we’re working on. But it’s there and it will be fully supported on .NET 5.&lt;/p&gt;
&lt;h3 id=&#34;c-8&#34;&gt;C# 8&lt;/h3&gt;
&lt;p&gt;This version tries to reduce the well-known (by all of us!) null reference exceptions as a source of program failures by &lt;a href=&#34;https://docs.microsoft.com/en-us/archive/msdn-magazine/2018/february/essential-net-csharp-8-0-and-nullable-reference-types&#34;&gt;introducing a nullability modifier for nullable reference types&lt;/a&gt;. Other main improvements include asynchronous streams, default interface methods and pattern matching enhancements. A full reference of all the new features can be found &lt;a href=&#34;https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;updates-to-entity-framework&#34;&gt;Updates to Entity Framework&lt;/h3&gt;
&lt;p&gt;EF will now integrate with the new C# 8, allowing us to consume the query results as &lt;a href=&#34;https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#asynchronous-streams&#34;&gt;asynchronous streams&lt;/a&gt;, and automatically mapping the new non-nullable types to non-nullable fields on the database, among other improvements.&lt;/p&gt;
&lt;h3 id=&#34;updates-to-mlnet&#34;&gt;Updates to ML.NET&lt;/h3&gt;
&lt;p&gt;.NET 5 will also include the latest version of &lt;a href=&#34;https://dotnet.microsoft.com/learn/ml-dotnet/what-is-mldotnet&#34;&gt;ML.NET&lt;/a&gt;, a free, open-source, and cross-platform machine learning framework for .NET, with some key features like the &lt;code&gt;DatabaseLoader&lt;/code&gt; class, which allows loading the data from any relational database with a connection string, and improvements to the object detection capabilities.&lt;/p&gt;
&lt;h3 id=&#34;and-more&#34;&gt;And more&lt;/h3&gt;
&lt;p&gt;And of course, everything that was already on .NET Core 3 will be a part of .NET 5: multi-platform mobile development, Azure Cloud access tools, gaming development with Unity and traditional ASP.NET development, etc.&lt;/p&gt;
&lt;p&gt;The long-term support (LTS) version of .NET Core is aimed to be launched in 2021, and it will be called .NET 6, hopefully recollecting everything that might be improved based on the feedback for this General Availability (GA) release.&lt;/p&gt;
&lt;p&gt;The .NET development team at End Point will be attending the main talks that will happen at the .NET Conf 2020. On Day 1, the focus will be put on this new release, so stay tuned for more to come!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Job opening: Windows Systems Integrator</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2020/07/job-windows-systems-integrator/"/>
      <id>https://www.endpointdev.com/blog/2020/07/job-windows-systems-integrator/</id>
      <published>2020-07-23T00:00:00+00:00</published>
      <author>
        <name>Jon Jensen</name>
      </author>
      <content type="html">
        &lt;img src=&#34;/blog/2020/07/job-windows-systems-integrator/20181204-063141-sm.jpg&#34; alt=&#34;New York City East River &amp; FDR Drive&#34; /&gt;
&lt;!-- Photo by Jon Jensen --&gt;
&lt;p&gt;We are looking for a Windows systems integrator in the New York City metropolitan region to work with us.&lt;/p&gt;
&lt;p&gt;We are an Internet technology consulting company based in NYC, with 50 employees serving many clients ranging from small family businesses to large corporations. The company turns 25 years old this year!&lt;/p&gt;
&lt;p&gt;This is a consulting position, so excellent verbal and written communication, troubleshooting, and time management skills are required, along with a good sense for when to quickly escalate issues to resolve them efficiently as needed.&lt;/p&gt;
&lt;h3 id=&#34;skills-and-tools&#34;&gt;Skills and tools&lt;/h3&gt;
&lt;p&gt;You will need to have extensive experience in the Microsoft Windows ecosystem: the MS Windows OS, Windows networking, Active Directory management via Group Policies, MS Exchange Server, MS SQL Server, etc.&lt;/p&gt;
&lt;p&gt;The greater knowledge of and larger base of experience you have with these, the better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Remote management &amp;amp; monitoring (RMM) systems, such as ConnectWise Manage and Automate&lt;/li&gt;
&lt;li&gt;Mobile devices and mobile device management (MDM) systems, such as SOTI MobiControl, AirWatch, and MaaS360&lt;/li&gt;
&lt;li&gt;VMware’s vSphere or Microsoft Hyper-V hypervisors&lt;/li&gt;
&lt;li&gt;Managing firewall security policies, switches, and wireless access points (WAPs)&lt;/li&gt;
&lt;li&gt;Storage management, connecting via iSCSI and SMB3 SAN &amp;amp; NAS devices&lt;/li&gt;
&lt;li&gt;Managing cloud services and migrating to and from such services as Office 365, Azure, Amazon Web Services, and Google Cloud Platform&lt;/li&gt;
&lt;li&gt;An understanding of disk imaging, backup, and recovery strategies&lt;/li&gt;
&lt;li&gt;Scripting or development experience, such as PowerShell, .NET/C#, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tell us about your other skills and strengths. We’ll be interested to hear about them.&lt;/p&gt;
&lt;h3 id=&#34;location&#34;&gt;Location&lt;/h3&gt;
&lt;p&gt;This position requires (at least once COVID-19 subsides) some work in our Manhattan office along with some on-site work at customer locations in the NYC metro region. Working remotely is also possible from time to time.&lt;/p&gt;
&lt;h3 id=&#34;benefits&#34;&gt;Benefits&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Flexible, sane work hours&lt;/li&gt;
&lt;li&gt;Annual bonus opportunity&lt;/li&gt;
&lt;li&gt;Paid holidays and vacation&lt;/li&gt;
&lt;li&gt;Health insurance subsidy&lt;/li&gt;
&lt;li&gt;401(k) retirement savings plan&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;how-to-contact-us&#34;&gt;How to contact us&lt;/h3&gt;
&lt;p&gt;&lt;del&gt;Please email us an introduction to jobs@endpointdev.com to apply.&lt;/del&gt;
&lt;strong&gt;(This job has been filled.)&lt;/strong&gt;
Include your location, a resume/​CV, your LinkedIn URL (if you have one), and whatever else helps us get to know you.&lt;/p&gt;
&lt;p&gt;We look forward to hearing from you! Direct work seekers only, please—​this role is not for agencies or subcontractors.&lt;/p&gt;
&lt;h3 id=&#34;equal-opportunity-employer&#34;&gt;Equal opportunity employer&lt;/h3&gt;
&lt;p&gt;We are an equal opportunity employer and value diversity at our company. We do not discriminate on the basis of sex/​gender, race, religion, color, national origin, sexual orientation, age, marital status, veteran status, or disability status.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Linux Development in Windows 10 with Docker and WSL 2</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2020/06/linux-development-in-windows-10-docker-wsl-2/"/>
      <id>https://www.endpointdev.com/blog/2020/06/linux-development-in-windows-10-docker-wsl-2/</id>
      <published>2020-06-18T00:00:00+00:00</published>
      <author>
        <name>Kevin Campusano</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2020/06/linux-development-in-windows-10-docker-wsl-2/banner.png&#34; alt=&#34;Banner&#34;&gt;&lt;/p&gt;
&lt;p&gt;I’m first and foremost a Windows guy. But for a few years now, moving away from working mostly with .NET and into a plethora of open source technologies has given me the opportunity to change platforms and run a Linux-based system as my daily driver. Ubuntu, which I honestly love for work, has been serving me well by supporting my development workflow with languages like &lt;a href=&#34;https://www.php.net/&#34;&gt;PHP&lt;/a&gt;, &lt;a href=&#34;https://www.javascript.com/&#34;&gt;JavaScript&lt;/a&gt; and &lt;a href=&#34;https://www.ruby-lang.org/en/&#34;&gt;Ruby&lt;/a&gt;. And with the help of the excellent &lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;Visual Studio Code&lt;/a&gt; editor, I’ve never looked back. There’s always been an inclination in the back of my mind though, to take some time and give Windows another shot.&lt;/p&gt;
&lt;p&gt;With the latest improvements coming to the Windows Subsystem for Linux with &lt;a href=&#34;https://docs.microsoft.com/en-us/windows/wsl/compare-versions#whats-new-in-wsl-2&#34;&gt;its second version&lt;/a&gt;, the new and exciting &lt;a href=&#34;https://github.com/microsoft/terminal&#34;&gt;Windows Terminal&lt;/a&gt;, and &lt;a href=&#34;https://docs.docker.com/docker-for-windows/wsl/&#34;&gt;Docker support for running containers inside WSL2&lt;/a&gt;, I think the time is now.&lt;/p&gt;
&lt;p&gt;In this post, we’ll walk through the steps I took to set up a PHP development environment in Windows, running in a Ubuntu Docker container running on WSL 2, and VS Code. Let’s go.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: You have to be on the latest version of Windows 10 Pro (Version 2004) in order to install WSL 2 by the usual methods. If not, you’d need to be part of the Windows Insider Program to have access to the software.&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3 id=&#34;whats-new-with-wsl-2&#34;&gt;What’s new with WSL 2&lt;/h3&gt;
&lt;p&gt;This is best explained by the &lt;a href=&#34;https://docs.microsoft.com/en-us/windows/wsl/compare-versions#whats-new-in-wsl-2&#34;&gt;official documentation&lt;/a&gt;. However, being a WSL 1 veteran, I’ll mention a few improvements made which have sparked my interest in trying it again.&lt;/p&gt;
&lt;h4 id=&#34;1-its-faster-and-more-compatible&#34;&gt;1. It’s faster and more compatible&lt;/h4&gt;
&lt;p&gt;WSL 2 introduces a complete architectural overhaul. Now, Windows ships with a full Linux Kernel which WSL 2 distributions run on. This results in greatly improved file system performance and much better compatibility with Linux programs. It’s no longer running a Linux look-alike, but actual Linux.&lt;/p&gt;
&lt;h4 id=&#34;2-its-better-integrated-with-windows&#34;&gt;2. It’s better integrated with Windows&lt;/h4&gt;
&lt;p&gt;This is a small one: we can now use the Windows explorer to browse files within a WSL distribution. This is not a WSL 2 exclusive feature, it has been there for a while now. I think it’s worth mentioning though, because it truly is a great convenience and a far cry from WSL’s first release, where Microsoft specifically advised against manipulating WSL distribution file systems from Windows. If nothing else, this makes WSL feel like a first class citizen in the Windows ecosystem and shows that Microsoft actually cares about making it a good experience.&lt;/p&gt;
&lt;h4 id=&#34;3-it-can-run-docker&#34;&gt;3. It can run Docker&lt;/h4&gt;
&lt;p&gt;I’ve recently been learning more and more about Docker and it’s quickly becoming my preferred way of setting up development environments. Due to its lightweightness, ease of use, repeatability, and VM-like compartmentalization, I find it really convenient to develop against a purpose-built Docker container, rather than directly in my local machine. And with VS Code’s Remote development extension, the whole thing is very easy to set up. Docker for Windows now supports running containers within WSL, so I’m eager to try that out and see how it all works.&lt;/p&gt;
&lt;h4 id=&#34;4-a-newer-version-means-several-bugfixes&#34;&gt;4. A newer version means several bugfixes&lt;/h4&gt;
&lt;p&gt;Performance notwithstanding, WSL’s first release was pretty stable. I did, however, encounter some weird bugs and gotchas when working with the likes of SSH and Ruby during certain tasks. It was nothing major, as workarounds were readily available. I’ve already discussed some of them &lt;a href=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/&#34;&gt;here&lt;/a&gt;, so I won’t bother mentioning them here again. But thanks to the fact that the technology has matured since last time I saw it, and considering the architectural direction it is going in, I’m excited to not have to deal with any number of quirks.&lt;/p&gt;
&lt;h3 id=&#34;the-development-environment&#34;&gt;The development environment&lt;/h3&gt;
&lt;p&gt;Ok, now with some of the motivation out of the way, let’s try and build a quick PHP Hello World app running in a Docker container inside WSL 2, make sure we can edit and debug it with VS Code, and access it in a browser from Windows.&lt;/p&gt;
&lt;h4 id=&#34;step-1-install-wsl-2-and-ubuntu&#34;&gt;Step 1: Install WSL 2 and Ubuntu&lt;/h4&gt;
&lt;p&gt;Step 1 is obviously to install WSL and a Linux distribution that we like. &lt;a href=&#34;https://docs.microsoft.com/en-us/windows/wsl/install-win10&#34;&gt;Microsoft’s own documentation&lt;/a&gt; offers an excellent guide on how to do just that. But in summary, we need to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Enable the “Windows Subsystem for Linux” and “Virtual Machine Platform” features by running these on an elevated PowerShell:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Restart your machine.&lt;/li&gt;
&lt;li&gt;Set WSL 2 as the default version with: &lt;code&gt;wsl --set-default-version 2&lt;/code&gt;, also from PowerShell.&lt;/li&gt;
&lt;li&gt;Install your desired distribution from the Microsoft Store. I chose &lt;a href=&#34;https://www.microsoft.com/en-us/p/ubuntu-2004-lts/9n6svws3rx71?rtc=2&amp;amp;activetab=pivot:overviewtab&#34;&gt;Ubuntu 20.04 LTS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;After installing, open the “Ubuntu 20.04 LTS” app from the Start menu and it should come up with a command line console. Wait for it to finish installing. It should prompt for a username and password along the way. Choose something you won’t forget.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Optionally, you can install the &lt;a href=&#34;https://github.com/microsoft/terminal&#34;&gt;Windows Terminal&lt;/a&gt; app to get a better command line experience. Windows Terminal can be used to interact with PowerShell and the classic CMD, as well as with our WSL distributions.&lt;/p&gt;
&lt;h4 id=&#34;step-2-install-docker&#34;&gt;Step 2: Install Docker&lt;/h4&gt;
&lt;p&gt;Installing Docker is very straightforward. Just download the installer for &lt;a href=&#34;https://hub.docker.com/editions/community/docker-ce-desktop-windows/&#34;&gt;Docker Desktop for Windows&lt;/a&gt;, execute it, and follow the wizard’s steps. Make sure that during setup the “Use the WSL 2 based engine” option is selected. In most cases, the installer will detect WSL 2 and automatically have the option selected.&lt;/p&gt;
&lt;p&gt;Follow the &lt;a href=&#34;https://docs.docker.com/docker-for-windows/wsl/&#34;&gt;official instructions&lt;/a&gt; for more details on the process, but it really is that simple.&lt;/p&gt;
&lt;h4 id=&#34;step-3-install-some-useful-vs-code-extensions&#34;&gt;Step 3: Install some useful VS Code extensions&lt;/h4&gt;
&lt;p&gt;Our objective is to create a new development environment inside a Docker container and connect to it directly with VS Code. To do that, we use a few useful extensions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker&#34;&gt;The Docker extension&lt;/a&gt; which allows us to browse and manage images and containers and other types of Docker assets.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl&#34;&gt;The Remote - WSL extension&lt;/a&gt; which allows VS Code to connect to a WSL distribution.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers&#34;&gt;The Remote - Containers extension&lt;/a&gt; which allows VS Code to connect to a container.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;step-4-create-the-development-container&#34;&gt;Step 4: Create the development container&lt;/h4&gt;
&lt;p&gt;The extensions that we installed will allow us to use VS Code to work on code from within our WSL Ubuntu as well as from the container. Specifically, we want to connect VS Code to a container. There are a few ways to do this, but I will describe the one I think is the easiest, most convenient and “automagic” by fully leveraging the tools.&lt;/p&gt;
&lt;p&gt;Let’s begin by opening a WSL Ubuntu terminal session, which will show something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Welcome to Ubuntu 20.04 LTS (GNU/Linux 4.19.104-microsoft-standard x86_64)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; * Documentation:  https://help.ubuntu.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; * Management:     https://landscape.canonical.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; * Support:        https://ubuntu.com/advantage
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kevin@kevin-thinkpad:/mnt/c/Users/kevin$&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&#34;the-project-directory&#34;&gt;The project directory&lt;/h4&gt;
&lt;p&gt;Let’s change to our home, create a new directory for our new project, and change into it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ &lt;span style=&#34;color:#038&#34;&gt;cd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ mkdir php-in-docker-demo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ &lt;span style=&#34;color:#038&#34;&gt;cd&lt;/span&gt; php-in-docker-demo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Because we installed the Remote - WSL extension, we can open up this directory in VS Code with &lt;code&gt;code .&lt;/code&gt;. Opening a terminal (Ctrl + `) in this VS Code instance opens WSL console, not Windows.&lt;/p&gt;
&lt;h4 id=&#34;the-dockerfile&#34;&gt;The Dockerfile&lt;/h4&gt;
&lt;p&gt;Now let’s create a new file called &lt;code&gt;Dockerfile&lt;/code&gt; which will define what our development environment image will look like. For a no-frills PHP environment, mine looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# The FROM statement says that our image will be based on the official Ubuntu Docker image from Docker Hub: https://hub.docker.com/_/ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FROM ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Install packages, not allowing apt to ask any questions since we can&amp;#39;t answer.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ENV DEBIAN_FRONTEND=noninteractive
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RUN apt-get update &amp;amp;&amp;amp; apt-get install -y software-properties-common php php-xdebug composer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Configure Xdebug so that the VS Code debugger can use it.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RUN echo &amp;#34;xdebug.remote_enable=on&amp;#34; &amp;gt;&amp;gt; /etc/php/7.4/mods-available/xdebug.ini
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RUN echo &amp;#34;xdebug.remote_autostart=on&amp;#34; &amp;gt;&amp;gt; /etc/php/7.4/mods-available/xdebug.ini
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# The CMD statement tells Docker which command to run when it starts up the container.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Here, we just call bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CMD [&amp;#34;bash&amp;#34;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This script will later be used to create our development container. It will have PHP, &lt;a href=&#34;https://xdebug.org/&#34;&gt;Xdebug&lt;/a&gt; and &lt;a href=&#34;https://getcomposer.org/&#34;&gt;Composer&lt;/a&gt;. This is all we need for our simple Hello World app. For more complex scenarios, other software like database clients or PHP extensions can be easily installed with additional &lt;code&gt;RUN&lt;/code&gt; statements that call upon the &lt;code&gt;apt&lt;/code&gt; package manager.&lt;/p&gt;
&lt;p&gt;Consider reading through &lt;a href=&#34;https://docs.docker.com/engine/reference/builder/&#34;&gt;Docker’s official documentation&lt;/a&gt; on Dockerfiles to learn more.&lt;/p&gt;
&lt;h4 id=&#34;the-configuration-file&#34;&gt;The configuration file&lt;/h4&gt;
&lt;p&gt;Now, to leverage VS Code’s capabilities, let’s add a development container configuration file. In our current location, we need to create a new directory called &lt;code&gt;.devcontainer&lt;/code&gt; and, inside that, a new file called &lt;code&gt;devcontainer.json&lt;/code&gt;. I put these contents in mine:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;// The name used by VS Code to identify this development environment
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;PHP in Docker Demo&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;// Sets the run context to one level up instead of the .devcontainer folder.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;..&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;// Update the &amp;#39;dockerFile&amp;#39; property if you aren&amp;#39;t using the standard &amp;#39;Dockerfile&amp;#39; filename.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;dockerFile&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;../Dockerfile&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;// Add the IDs of extensions you want installed when the container is created.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#888&#34;&gt;// This is the VS Code PHP Debug extension.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#888&#34;&gt;// It needs to be installed in the container for us to have access to it.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;extensions&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;felixfbecker.php-debug&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#888&#34;&gt;// Use &amp;#39;forwardPorts&amp;#39; to make a list of ports inside the container available locally.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#888&#34;&gt;// When we run our PHP app, we will use this port.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;forwardPorts&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;5000&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A default version of this file can be automatically generated by running the “Remote-Containers: Add Development Container Configuration Files…” command in VS Code’s Command Palette (Ctrl + Shift + P).&lt;/p&gt;
&lt;h4 id=&#34;the-development-container&#34;&gt;The development container&lt;/h4&gt;
&lt;p&gt;Now that we have all that in place, we can create our image, run our container, and start coding our app. Bring up the VS Code Command Palette with Ctrl + Shift + P and run the “Remote-Containers: Reopen in Container” command. The command will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Read the Dockerfile and create an image based on that. This is like running &lt;code&gt;docker build -t AUTOGENERATED_IMAGE_ID .&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run a container based on that image with the settings specified in &lt;code&gt;.devcontainer/devcontainer.json&lt;/code&gt;. In our case, all it will do is enable the container’s port 5000 to be accessible by the host. This is more or less like running: &lt;code&gt;docker run -d -p 5000:5000 -v ${PWD}:/workspaces/php-in-docker-demo AUTOGENERATED_IMAGE_ID&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Open a new VS Code instance connected to the container with the &lt;code&gt;/workspaces/php-in-docker-demo&lt;/code&gt; directory open.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It will take a while, but after it’s done, we will have a VS Code instance running directly in the container. Open the VS Code terminal with Ctrl + ` and see for yourself. It will show a prompt looking like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@ec5be7dd0b9b:/workspaces/php-in-docker-demo#&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can for example, run &lt;code&gt;php -v&lt;/code&gt; in this terminal, and expect something along these lines:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PHP 7.4.3 (cli) (built: May 26 2020 12:24:22) ( NTS )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Copyright (c) The PHP Group
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Zend Engine v3.4.0, Copyright (c) Zend Technologies
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is PHP running, not in Windows, not in our WSL Ubuntu, but in the Docker container.&lt;/p&gt;
&lt;h4 id=&#34;hello-windows--wsl-2--ubuntu--docker--php--vs-code&#34;&gt;Hello Windows + WSL 2 + Ubuntu + Docker + PHP + VS Code&lt;/h4&gt;
&lt;p&gt;Let’s now create our app. Add a new &lt;code&gt;index.php&lt;/code&gt; file containing something silly like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;?php
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;Hello Windows + WSL 2 + Ubuntu + Docker + PHP + Visual Studio Code!&amp;#34;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, in the VS Code console (remember, Ctrl + `), start up an instance of the built in PHP development server wth &lt;code&gt;php -S 0.0.0.0:5000&lt;/code&gt;. It’s important that we use port 5000 because that’s the one that we configured our container to use.&lt;/p&gt;
&lt;p&gt;Navigate to &lt;code&gt;http://localhost:5000/&lt;/code&gt; in your browser and feel good about a job well done.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2020/06/linux-development-in-windows-10-docker-wsl-2/running.png&#34; alt=&#34;Running app&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;interactive-debugging&#34;&gt;Interactive debugging&lt;/h4&gt;
&lt;p&gt;When configuring our development container, we added Xdebug and the PHP Debug VS Code extension. This means that VS Code can leverage Xdebug to provide an interactive debugging experience for PHP code.&lt;/p&gt;
&lt;p&gt;Almost everyting is set up at this point, we just need to do the usual VS Code configuration and add a &lt;code&gt;launch.json&lt;/code&gt; file. To do so, in VS Code, press Ctrl + Shift + D to bring up the “Run” panel, click on the “create a launch.json file” link, and in the resulting “Select Environment” menu, select “PHP”.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2020/06/linux-development-in-windows-10-docker-wsl-2/vscode-run.png&#34; alt=&#34;Running app&#34;&gt;&lt;/p&gt;
&lt;p&gt;After that, the “Run” panel will show a green triangular “Start Debugging” button next to a “Listen to XDebug” text. If you haven’t already, start up a dev web server with &lt;code&gt;php -S 0.0.0.0:5000&lt;/code&gt;, click on the “Start Debugging” button, put a breakpoint somewhere in your &lt;code&gt;index.php&lt;/code&gt; file, and finally open up &lt;code&gt;http://localhost:5000/&lt;/code&gt; in a browser.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2020/06/linux-development-in-windows-10-docker-wsl-2/debug.png&#34; alt=&#34;Running app&#34;&gt;&lt;/p&gt;
&lt;p&gt;We’re interactively debugging PHP code running on a Docker container in WSL from our Windows IDE/​editor. Pretty cool, huh?&lt;/p&gt;
&lt;p&gt;And that’s all for now. In this article we’ve learned how to set up a Linux development environment using Docker containers and WSL 2, with Windows 10 Pro. This is a nice approach for anybody who’s confortable on Windows and needs access to a Linux environment for development; and have that environment be easy to reproduce.&lt;/p&gt;
&lt;h3 id=&#34;resources&#34;&gt;Resources:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.microsoft.com/en-us/windows/wsl/install-win10&#34;&gt;Windows Subsystem for Linux Installation Guide for Windows 10&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://code.visualstudio.com/blogs/2020/03/02/docker-in-wsl2&#34;&gt;Using Docker in WSL 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.docker.com/docker-for-windows/wsl/&#34;&gt;Docker Desktop WSL 2 backend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://code.visualstudio.com/docs/remote/remote-overview&#34;&gt;VS Code Remote Development&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </content>
    </entry>
  
    <entry>
      <title>End Point Security Tips: Securing your Infrastructure</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2020/02/end-point-security-tips/"/>
      <id>https://www.endpointdev.com/blog/2020/02/end-point-security-tips/</id>
      <published>2020-02-05T00:00:00+00:00</published>
      <author>
        <name>Charles Chang</name>
      </author>
      <content type="html">
        &lt;img src=&#34;/blog/2020/02/end-point-security-tips/image-4.jpg&#34; alt=&#34;phishing key on keyboard&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://flic.kr/p/24YXTiY&#34;&gt;Photo&lt;/a&gt; from &lt;a href=&#34;https://www.comparitech.com/blog/information-security/common-phishing-scams-how-to-avoid/&#34;&gt;comparitech.com&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;implement-security-measures-to-protect-your-organization--employees&#34;&gt;Implement Security Measures to Protect Your Organization &amp;amp; Employees&lt;/h3&gt;
&lt;p&gt;In this post, I’ll address what I believe are the three important initiatives every organization should implement to protect your organization and employees:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Train employees on security culture.&lt;/li&gt;
&lt;li&gt;Implement the best technical tools to aid with organizational security.&lt;/li&gt;
&lt;li&gt;Implement recovery tools in case you need to recover from a security breach.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;habits-of-a-security-culture&#34;&gt;Habits of a Security Culture&lt;/h3&gt;
&lt;p&gt;Train everyone in your organization on these fundamentals:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The only time you should be requested to reset your password by email is when you initiate it. There are rare exceptions to this rule, such as when accounts are compromised and providers request all users reset their passwords, but those events should be publicly announced. Staff can confirm with security personnel before acting on such requests.&lt;/li&gt;
&lt;li&gt;If you are asked to reset your password, it will typically be after you successfully logged into a website and the old one has expired.&lt;/li&gt;
&lt;li&gt;If you receive an email and do not know the sender, do not trust the contents or open attachments. Get advice from security personnel if needed.&lt;/li&gt;
&lt;li&gt;If you think the email is from your bank, keep in mind that banks do not ask their clients for private information via email.&lt;/li&gt;
&lt;li&gt;If you think the social security office emailed you to obtain your personal information, keep in mind that they do not initiate or solicit private information via email.&lt;/li&gt;
&lt;li&gt;Companies should not solicit private information unless you initiate first.&lt;/li&gt;
&lt;li&gt;Online retailers should not ask for your private information unless you initiate first.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;a-security-concern-going-phishing&#34;&gt;A Security Concern: Going Phishing!&lt;/h3&gt;
&lt;div style=&#34;float: right; padding: 20px;&#34;&gt;&lt;img src=&#34;/blog/2020/02/end-point-security-tips/image-1.jpg&#34; alt=&#34;phishing fraud&#34; align=&#34;right&#34; hspace=&#34;10&#34;&gt;&lt;p&gt;&lt;a href=&#34;https://flic.kr/p/2gLaNqk&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://www.epictop10.com/&#34;&gt;Epic Top 10 Site&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;One of the more common ways to steal someone’s private information is through phishing. Phishing is like fishing: you try to catch something. In this case, the ‘fish’ is your data. Someone with malicious intent sends you email to attempt to get you to click on the link, picture, content, etc. within the email. Once you click the link or content within the email, it might take you to a website to enter or reset your password, even ask for your social security number or other personal information. The person with malicious intent would use the information collect to open accounts, purchase items online or resell your personal data. The links within the phishing email might even redirect you to a fake website that mimics a real website to collect your personal data. The goal is to confuse the email recipient into believing that the email message is legit in its attempt to collect personal information from the user.&lt;/p&gt;
&lt;h4 id=&#34;phishing-exercises&#34;&gt;Phishing Exercises&lt;/h4&gt;
&lt;div style=&#34;float: left; padding: 20px;&#34;&gt;&lt;img src=&#34;/blog/2020/02/end-point-security-tips/image-2.jpg&#34; alt=&#34;phishing attack&#34; hspace=&#34;10&#34;&gt;&lt;p&gt;&lt;a href=&#34;https://flic.kr/p/x9zZ4A&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://www.flickr.com/photos/christiaancolen/&#34;&gt;Christiaan Colen&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;One way to help the staff better their understanding of a phishing email is to practice phishing exercises by setting up an experiment to see which users would click on your test phishing email. If the user clicks on the experiment phishing email, the email administrator would notify the compliance officer and he or she would re-train the staff on how to properly differentiate real emails from phishing emails. Phishing exercises make a great activity for the employees to avoid the email scams and exert more caution in the future.&lt;/p&gt;
&lt;h3 id=&#34;essential-security-tools&#34;&gt;Essential Security Tools&lt;/h3&gt;
&lt;h4 id=&#34;firewall&#34;&gt;Firewall&lt;/h4&gt;
&lt;p&gt;A firewall should be a mandatory technology for all consumers or businesses. This is basically your main door. The office or organization’s technology is what the firewall is protecting. When you sit in your office working on the computer, just imagine that you are in a fort surrounded by walls. If someone needs to come in, they must be given permission by a gatekeeper to enter the fort. The firewall is very similar. The firewall allows network traffic to go in and out of the office based on the configuration set by a network engineer. The engineer determines what network traffic comes into the office and goes out.&lt;/p&gt;
&lt;p&gt;Companies typically test their firewall with penetration tests and network scans to determine if there are any security concerns after implementing the firewall. The testing of the firewall verifies that good security practices are implemented and the firewall is setup properly and securely.&lt;/p&gt;
&lt;p&gt;Some hardware firewall devices to consider include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.watchguard.com/wgrd-products/rack-mount/firebox-m270-m370&#34; target=&#34;_blank&#34;&gt;WatchGuard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.cisco.com/c/en/us/products/security/firewalls/index.html&#34; target=&#34;_blank&#34;&gt;Cisco Firepower&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.ui.com/unifi-routing/unifi-security-gateway-pro-4/&#34; target=&#34;_blank&#34;&gt;UniFi Security Gateway Pro&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;network-assessment--internal-threat-protection&#34;&gt;Network Assessment &amp;amp; Internal Threat Protection&lt;/h4&gt;
&lt;p&gt;Why is security vulnerability testing necessary? Many organizations have legacy servers, or desktops/​laptops with operating systems that are no longer supported. For example, outdated Microsoft Windows XP and 7 can be compromised by malware while browsing the Internet due to &lt;a href=&#34;https://www.pcworld.com/article/3400698/nsa-warns-that-bluekeep-vulnerability-in-windows-xp-and-windows-7-is-especially-dangerous.html&#34;&gt;the BlueKeep vulnerability&lt;/a&gt;. Systems that are not patched could expose your organization to be infected with malware such as ransomware which would hold your data ransom until you pay to unlock the data.&lt;/p&gt;
&lt;p&gt;Security vulnerability testing typically results in a report outlining problematic areas such as outdated operating systems, private data that does not belong on a file server, such as social security or credit card number (personally identifying information, or PII). If PII is needed for the organization to operate, then higher security standards and an encryption system to store the private data is needed. The security vulnerabilities testing could also check if your environment is HIPAA or PCI DSS compliant if those security standards apply to you.&lt;/p&gt;
&lt;p&gt;Some security vulnerability testing technology includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.rapidfiretools.com/products/network-detective/&#34; target=&#34;_blank&#34;&gt;Rapid Fire Tools Network Detective&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.rapidfiretools.com/products/cyber-hawk/&#34; target=&#34;_blank&#34;&gt;Rapid Fire Tools Cyberhawk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;enterprise-antivirus-systems&#34;&gt;Enterprise Antivirus Systems&lt;/h4&gt;
&lt;p&gt;Antivirus software is the last line of defense if malware enters your computer. The antivirus itself would not protect you 100% from being infected by malware or virus but if you have multiple layers of security in place, then the chances are much lower that your organization’s systems would not be compromised. A company called &lt;a href=&#34;https://www.av-comparatives.org/tests/business-security-test-2019-march-june/&#34;&gt;AV-Comparatives assessed some of the popular antivirus software&lt;/a&gt; in the market.&lt;/p&gt;
&lt;p&gt;The battle with malware is endless. Case in point: The &lt;a href=&#34;https://techcrunch.com/2019/05/12/wannacry-two-years-on/&#34;&gt;WannaCry&lt;/a&gt; malware affected over 200,000 machines across the world and spread quickly. Security researchers quickly realized the malware was spreading like a computer worm, across computers and over the network, using the Windows SMB protocol.&lt;/p&gt;
&lt;p&gt;New variants of viruses and malware are developed every day, so the antivirus companies are also daily hard at work developing a way to block and remove malware.&lt;/p&gt;
&lt;p&gt;Some antivirus software includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.webroot.com/us/en/business/smb/endpoint-protection&#34; target=&#34;_blank&#34;&gt;Webroot Antivirus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.broadcom.com/products/cyber-security/endpoint/end-user&#34; target=&#34;_blank&#34;&gt;Symantec Endpoint Security&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;web-filtering-technology&#34;&gt;Web Filtering Technology&lt;/h4&gt;
&lt;p&gt;Web filtering technology blocks websites that are malicious or deemed not appropriate to visit from an organization’s network. For example, websites for gambling could be blocked to reduce employee distractions, but also to reduce access to sites popularly infected with malware, reducing the possibility of malware coming into your network.&lt;/p&gt;
&lt;p&gt;There are many competitors out there in this competitive market, and some vendors offer free proof-of-concept testing with their product before you make a big investment. Take a look at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.forcepoint.com/product/url-filtering&#34; target=&#34;_blank&#34;&gt;Forcepoint Web Filtering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.webtitan.com/webtitan-gateway/&#34; target=&#34;_blank&#34;&gt;Web Titan Gateway&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;data-loss-prevention&#34;&gt;Data Loss Prevention&lt;/h4&gt;
&lt;p&gt;Employees’ and businesses’ private information is sensitive and should be protected. Businesses, whether audited or not, should always protect their employee private information. 20 years ago paper was used to store private information and locked in a file cabinet, but in 2020 most private information is stored digitally. How do companies keep private information from leaving their office?&lt;/p&gt;
&lt;p&gt;Physically you probably can’t stop someone from walking out with private information, but digitally there is technology called digital loss prevention (DLP) that can help keep confidential information from leaving the office. For example, if someone in the office decides to copy private information onto USB storage, or tries to send a social security number or credit card information via email, this can often be prevented. Prepare your business with solutions tailored for regulations involving personal information using DLP software.&lt;/p&gt;
&lt;p&gt;Some DLP solutions to consider include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.forcepoint.com/product/dlp-data-loss-prevention&#34; target=&#34;_blank&#34;&gt;Forcepoint DLP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.broadcom.com/products/cyber-security/information-protection/data-loss-prevention&#34; target=&#34;_blank&#34;&gt;Symantec Data Loss Prevention&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;email-filtering&#34;&gt;Email Filtering&lt;/h4&gt;
&lt;p&gt;Probably one of the easiest and oldest methods to infect or phish someone is via email. There are multiple mechanisms email filtering uses to stop malicious emails: SPF and DKIM, blacklists, etc. On top of these configurable items, email filtering software vendors often release updates throughout the day to block the latest known malware or spam based on heuristics.&lt;/p&gt;
&lt;p&gt;Cloud email services such as Microsoft Office 365 are for many businesses superior to on-premise email servers due to having all the bells and whistles to proactively protect your email environment, such as spam &amp;amp; virus filtering, and email archiving for retention purposes. If you need email encryption to protect sensitive emails, this feature is also available.&lt;/p&gt;
&lt;p&gt;The distinct advantage of using hosted email service is that the cost is predictable and includes maintenance, so your email administrators do not have to worry about updating the email server software or hardware.&lt;/p&gt;
&lt;p&gt;Email filtering technology available includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.microsoft.com/en-us/security/business/threat-protection/office-365-defender&#34; target=&#34;_blank&#34;&gt;Microsoft Defender for Office 365&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.forcepoint.com/product/email-security&#34; target=&#34;_blank&#34;&gt;Forcepoint Email Filtering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.spamtitan.com/email-filtering-service/&#34; target=&#34;_blank&#34;&gt;SpamTitan&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;two-factor-authentication-2fa&#34;&gt;Two Factor Authentication (2FA)&lt;/h4&gt;
&lt;p&gt;Companies like Duo (owned by Cisco) and Google’s two-factor authentication technology are great tools to implement to improve your overall security. Beyond the usual user name and password, your smartphone or a hardware token are used to authorize the access to a website, an application, or a network. This technology is now well-established and available in most online services, and can be added to your own custom business applications.&lt;/p&gt;
&lt;p&gt;Some starting points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://duo.com/product/multi-factor-authentication-mfa&#34; target=&#34;_blank&#34;&gt;Duo Multi-Factor Authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.google.com/landing/2step/&#34; target=&#34;_blank&#34;&gt;Google Authenticator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;vpn-virtual-private-network&#34;&gt;VPN (Virtual Private Network)&lt;/h4&gt;
&lt;p&gt;Virtual private network technology allows businesses to provide secure access to office systems or applications to employees who travel or work from a remote location. That is important so that data traveling to and from the source, and many details of traffic patterns, are encrypted, so that the data cannot be captured and decrypted. VPN solutions have been around for years and are an important tool to securely and safely protect data in transit.&lt;/p&gt;
&lt;h4 id=&#34;password-reset-systems&#34;&gt;Password Reset Systems&lt;/h4&gt;
&lt;p&gt;Why are self-service password reset systems necessary, and are they secure? They eliminate many manual password assignment mistakes, keep passwords private to the user alone, and allow an organization to integrate two-factor authentication to securely reset user passwords, such as Active Directory for Windows, or other single sign-on password. Onboarding is needed for each user, which is done by sending them an email with a link to register.&lt;/p&gt;
&lt;p&gt;The password reset system could be an internal system only available to your organization. Another possibility is to access the system via VPN or even through a proxy server in the DMZ to allow password reset from anywhere.&lt;/p&gt;
&lt;p&gt;Some password reset systems include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.manageengine.com/products/self-service-password/&#34; target=&#34;_blank&#34;&gt;ManageEngine ADSelfService Plus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.microsoft.com/en-us/azure/active-directory/authentication/concept-sspr-howitworks&#34; target=&#34;_blank&#34;&gt;Azure AD Self-Service Password Reset&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;recovery-tools&#34;&gt;Recovery Tools&lt;/h3&gt;
&lt;h4 id=&#34;data-and-system-backupsdisaster-recovery&#34;&gt;Data and System Backups/​Disaster Recovery&lt;/h4&gt;
&lt;p&gt;Data backup and disaster recovery practice is a critical component for a business to speed up the process of recovery if malware attacks your systems or if a system becomes inoperable.&lt;/p&gt;
&lt;p&gt;If you are attacked by ransomware and all the critical systems and desktops are compromised and rendered useless, then the only way to recover is from backups. At that point, the disaster recovery preparation you made will be well worth what you invested into it. If you did not have an adequate backup or disaster recovery plan, your organization or company would have to start from scratch and rebuild all systems and desktops which could take weeks if not months to recover from. The lost wages, and possibly clients, due to unavailable systems and desktop to operate, probably would cost you far more than preparation does. The more options you have, the better the chances that you will get out of your bind and not prolong the situation.&lt;/p&gt;
&lt;p&gt;Some backup solutions I have worked with have the flexibility to mix and match to fit your configuration needs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.acronis.com/en-us/products/cloud/cyber-protect/backup/&#34; target=&#34;_blank&#34;&gt;Acronis Backup Solution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.rubrik.com/solutions/backup-recovery&#34; target=&#34;_blank&#34;&gt;Rubrik&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://azure.microsoft.com/en-us/services/backup/&#34; target=&#34;_blank&#34;&gt;Azure Backup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Acronis Cloud Backup allows you to back up to local storage, the cloud, and off-premise, recover a system using a USB drive, back up Office 365 emails, or backup VMware or Hyper-V environments. It also allows you to recover a single file if needed.&lt;/p&gt;
&lt;h3 id=&#34;additional-security-recommendations&#34;&gt;Additional Security Recommendations&lt;/h3&gt;
&lt;h4 id=&#34;ssltls-certificates&#34;&gt;SSL/TLS Certificates&lt;/h4&gt;
&lt;p&gt;What are SSL and TLS? SSL is outdated and replaced by TLS, but people often still use the familiar SSL name. They are an encryption system to keep sensitive information sent across the Internet encrypted so that only the intended recipient can access it.&lt;/p&gt;
&lt;p&gt;When an SSL certificate is validated, the transmitted data is not only unreadable by anyone except for the intended server, but you are relatively well assured you are communicating with the organization you expected and not with a malicious intermediary. Read more details in &lt;a href=&#34;https://www.sslshopper.com/why-ssl-the-purpose-of-using-ssl-certificates.html&#34;&gt;SSL Shopper’s Why SSL?&lt;/a&gt; article.&lt;/p&gt;
&lt;p&gt;SSL certificates were historically used primarily for higher-security web servers, but now are commonly used on almost all web servers. They are also used for other remote server access, B2B server-to-server communication, VPN access, email systems, etc.&lt;/p&gt;
&lt;h3 id=&#34;recent-destructive-incidents&#34;&gt;Recent Destructive Incidents&lt;/h3&gt;
&lt;p&gt;These incidents from just a few weeks in fall 2019 show that we have a long way to go in protecting our technology usage:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://www.nbcnewyork.com/news/local/long-island-schools-hacked-district-forced-to-pay-88000-in-ransom/1491924/&#34; target=&#34;_blank&#34;&gt;Long Island Schools Hacked; District Forced to Pay $88,000 in Ransom&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.nbcnewyork.com/news/local/ny-school-delays-start-of-year-after-ransomware-attack/1990459/&#34; target=&#34;_blank&#34;&gt;NY School Delays Start of Year After Ransomware Attack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.newsweek.com/tortoiseshell-hacker-hire-military-heroes-fake-website-1461320&#34; target=&#34;_blank&#34;&gt;Veterans Targeted by Hackers Through Fake Military Heroes Hiring Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.zdnet.com/article/hackers-target-transportation-and-shipping-industries-in-new-trojan-malware-campaign/&#34; target=&#34;_blank&#34;&gt;Hackers Target Transportation and Shipping Companies in New Trojan Malware Campaign&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://inc42.com/buzz/hacking-routers-webcams-printers-are-the-most-searched-keywords-on-the-dark-web/&#34; target=&#34;_blank&#34;&gt;Hacking of IoT – Internet of Things (webcams, security cams, printers, home routers)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;speak-with-us&#34;&gt;Speak With Us!&lt;/h3&gt;
&lt;p&gt;Keeping up with security can be a full-time job. If you need professional consulting on security tools and implementing them, &lt;a href=&#34;/contact/&#34;&gt;contact&lt;/a&gt; our team today.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Keeping our Windows Server clean</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2019/09/keeping-our-windows-server-clean/"/>
      <id>https://www.endpointdev.com/blog/2019/09/keeping-our-windows-server-clean/</id>
      <published>2019-09-27T00:00:00+00:00</published>
      <author>
        <name>Juan Pablo Ventoso</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2019/09/keeping-our-windows-server-clean/cover.jpg&#34; alt=&#34;Keeping our Windows Server clean&#34; /&gt; &lt;a href=&#34;https://flic.kr/p/ofjEj4&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://www.flickr.com/photos/oneilsh/&#34;&gt;Shawn O’Neil&lt;/a&gt;, used under &lt;a href=&#34;https://creativecommons.org/licenses/by/2.0/&#34;&gt;CC BY 2.0&lt;/a&gt;, cropped from original&lt;/p&gt;
&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I have been running websites and web applications under Windows Server for years, for both work and personal purposes. Most of them were small websites with a few daily visitors, but one particular case (a &lt;a href=&#34;https://www.pronosticoextendido.net&#34; target=&#34;_blank&#34;&gt;weather website&lt;/a&gt; I originally created as a hobby) grew over time to around one million page views per month.&lt;/p&gt;
&lt;p&gt;The website is mostly ASP.NET, with some services and components written in PHP and Python, and uses MySQL for persistence (as well as a bunch of XML/PNG files to cache weather forecasts and weather imagery). As months passed by, I’ve discovered that the default IIS and Windows log files will grow drastically so, while checking its content periodically to detect issues and vulnerabilities, we need to take action to preserve free disk space and server performance.&lt;/p&gt;
&lt;h3 id=&#34;internet-information-services-log-files&#34;&gt;Internet Information Services log files&lt;/h3&gt;
&lt;p&gt;In our IIS public folder (by default &lt;code&gt;C:\inetpub&lt;/code&gt;) we will have a path &lt;code&gt;logs\LogFiles&lt;/code&gt;. Inside that folder, the IIS service will create a set of folders, one per HTTP/FTP service that is running under our instance. How fast it will grow depends on many things, mainly traffic, but also website visibility and bad requests. But it will start to sooner or later consume our free disk space.&lt;/p&gt;
&lt;p&gt;To prevent this, we can create a batch file that can be run on a daily basis from a scheduled task.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;CleanIISLogs.bat&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bat&#34; data-lang=&#34;bat&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;forfiles /D -10 /P &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;C:\inetpub\logs\LogFiles&amp;#34;&lt;/span&gt; /S /C &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;cmd /c del /f /q @path&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This script traverses through all files on the folder passed by parameter that are more than 10 days old, and for each file, it executes the &lt;code&gt;del&lt;/code&gt; command in quiet mode. This script will search for all files within the folder and all subfolders that are more than 10 days old and delete them. After running the task, we should confirm that the used space was reduced:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/09/keeping-our-windows-server-clean/logfiles-space-green-check.jpg&#34; alt=&#34;Folder properties after cleanup&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;http-error-logs&#34;&gt;HTTP Error logs&lt;/h3&gt;
&lt;p&gt;There is another location where different operating system logs are stored: &lt;code&gt;C:\Windows\System32\LogFiles&lt;/code&gt;. And when we navigate there, we will find an &lt;code&gt;HTTPERR&lt;/code&gt; folder which will also start consuming free space as our websites are visited. The log files in that folder will save information regarding HTTP errors from any API/Service running on our IIS instance.&lt;/p&gt;
&lt;p&gt;So depending on the web traffic our applications have, it will grow faster or slower. But in any case, I recommend creating a batch file to clean old log files using the &lt;code&gt;del&lt;/code&gt; command, and to run that file on a daily basis by configuring a scheduled task.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;CleanHTTPERRLogs.bat&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bat&#34; data-lang=&#34;bat&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;forfiles /D -10 /P &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;C:\Windows\System32\LogFiles\HTTPERR&amp;#34;&lt;/span&gt; /C &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;cmd /c del /f /q @path&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This script, just as the previous one, will search for all files more than 10 days old and delete them. We don’t need to search for subfolders in this case because of Windows storing all HTTPERR logs at the same level. After running the task, we can open the folder properties and check that the used space will be the roughly the same over the days:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/09/keeping-our-windows-server-clean/httperr-space-green-check.jpg&#34; alt=&#34;Folder properties after cleanup&#34;&gt;&lt;/p&gt;
&lt;p&gt;(I know, still 1 GB after cleanup, gotta do something about those bad requests!)&lt;/p&gt;
&lt;h3 id=&#34;compressing-files&#34;&gt;Compressing files&lt;/h3&gt;
&lt;p&gt;If we need to comply with strict security/​auditing policies, and if we don’t have a backup device with enough capacity, deleting old files might not be an option. If that’s the case, we can compress the files to save space on disk.&lt;/p&gt;
&lt;p&gt;So an alternative would be to create a script to compress the files instead of deleting them using the &lt;code&gt;compact&lt;/code&gt; command. This is an example of a batch file that will compress all files in the IIS LogFiles folder that are more than 10 days old.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;CompressIISLogs.bat&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bat&#34; data-lang=&#34;bat&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;forfiles /D -10 /P &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;C:\inetpub\logs\LogFiles&amp;#34;&lt;/span&gt; /S /C &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;cmd /c compact @path&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And of course, we can create more scripts for other locations, like the &lt;code&gt;C:\Windows\Temp&lt;/code&gt; folder for example. I mentioned earlier that my website creates a lot of XML and PNG files: I have another script whose mission is keeping those folders at bay, deleting forecast files that haven’t been used for more than one day (the local forecast will be outdated and would need to refresh it from the external web service anyway).&lt;/p&gt;
&lt;h3 id=&#34;more-resources-from-microsoft&#34;&gt;More resources from Microsoft&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/forfiles&#34;&gt;forfiles syntax and usage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.microsoft.com/en-us/windows/win32/http/configuring-http-server-api-error-logging&#34;&gt;Configuring HTTP server logging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.microsoft.com/en-us/iis/manage/provisioning-and-managing-iis/managing-iis-log-file-storage&#34;&gt;Managing IIS Log folder&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </content>
    </entry>
  
    <entry>
      <title>How to set up your Ruby on Rails development environment in Windows 10 Pro with Visual Studio Code and Windows Subsystem for Linux</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/"/>
      <id>https://www.endpointdev.com/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/</id>
      <published>2019-04-04T00:00:00+00:00</published>
      <author>
        <name>Kevin Campusano</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/banner.png&#34; alt=&#34;Banner&#34;&gt;&lt;/p&gt;
&lt;p&gt;There’s one truth that I quickly discovered as I went into my first real foray into Ruby and Rails development: Working with Rails in Windows sucks.&lt;/p&gt;
&lt;p&gt;In my experience, there are two main roadblocks when trying to do this. First: &lt;a href=&#34;https://rubyinstaller.org/downloads/&#34;&gt;RubyInstaller&lt;/a&gt;, the most mainstream method for getting Ruby on Windows, is not available for every version of the interpreter. Second: I’ve run into issues while compiling native extensions for certain gems. One of these gems is, surprisingly, sqlite3, a gem that’s needed to even complete the official Getting Started tutorial over on &lt;a href=&#34;https://guides.rubyonrails.org/&#34;&gt;guides.rubyonrails.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this post, I’m going to be talking about how to avoid these pitfalls by setting up your development environment using the Windows Subsystem for Linux on Windows 10 Pro. You can jump to the summary at the bottom of the article to get a quick idea of what we’re going to do over the next few minutes.&lt;/p&gt;
&lt;p&gt;Anyway, I’ve since learned that the vast majority of the Ruby and Rails community uses either macOS or some flavor of Linux as their operating system of choice.&lt;/p&gt;
&lt;p&gt;Great, but what is a Windows guy like me to do under these circumstances? Well, there are a few options. Assuming they would like/​need to keep using Windows as their main OS, they could virtualize some version of Linux using something like Hyper-V or VitrualBox, or go dual boot with a native Linux installation on their current hardware. Provided you can set something like these up, these solutions can work beautifully, but they can have drawbacks.&lt;/p&gt;
&lt;p&gt;Virtual machines, depending on how you set them up and for graphical interfaces specially, can take a bit of a performance hit when compared to running the OS natively. So, having your entire development environment in one can get annoying after a while. The dual boot scenario gets rid of any performance degradation but then you have to go through the hassle of restarting anytime you want to work in a different OS. This can become a problem if you need to actively work on Windows-​based projects as well.&lt;/p&gt;
&lt;p&gt;There’s also the option of using something like &lt;a href=&#34;https://www.cygwin.com/&#34;&gt;Cygwin&lt;/a&gt; to create an environment very close to what you’d see in a Linux distribution.&lt;/p&gt;
&lt;p&gt;Luckily for me, it turns out that Microsoft’s own Windows Subsystem for Linux is up to the task of providing a drama-​free solution for working in a Linux environment within Windows. That’s why I thought I’d give it a shot in setting up my Ruby/​Rails development environment. I can happily say that this exercise ended up being a resounding success.&lt;/p&gt;
&lt;p&gt;When all was said and done, I could install, run and interactively debug Ruby and Rails apps from my editor of choice running on Windows (Visual Studio Code) and have all the editor amenities like syntax highlighting, code completion, automatic linting, etc. I could also run the app in WSL and access it via the browser on windows. Pretty much the whole shebang.&lt;/p&gt;
&lt;p&gt;So, how did I do that? Let’s go into the detail of it with a step-​by-​step guide. It’s important to note though, that WSL is currently available only for Windows 10 Pro. Now let’s get started.&lt;/p&gt;
&lt;h3 id=&#34;1-install-wsl&#34;&gt;1. Install WSL&lt;/h3&gt;
&lt;p&gt;First of all, if you don’t already have it, we need to install a Linux distribution via the Windows Subsystem for Linux. This is as easy as firing up the Microsoft Store and searching for “WSL”. Here’s what the store greets you with:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/microsoft-store.png&#34; alt=&#34;Microsoft Store&#34;&gt;&lt;/p&gt;
&lt;p&gt;There are multiple options here but I decided to go with Ubuntu 18.04 LTS. Ok, click it and follow the screens until you are downloading and installing it. Everything there is pretty straightforward. After the store says that the Linux distribution has been installed, &lt;strong&gt;it’s actually not fully installed yet&lt;/strong&gt;. When you launch it for the first time, it’ll do some final installing that was still pending, ask you for a new UNIX username and password, and then you’ll be ready to use your newly installed Linux distribution.&lt;/p&gt;
&lt;p&gt;Your console should look something like this now:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Installing, this may take a few minutes...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Please create a default UNIX user account. The username does not need to match your Windows username.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;For more information visit: https://aka.ms/wslusers
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Enter new UNIX username: kevin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Enter new UNIX password:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Retype new UNIX password:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;passwd: password updated successfully
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Installation successful!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;To run a command as administrator (user &amp;#34;root&amp;#34;), use &amp;#34;sudo &amp;lt;command&amp;gt;&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;See &amp;#34;man sudo_root&amp;#34; for details.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kevin@KEVIN-SATELLITE:~$&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let’s look at our freshly installed distribution’s version:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kevin@KEVIN-SATELLITE:~$ lsb_release -a
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;No LSB modules are available.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Distributor ID: Ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Description:    Ubuntu 18.04.1 LTS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Release:        18.04
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Codename:       bionic
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kevin@KEVIN-SATELLITE:~$&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Cool, we now have Linux running on Windows without too much hassle.&lt;/p&gt;
&lt;h3 id=&#34;2-install-ruby&#34;&gt;2. Install Ruby&lt;/h3&gt;
&lt;h4 id=&#34;21-install-rvm&#34;&gt;2.1 Install RVM&lt;/h4&gt;
&lt;p&gt;Now that we have Linux, let’s go ahead and install all the stuff we need for developing Rails apps. The first thing we need as far as Ruby goes, is &lt;a href=&#34;https://rvm.io/&#34;&gt;RVM&lt;/a&gt;, or Ruby Version Manager. It allows us to easily install multiple Ruby versions at the same time. A quick glance over their official web site reveals that installing RVM is pretty easy. We just have to run these two commands in our WSL Ubuntu console:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#04d;background-color:#fff0f0&#34;&gt;\c&lt;/span&gt;url -sSL https://get.rvm.io | bash -s stable&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After running the second command, among other things, we get something like this in the console:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Installing RVM to /home/kevin/.rvm/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Adding rvm PATH line to /home/kevin/.profile /home/kevin/.mkshrc /home/kevin/.bashrc /home/kevin/.zshrc.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Adding rvm loading line to /home/kevin/.profile /home/kevin/.bash_profile /home/kevin/.zlogin.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Installation of RVM in /home/kevin/.rvm/ is almost complete:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  * To start using RVM you need to run `source /home/kevin/.rvm/scripts/rvm`
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    in all your open shell windows, in rare cases you need to reopen all shell windows.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kevin@KEVIN-SATELLITE:~$&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It tells us to run one additional command in order to start using RVM so let’s do that:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;source&lt;/span&gt; /home/kevin/.rvm/scripts/rvm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And, finally, to confirm that our RVM has installed correctly:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kevin@KEVIN-SATELLITE:~$ rvm -v
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rvm 1.29.4 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&#34;22-install-a-ruby-via-rvm&#34;&gt;2.2 Install a Ruby via RVM&lt;/h4&gt;
&lt;p&gt;All right, nice. Now that we have RVM installed, we are ready to install any version of Ruby that we want. Let’s see what’s available by running this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rvm list known&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;RVM responds with something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# MRI Rubies
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ruby-]1.8.6[-p420]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ruby-]1.8.7[-head] # security released on head
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ruby-]1.9.1[-p431]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ruby-]1.9.2[-p330]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ruby-]1.9.3[-p551]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ruby-]2.0.0[-p648]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ruby-]2.1[.10]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ruby-]2.2[.10]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ruby-]2.3[.7]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ruby-]2.4[.4]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ruby-]2.5[.1]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ruby-]2.6[.0-preview2]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ruby-head
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;RVM’s &lt;code&gt;list known&lt;/code&gt; command shows us all the available Rubies that can be installed via RVM. There are a bunch of different Ruby implementations available like MRI, JRuby, IronRuby, etc. The MRI ones, listed first, stand for “Matz’s Ruby Interpreter” and represent the standard for Ruby implementations. Nowadays, it would be more accurate to call them “YARV”, but that’s a story for another day. For our purposes, let’s think of the MRI Rubies as the default Rubies. Anyway, let’s install one of the most recent ones with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rvm install 2.5.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With this, RVM will take its time downloading and installing Ruby 2.5.1 and all the required packages. After a while, Ruby would have been installed and we can test it with our usual:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ruby -v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which responds with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For those of you out there that are more on the curious side, we can run &lt;code&gt;which ruby&lt;/code&gt; and see that the Ruby that we’re running is actually installed inside the RVM installation directory. Take a look:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kevin@KEVIN-SATELLITE:~$ which ruby
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/home/kevin/.rvm/rubies/ruby-2.5.1/bin/ruby&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Nice. This Ruby, since it’s the only one we have installed so far (remember that RVM allows us to have multiple versions of Ruby at the same time), will be set as our default one by RVM. You can go to &lt;a href=&#34;https://rvm.io/rvm/basics&#34;&gt;RVM’s own documentation&lt;/a&gt; for more info on running multiple Rubies.&lt;/p&gt;
&lt;p&gt;At this point, it’s the usual Ruby process of installing the Bundler gem and creating our skeleton Rails app. Let’s breeze through it.&lt;/p&gt;
&lt;h3 id=&#34;3-create-a-new-rails-app&#34;&gt;3. Create a new Rails app&lt;/h3&gt;
&lt;h4 id=&#34;31-set-up-rails-skeleton-app&#34;&gt;3.1. Set up Rails skeleton app&lt;/h4&gt;
&lt;p&gt;Now we need to install the Bundler gem by doing:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gem install bundler&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We also need Rails, so&amp;hellip;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gem install rails&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h5 id=&#34;context-the-problem-with-windows&#34;&gt;Context: The problem with Windows&lt;/h5&gt;
&lt;p&gt;Installing Rails can take a while so, while the RubyGems package manager works its magic, I’d like to take the opportunity to point out one of the major pain points that we’re avoiding by not doing all this on plain Windows. When installing some gems like Rails, the package manager will not only have to download the packages, but also build some native extensions that are required for them to work.&lt;/p&gt;
&lt;p&gt;This is where I ran into problems with Windows. Namely, these build steps would fail because, for some reason, the Windows environment does not have (at least not by default or in a way that’s easy to get) the required build and compilation tools for these to succeed.&lt;/p&gt;
&lt;p&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;Ok, now that Rails has finished installing, we can create a new app. I’ve chosen to create it inside a new &lt;code&gt;railsdemo&lt;/code&gt; directory. So, if you’ve done the same, &lt;code&gt;cd&lt;/code&gt; to it and create a new app with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rails new my-rails-app --skip-spring --skip-listen&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h5 id=&#34;note-file-system-notifications-in-wsl&#34;&gt;Note: File system notifications in WSL&lt;/h5&gt;
&lt;p&gt;We need to pass in the &lt;code&gt;--skip-spring&lt;/code&gt; and &lt;code&gt;--skip-listen&lt;/code&gt; options because, according to &lt;a href=&#34;https://guides.rubyonrails.org/getting_started.html&#34;&gt;Rails’ official documentation&lt;/a&gt;, there are currently some limitations on file system notifications in the Windows Subsystem for Linux.&lt;/p&gt;
&lt;p&gt;Ok then, let’s &lt;code&gt;cd&lt;/code&gt; into our brand-new app’s directory and try running it with the included development web server:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kevin@KEVIN-SATELLITE:~/railsdemo$ cd my-rails-app/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Using /home/kevin/.rvm/gems/ruby-2.5.1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kevin@KEVIN-SATELLITE:~/railsdemo/my-rails-app$ rails server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Oops! Unfortunately, that doesn’t work. We get a bunch of stuff in the console ending in this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is no biggie. All it means is that we need to install a JavaScript runtime. Let’s install Node.js to appease Rails.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt-get install nodejs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ubuntu will ask you for your &lt;code&gt;sudo&lt;/code&gt; password by prompting you with &lt;code&gt;[sudo] password for kevin:&lt;/code&gt; (Obviously, instead of &lt;code&gt;kevin&lt;/code&gt;, your username will show up there.) This is the password that you put in at the very beginning when we installed Ubuntu for the WSL. So, type it in there and let &lt;code&gt;apt-get&lt;/code&gt; do its job. Once that’s done, let’s try running our app again with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rails server webrick&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h5 id=&#34;note-using-webrick-instead-of-puma&#34;&gt;Note: Using WEBrick instead of Puma&lt;/h5&gt;
&lt;p&gt;We’re explicitly telling Rails to use the WEBrick development server here because, currently, there’s an issue with Puma (another web server shipped with Rails) that prevents it from working in a WSL environment.&lt;/p&gt;
&lt;p&gt;You should now see something like this in the prompt:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;=&amp;gt; Booting WEBrick
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;=&amp;gt; Rails 5.2.1.1 application starting in development on http://localhost:3000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;=&amp;gt; Run `rails server -h` for more startup options
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[2018-12-04 16:21:10] INFO  WEBrick 1.4.2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[2018-12-04 16:21:10] INFO  ruby 2.5.1 (2018-03-29) [x86_64-linux]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[2018-12-04 16:21:10] INFO  WEBrick::HTTPServer#start: pid=132 port=3000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Well, this looks much better than our last try. Ok, now that the app is running, simply open up your browser of choice and navigate to &lt;code&gt;localhost:3000&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/rails-running.png&#34; alt=&#34;Rails app up and running&#34;&gt;&lt;/p&gt;
&lt;p&gt;How cool is that? We’re running a Rails app in our WSL Linux distribution and accessing it via a browser running in Windows.&lt;/p&gt;
&lt;h4 id=&#34;32-where-are-my-files&#34;&gt;3.2. Where are my files?&lt;/h4&gt;
&lt;p&gt;So far, we’ve fired up a WSL console, created our app and served it from there. We created folders and files as part of Rails’ initialization command (&lt;code&gt;rails new my-rails-app ...&lt;/code&gt;). Those files are definitely somewhere in our disk, but where exactly? Well that would be in our distribution’s folder within Windows. It’s hidden pretty deep within the file system but it is there. To find it, navigate to your local &lt;code&gt;AppData&lt;/code&gt; folder in &lt;code&gt;C:\Users\[YOUR_USER]\AppData\Local&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once there, go to the &lt;code&gt;Packages&lt;/code&gt; folder and, in there, look for a folder whose name corresponds to your installed Linux distribution. Mine shows up as a folder named &lt;code&gt;CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc&lt;/code&gt; because I installed Ubuntu 18.04. It may vary slightly for different systems and distributions but, given how it’s named, it should be easily identifiable nonetheless.&lt;/p&gt;
&lt;p&gt;All right, enter that folder and continue navigating to &lt;code&gt;LocalState&lt;/code&gt; and then &lt;code&gt;rootfs&lt;/code&gt;. And now, we’re finally there. This is the root of our distribution’s file system. If you navigate further through &lt;code&gt;home&lt;/code&gt;, then a folder named after your user, you’ll find our &lt;code&gt;railsdemo/my-rails-app&lt;/code&gt; directory. Inside it, that’s where the code of our app lives.&lt;/p&gt;
&lt;p&gt;So, after all that spelunking, we’ve learned a few things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Should you have multiple WSL distributions installed, they will each have a folder in the local AppData directory. That’s &lt;code&gt;C:\Users\[YOUR_USER]\AppData\Local\Packages\&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Inside this folder, the folders corresponding to the installed distributions are named using their name and version, among other things. For Ubuntu 18.04, the folder is named &lt;code&gt;CanonicalGroupLimited.Ubuntu16.04onWindows_79rhkp1fndgsc&lt;/code&gt; in my case.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The actual root of the distribution’s file system is further down that path in &lt;code&gt;C:\Users\[YOUR_USER]\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu16.04onWindows_79rhkp1fndgsc\LocalState\rootfs&lt;/code&gt;. Once there, it’s just your usual Linux directory structure. With directories like &lt;code&gt;home&lt;/code&gt; and the like.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Bonus: To access your local Windows file system from inside a WSL distribution, you can use the &lt;code&gt;/mnt/c&lt;/code&gt; directory. That directory is linked to your Windows &lt;code&gt;C:\&lt;/code&gt; drive.&lt;/p&gt;
&lt;h3 id=&#34;4-using-visual-studio-code&#34;&gt;4. Using Visual Studio Code&lt;/h3&gt;
&lt;h4 id=&#34;41-using-vs-code-to-develop-our-rails-app&#34;&gt;4.1. Using VS Code to develop our Rails app&lt;/h4&gt;
&lt;p&gt;Ok, now that we managed to get all the way into the directory inside our WSL distribution where the code for our Rails app actually lives, let’s try to open it with Visual Studio Code. There’s nothing special to this, just open it like you would open any other folder in VS Code, either right click &amp;gt; “Open with Code” from the Windows Explorer context menu, or via the “File” &amp;gt; “Open Folder&amp;hellip;” option within VS Code itself.&lt;/p&gt;
&lt;p&gt;However you choose to do it, we end up with our app’s source code ready for editing in VS Code.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/vscode.png&#34; alt=&#34;Our Rails code in VS Code&#34;&gt;&lt;/p&gt;
&lt;p&gt;All right, that looks good. But let’s start setting up VS Code for Rails development.&lt;/p&gt;
&lt;p&gt;VS Code has an integrated console. You can set it up so that it can use any console that’s currently installed in the system. Since we’re using WSL, let’s set that one up as the default. Press &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;P&lt;/code&gt; to bring up the Command Palette and type in “default shell” to search for the &lt;code&gt;Terminal: Select Default Shell&lt;/code&gt; option:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/command-palette.png&#34; alt=&#34;VS Code’s Command Palette&#34;&gt;&lt;/p&gt;
&lt;p&gt;Hit &lt;code&gt;Enter&lt;/code&gt; and select the &lt;code&gt;WSL Bash&lt;/code&gt; from the options that pop up:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/select-wsl-bash.png&#34; alt=&#34;Select WSL Bash&#34;&gt;&lt;/p&gt;
&lt;p&gt;Hit &lt;code&gt;Enter&lt;/code&gt; to make the selection. Then, press &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;`&lt;/code&gt; to bring up the Terminal. Our WSL console should show up and we can play around with it. As you will see, the terminal opens up in the root directory so don’t forget to navigate to where our code actually lives.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/wsl-terminal.png&#34; alt=&#34;WSL in VS Code’s Terminal&#34;&gt;&lt;/p&gt;
&lt;p&gt;This is the same full-​featured bash that we ran earlier to install Ruby and Rails and run our app in the development server. So, you can do all of that through the VS Code terminal as well. Go ahead, give it a go.&lt;/p&gt;
&lt;h4 id=&#34;42-improving-the-developer-experience&#34;&gt;4.2. Improving the developer experience&lt;/h4&gt;
&lt;p&gt;By now, we have access to our console and a way of editing our code all within an integrated environment. At this point we’re ready to start writing some Rails code. This is, however, the bare minimum, so let’s dive into VS Code’s rich extension ecosystem in order to turn it into a powerful Rails development environment.&lt;/p&gt;
&lt;p&gt;Press &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;X&lt;/code&gt; and the Extensions window should show up in the sidebar. Search for “ruby” and you’ll get a bunch of results.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/extensions-marketplace.png&#34; alt=&#34;VS Code’s Available Ruby Extensions&#34;&gt;&lt;/p&gt;
&lt;p&gt;Indeed, there are many extensions available that aid in Ruby/​Rails development but there are three in particular that I’ve found most useful:&lt;/p&gt;
&lt;h5 id=&#34;the-ruby-extension&#34;&gt;The Ruby Extension&lt;/h5&gt;
&lt;p&gt;This is the main extension that provides support for the Ruby language in VS Code. It includes debugging, autocomplete, IntelliSense, formatting, linters, etc. To install it, just click the green install button in VS Code’s Extensions window. VS Code will then proceed to download and install the extension. It’ll then ask you to reload VS Code. After that, the extension should be installed and ready to go.&lt;/p&gt;
&lt;p&gt;The best way to learn how to harness the full power of this tool is by reading up on their documentation. You can do this either from inside VS Code itself (in the window that opens up when you select the extension from the Extensions window) or in &lt;a href=&#34;https://github.com/rubyide/vscode-ruby&#34;&gt;their official project page on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Anyway, for this post, we’re particularly interested in interactive debugging so, as instructed by their docs, let’s install some additional gems that we’ll need for that. Run these in your terminal:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gem install ruby-debug-ide
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gem install debase&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With that, we’re ready as far as this extension goes. We’re going to be using it later.&lt;/p&gt;
&lt;h5 id=&#34;the-rails-extension&#34;&gt;The Rails Extension&lt;/h5&gt;
&lt;p&gt;This one is specific for Rails development. It includes features like code snippets, syntax highlighting support for &lt;code&gt;.erb&lt;/code&gt; files, improvements to code navigation, among others. Install it just like any other extension, the same as we did with the Ruby extension. The only difference here is that we don’t need to install any other gems for this one to work.&lt;/p&gt;
&lt;h5 id=&#34;the-ruby-solargraph-extension&#34;&gt;The Ruby Solargraph Extension:&lt;/h5&gt;
&lt;p&gt;This extension provides a better IntelliSense and code completion experience over the base Ruby extension. Another nice thing about Solargraph is that it also includes documentation in the code completion popups. Again, you can read all about it in this extension’s page in VS Code.&lt;/p&gt;
&lt;p&gt;We do need to install an additional gem for this one to work though, so running this is required:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gem install solargraph&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&#34;43-interactive-debugging-with-vs-code&#34;&gt;4.3. Interactive debugging with VS Code&lt;/h4&gt;
&lt;h5 id=&#34;431-adding-some-new-code-to-debug&#34;&gt;4.3.1. Adding some new code to debug&lt;/h5&gt;
&lt;p&gt;All right, once we have the Ruby extension installed and ready, setting up our project to support interactive debugging via VS Code is actually pretty straightforward, albeit with some gotchas.&lt;/p&gt;
&lt;p&gt;Before that though, let’s actually add some code that we can debug. With Rails, this is pretty easy to do using generators. Here, run this command in your terminal:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bin/rails generate controller Greetings hello&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The terminal will display something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/generate-controller.png&#34; alt=&#34;Rails generating a controller and action&#34;&gt;&lt;/p&gt;
&lt;p&gt;Among other things that we right now don’t care too much about, Rails has created a new &lt;code&gt;Greetings&lt;/code&gt; controller for us with a &lt;code&gt;hello&lt;/code&gt; action and even added a route so that we can access it via the browser.&lt;/p&gt;
&lt;p&gt;Make sure that your dev server is running (run &lt;code&gt;bin/rails server webrick&lt;/code&gt; if not) and let’s see what’s in there by navigating to &lt;code&gt;http://localhost:3000/greetings/hello&lt;/code&gt;. You should see something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/greetings-hello-page.png&#34; alt=&#34;The Greetings Hello page&#34;&gt;&lt;/p&gt;
&lt;p&gt;Ok, now let’s do some trivial changes. It could be something like a simple “hello world” message getting sent from the controller to the view. It could look something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ruby&#34; data-lang=&#34;ruby&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# app\controllers\greetings_controller.rb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;GreetingsController&lt;/span&gt; &amp;lt; &lt;span style=&#34;color:#036;font-weight:bold&#34;&gt;ApplicationController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06b;font-weight:bold&#34;&gt;hello&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#33b&#34;&gt;@message&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;Hello world!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#33b&#34;&gt;@message&lt;/span&gt;.upcase!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and&amp;hellip;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&amp;lt;!-- app\views\greetings\hello.html.erb --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;h1&lt;/span&gt;&amp;gt;Greetings#hello&amp;lt;/&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;h1&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;p&lt;/span&gt;&amp;gt;Find me in app/views/greetings/hello.html.erb&amp;lt;/&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;h1&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&amp;lt;&lt;/span&gt;%= @message %&amp;gt;&amp;lt;/&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now restart your server, and navigate to &lt;code&gt;http://localhost:3000/greetings/hello&lt;/code&gt; again. You should see something like this now:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/hello-world-page.png&#34; alt=&#34;The Greetings hello world page&#34;&gt;&lt;/p&gt;
&lt;h5 id=&#34;432-creating-a-launch-configuration-for-vs-code&#34;&gt;4.3.2. Creating a launch configuration for VS Code&lt;/h5&gt;
&lt;p&gt;Now, to debug our code, we need to create a new launch configuration for VS Code. With the help of the Ruby extension, that’s pretty easy: Press &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;D&lt;/code&gt; to bring up the Debugger window in the sidebar, then, near the top of the screen, expand the “No Configurations” drop down and select “Add Configuration&amp;hellip;”. It looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/debugger-add-config.png&#34; alt=&#34;Adding a new launch configuration&#34;&gt;&lt;/p&gt;
&lt;p&gt;After clicking that option, VS Code will ask you to select an environment from a list. The items that show up in this list will depend on your setup but Ruby will most definitely be there, so select that:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/select-environment.png&#34; alt=&#34;Adding a new launch configuration&#34;&gt;&lt;/p&gt;
&lt;p&gt;Once that’s done, VS Code will open a new &lt;code&gt;launch.json&lt;/code&gt; file that it has just created under a new &lt;code&gt;.vscode&lt;/code&gt; folder in the root directory of your project. This file’s purpose is to store all the possible launch configurations for the project that will allow them to be executed from within VS Code. You’re supposed to put things like “start up the dev server” or “run all the unit tests”, etc.&lt;/p&gt;
&lt;p&gt;For our Rails project however, the Ruby extension has created a bunch of configurations. Feel free to take a look but right now we only care about this one:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0.2.0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;configurations&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888&#34;&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;Listen for rdebug-ide&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;Ruby&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;attach&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;cwd&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;${workspaceRoot}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;remoteHost&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;remotePort&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;1234&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;remoteWorkspaceRoot&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;${workspaceRoot}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#888&#34;&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;    ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can’t use it just like that though. We need to tell VS Code where the source code is located in the “remote machine” (i.e. our WSL Linux distribution). Let’s then change the &lt;code&gt;remoteWorkspaceRoot&lt;/code&gt; field’s value to our project’s root in WSL. In my case that’s &lt;code&gt;/home/kevin/railsdemo/my-rails-app&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So, the whole entry now looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;Listen for rdebug-ide&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;Ruby&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;attach&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;cwd&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;${workspaceRoot}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;remoteHost&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;remotePort&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;1234&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;remoteWorkspaceRoot&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/kevin/railsdemo/my-rails-app&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This configuration allows VS Code to, with the click of a button, attach to a debugger that’s already running in some other machine and inspect the code. This is essentially a configuration for debugging remotely. We need to use such a configuration because we will not be running our Rails app in the same place where VS Code is running. That is, our Rails app will be running within WSL and VS Code will be running in the good-​old Windows host.&lt;/p&gt;
&lt;p&gt;If we were working with VS Code on Linux or if we were running Ruby directly on our Windows machine, we would be able to use a simpler configuration. In fact, of the ones that were created for us just now, the one named &lt;code&gt;Rails server&lt;/code&gt; would just do the trick.&lt;/p&gt;
&lt;p&gt;For our case though, since we’re running the Rails app and VS Code in separate “machines” (not really, but kind of, from the perspective of the debugger), we need to use this. We need to attach to a remote debugger.&lt;/p&gt;
&lt;p&gt;Again, feel free to look around the &lt;code&gt;launch.json&lt;/code&gt; file that the Ruby extension has kindly provided for us as well as their docs to get further insight into how all of this works and the extent of what you can do with it.&lt;/p&gt;
&lt;h5 id=&#34;gotcha-ruby-versions-250-and-251-have-some-issues&#34;&gt;Gotcha: Ruby versions 2.5.0 and 2.5.1 have some issues&lt;/h5&gt;
&lt;p&gt;At this point there’s one big gotcha. Ruby versions 2.5.0 and 2.5.1 have some issues that prevent doing this kind of debugging in Rails apps. You can read more about that &lt;a href=&#34;https://superuser.com/questions/1359747/is-it-possible-to-get-visual-studio-code-ide-debugging-of-apps-on-rails-5-2-to-w&#34;&gt;here&lt;/a&gt;. Thankfully, there’s a quick workaround: Replace the &lt;code&gt;require &#39;bootsnap/setup&#39;&lt;/code&gt; line in the &lt;code&gt;config\boot.rb&lt;/code&gt; file with something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ruby&#34; data-lang=&#34;ruby&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;unless&lt;/span&gt; ( ((&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;2.5.0&amp;#39;&lt;/span&gt;..&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;2.5.1&amp;#39;&lt;/span&gt;).include? &lt;span style=&#34;color:#036;font-weight:bold&#34;&gt;RUBY_VERSION&lt;/span&gt;) &amp;amp;&amp;amp; defined?&amp;gt;(&lt;span style=&#34;color:#036;font-weight:bold&#34;&gt;Debugger&lt;/span&gt;) )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#038&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;bootsnap/setup&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#888&#34;&gt;# Speed up boot time by caching expensive operations.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Basically, we’re preventing the inclusion of the &lt;code&gt;bootsnap/setup&lt;/code&gt; gem for versions of Ruby between 2.5.0 and 2.5.1.&lt;/p&gt;
&lt;h5 id=&#34;444-setting-code-breakpoints&#34;&gt;4.4.4. Setting code breakpoints&lt;/h5&gt;
&lt;p&gt;Ok, with all of that taken care of, let’s add a few breakpoints to our code by clicking close to the left of the line number where we want the code’s execution to stop. Red dots should show up. It could be something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/breakpoints.png&#34; alt=&#34;Breakpoints&#34;&gt;&lt;/p&gt;
&lt;h5 id=&#34;445-debugging-with-vs-code&#34;&gt;4.4.5. Debugging with VS Code&lt;/h5&gt;
&lt;p&gt;Now, we need to run our dev server in a way that allows for a debugger to inspect it while it executes. We can do that using the &lt;code&gt;ruby-debug-ide&lt;/code&gt; gem that we installed earlier. The command would look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rdebug-ide ./bin/rails server webrick&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Run this in your WSL terminal and it should respond with something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Fast Debugger (ruby-debug-ide 0.6.1, debase 0.2.2, file filtering is supported) listens on 127.0.0.1:1234&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, back in VS Code, go back to the Debug sidebar (remember you can press &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;D&lt;/code&gt; to get it to show up) and, in the configurations drop down that we used before, select the “Listen to rdebug-ide” option. Finally, press the green “Play” button right next to it. This one:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/attach-to-debugger.png&#34; alt=&#34;Attach to debugger&#34;&gt;&lt;/p&gt;
&lt;p&gt;After doing this, a few things happen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;VS Code shows this new tool bar:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/debug-toolbar.png&#34; alt=&#34;Debug tool bar&#34;&gt;&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;
&lt;p&gt;VS Code’s bottom bar turns from blue to orange to indicate that it’s in debug mode.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The previous prompt that we had in our terminal about &lt;code&gt;Fast Debugger&lt;/code&gt; and whatnot, continues and shows the rest of the usual WEBrick output:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;=&amp;gt; Booting WEBrick
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;=&amp;gt; Rails 5.2.2 application starting in development on http://localhost:3000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;=&amp;gt; Run `rails server -h` for more startup options
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[2018-12-05 13:18:17] INFO  WEBrick 1.4.2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[2018-12-05 13:18:17] INFO  ruby 2.5.1 (2018-03-29) [x86_64-linux]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[2018-12-05 13:18:17] INFO  WEBrick::HTTPServer#start: pid=931 port=3000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that the app is running and the VS Code debugger is attached to it, let’s navigate to &lt;code&gt;http://localhost:3000/greetings/hello&lt;/code&gt; and behold&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/04/rails-development-in-windows-10-pro-with-visual-studio-code-and-wsl/finally-debugging.png&#34; alt=&#34;Finally debugging&#34;&gt;&lt;/p&gt;
&lt;p&gt;If you take a look at VS Code now, you’ll see that code execution has stopped in the first breakpoint that we set and is waiting for us to continue. How cool is that?&lt;/p&gt;
&lt;p&gt;VS Code’s debug mode GUI is pretty complete with a console for evaluating any expression in context, watches, listings of variables in scope, call stacks&amp;hellip; Pretty much anything you would want or need in your debugging session.&lt;/p&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary&lt;/h3&gt;
&lt;p&gt;So, in summary, here’s what we just did:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Installed a WSL distribution.&lt;/li&gt;
&lt;li&gt;Installed RVM.&lt;/li&gt;
&lt;li&gt;Installed a Ruby via RVM.&lt;/li&gt;
&lt;li&gt;Created a new Rails app in the WSL distribution’s file system.&lt;/li&gt;
&lt;li&gt;Ran the Rails app in WSL and accessed it via the browser from Windows.&lt;/li&gt;
&lt;li&gt;Learned where the WSL file system lives within Windows.&lt;/li&gt;
&lt;li&gt;Opened the Rails app’s source code in VS Code.&lt;/li&gt;
&lt;li&gt;Set VS Code’s Terminal’s default shell as WSL’s bash.&lt;/li&gt;
&lt;li&gt;Installed and set up key VS Code extensions for Ruby/Rails development like “Ruby”, “Rails” and “Solargraph”.&lt;/li&gt;
&lt;li&gt;Created a demo controller with a simple hello world action.&lt;/li&gt;
&lt;li&gt;Added a suite of Ruby/​Rails launch configurations to VS Code via the launch.json file.&lt;/li&gt;
&lt;li&gt;Set up an “attach” launch configuration for our Rails app.&lt;/li&gt;
&lt;li&gt;Learned how to deal with Ruby versions 2.5.0 and 2.5.1 for debugging.&lt;/li&gt;
&lt;li&gt;Set breakpoints in VS Code.&lt;/li&gt;
&lt;li&gt;Launched the Rails app’s dev server from WSL in remote debug mode.&lt;/li&gt;
&lt;li&gt;Attached our debugger from VS Code running on Windows to the Rails app running in WSL.&lt;/li&gt;
&lt;li&gt;Had our minds blown because we accomplished all of this and now developing Ruby/​Rails on Windows will be much easier and fun.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Yeah, we’ve accomplished quite a lot! We should feel pretty proud.&lt;/p&gt;
&lt;p&gt;Few bugs will withstand the power of this combo for too long. Also, if there’s a big code base that you need to understand in order to add some features, interactive debuggers are incredibly useful for that as well.&lt;/p&gt;
&lt;p&gt;And now, if you’re on Windows (10 Pro) and your project is written in Rails, you know how to set it all up.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Running Magento 2 in Windows with XAMPP</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2019/03/running-magento-2-windows-xampp/"/>
      <id>https://www.endpointdev.com/blog/2019/03/running-magento-2-windows-xampp/</id>
      <published>2019-03-22T00:00:00+00:00</published>
      <author>
        <name>Juan Pablo Ventoso</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2019/03/running-magento-2-windows-xampp/e-commerce-safe.jpg&#34; alt=&#34;Ecommerce&#34; /&gt;&lt;br&gt;&lt;a href=&#34;https://burst.shopify.com/photos/computer-security-lock-and-payment?q=e-commerce&#34;&gt;Photo by Nicole De Khors&lt;/a&gt; · &lt;a href=&#34;https://burst.shopify.com/licenses/shopify-some-rights-reserved&#34;&gt;Burst, Some Rights Reserved&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Magento is an open source ecommerce platform, written in PHP and relying on MySQL/​MariaDB for persistence. According to &lt;a href=&#34;https://trends.builtwith.com/shop&#34;&gt;BuiltWith&lt;/a&gt;, Magento is the third most used platform in ecommerce websites. It began its life in 2008 with its first general release, and a major update (Magento 2) was released in 2015.&lt;/p&gt;
&lt;p&gt;And now, more than three years after, Magento 1 is slowly dying: There won’t be any more quality fixes or security updates from June 2020, and there won’t be extended support for fixes or new payment methods. So the obvious choice will be Magento 2 from now on.&lt;/p&gt;
&lt;p&gt;But is it fully tested yet? Is it stable enough? If we already have a website running with Magento 1, what should we do? Migrating to Magento 2 is not just hitting an “Update” button: Themes are incompatible, most extensions won’t work, and of course, there’s a big set of changes to get familiar with.&lt;/p&gt;
&lt;p&gt;So a good approach might be to get a clean Magento 2 version deployed locally, to look what we need to do to get our website updated and running, test the backend, find where the configuration sections are located, and so on. And many business users, and even some developers like myself, have Microsoft Windows installed on our computers.&lt;/p&gt;
&lt;h3 id=&#34;environment-setup&#34;&gt;Environment setup&lt;/h3&gt;
&lt;p&gt;The environment I used for this testing installation was Windows 10 Professional. As a first step, we’ll need to make sure that &lt;code&gt;localhost&lt;/code&gt; is published in our local hosts file:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Navigate to the folder &lt;code&gt;%SystemRoot%\system32\drivers\etc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Backup the existing hosts file&lt;/li&gt;
&lt;li&gt;Open a text editor with administrator rights&lt;/li&gt;
&lt;li&gt;Open the hosts file&lt;/li&gt;
&lt;li&gt;Make sure the first line after the commented (#) lines is &lt;code&gt;127.0.0.1 localhost&lt;/code&gt; and the second is &lt;code&gt;::1 localhost&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Open a cmd window with administrator rights and run the command &lt;code&gt;ipconfig /flushdns&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now we’re ready to install the environment needed to run Magento. I recommend using &lt;a href=&#34;https://www.apachefriends.org/&#34;&gt;XAMPP&lt;/a&gt;, a free Apache distribution for Windows that includes MariaDB, PHP, and Perl in a single package. Magento 2 currently runs with PHP 7.2 and it will not work with newer versions.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install XAMPP 7.2 with default settings: &lt;a href=&#34;https://www.apachefriends.org/xampp-files/7.2.15/xampp-win32-7.2.15-0-VC15-installer.exe&#34;&gt;apachefriends.org/xampp-files/7.2.15/xampp-win32-7.2.15-0-VC15-installer.exe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Download Magento 2. You will need to register on the website first: &lt;a href=&#34;https://magento.com/tech-resources/download&#34;&gt;magento.com/tech-resources/download&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Create a new “magento” subfolder (or whatever name you prefer) inside the htdocs folder in the XAMPP installation (usually &lt;code&gt;C:\xampp&lt;/code&gt;) and uncompress the Magento 2 archive there.&lt;/li&gt;
&lt;li&gt;Start the XAMPP Control Panel from the Windows start menu. In the “Apache” section, click the “Config” button and, on the menu that appears, select “PHP (php.ini)”. Remove the semicolon before the &lt;code&gt;extension=intl&lt;/code&gt;, &lt;code&gt;extension=soap&lt;/code&gt;, and &lt;code&gt;extension=xsl&lt;/code&gt; texts to enable the intl, soap and xsl extensions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/03/running-magento-2-windows-xampp/xampp-control-panel.jpg&#34; /&gt;&lt;br&gt;&lt;small&gt;Screenshot of the XAMPP Control Panel with the PHP config menu displayed.&lt;/small&gt;&lt;/p&gt;
&lt;h3 id=&#34;mysql-and-magento-setup&#34;&gt;MySQL and Magento setup&lt;/h3&gt;
&lt;p&gt;We have all the files in place and the environment ready to start configuring the database and install Magento 2.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Start the Apache and MySQL services from the XAMPP Control Panel. Wait for the green status texts to appear.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a “magento” (or whatever name you prefer) database in MySQL from phpMyAdmin, installed already on XAMPP: &lt;a href=&#34;http://localhost/phpmyadmin&#34;&gt;localhost/phpmyadmin&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the Magento 2 setup from &lt;a href=&#34;http://localhost/magento&#34;&gt;localhost/magento&lt;/a&gt; (replace the “magento” part of the URL with whatever name you have chosen to host Magento). If the setup program requires to do any additional configuration change, do it as instructed. Do a screenshot or save the final page contents for later use.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/03/running-magento-2-windows-xampp/magento-2-installation-success.jpg&#34; /&gt;&lt;br&gt;&lt;small&gt;Example of the page that will be displayed when the Magento 2 installation finishes.&lt;/small&gt;&lt;/p&gt;
&lt;h3 id=&#34;fixing-known-issues&#34;&gt;Fixing known issues&lt;/h3&gt;
&lt;p&gt;When we finish the installation process, we will have a Magento 2 instance running on our host. But we’re not ready yet! There are a couple known bugs with Magento 2 and XAMPP at the moment I’m writing this post:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The Magento admin page may not work (it shows a blank page): Fix this issue by updating the “isPathInDirectories” function inside the &lt;code&gt;Validator.php&lt;/code&gt; file as instructed in &lt;a href=&#34;https://magento.stackexchange.com/questions/252188/magento-2-2-7-admin-panel-blank-page&#34;&gt;this article.&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We might not be able to upload images (like a custom logo or product pictures): Fix this issue by updating the &lt;code&gt;design_config_form.xml&lt;/code&gt; file as shown &lt;a href=&#34;https://community.magento.com/t5/Magento-2-x-Technical-Issues/A-technical-problem-with-the-server-created-an-error-Try-again/m-p/115085#M7549&#34;&gt;here.&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After we finish making these changes, we will need to &lt;b&gt;restart the Apache service&lt;/b&gt; from the XAMPP control panel. And that’s it! We should be ready to open the Magento front page, and login into the backend.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/03/running-magento-2-windows-xampp/magento-2-front-end.jpg&#34; /&gt;&lt;br&gt;&lt;small&gt;An empty home page with the default theme enabled in Magento 2.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2019/03/running-magento-2-windows-xampp/magento-2-back-end.jpg&#34; /&gt;&lt;br&gt;&lt;small&gt;This is how the Magento 2 back-end dashboard looks like once we login.&lt;/small&gt;&lt;/p&gt;
&lt;h3 id=&#34;setting-up-the-store-a-roadmap&#34;&gt;Setting up the store: A roadmap&lt;/h3&gt;
&lt;p&gt;The purpose of this article is to get Magento 2 up and running on Windows computer, and that’s what I hope we’ve achieved so far. But just to point in a direction on what to do next, below is my usual roadmap to set up the store, add a few products and publish the catalog on the home page.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Change the default store name and logo from the section Content &amp;gt; Design &amp;gt; Configuration and choose “Edit” in the “Default store view”.&lt;/li&gt;
&lt;li&gt;Set up the default store configuration from the section Stores &amp;gt; Configuration.&lt;/li&gt;
&lt;li&gt;Create the product categories from the section Catalog &amp;gt; Categories. Set up a category name and its dependency from another category, or from the default master category.&lt;/li&gt;
&lt;li&gt;Create/edit the product attributes from the section Stores &amp;gt; Attributes (check the option “visible in storefront” to show the products in the product page). For example, custom attributes for book products would be Author, Publisher&amp;hellip;&lt;/li&gt;
&lt;li&gt;Add the attributes to the default attribute set from the section Stores &amp;gt; Attribute. This is required for the attributes to show up when adding a new product by default.&lt;/li&gt;
&lt;li&gt;Create a set of products from the section Catalog &amp;gt; Products. Set the custom variations for each product from the “Customizable options” section. Set up a short and long description, a custom SKU for each customizable option, and a tax mode.&lt;/li&gt;
&lt;li&gt;Add a widget to the homepage to show the product catalog from the section Content &amp;gt; Homepage &amp;gt; Edit &amp;gt; Show/Hide Editor &amp;gt; Add widget &amp;gt; Products list. Here we can also add any content we like, including HTML tags, images, and third-party content.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;It’s possible—​and pretty straightforward—​to run a Magento 2 instance in Windows with XAMPP. But this is just a kick-off, a simple overview: there’s a lot more to do if we want to get a full ecommerce website that is ready to scale up and support enterprise-​level traffic, like caching optimization, load balancing, and advanced server-​side monitoring.&lt;/p&gt;
&lt;p&gt;At End Point, we have professionals with a strong background in deploying powerful, reliable, fully responsive, fast, and SEO-​optimized ecommerce websites. We have experience in migrating Magento to newer versions, and even creating full Magento 2 websites from scratch. &lt;a href=&#34;/contact/&#34;&gt;Drop us a line if you want to hear more.&lt;/a&gt;&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Where are you with your Windows OS in 2019?</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2019/02/where-are-you-with-windows-2019/"/>
      <id>https://www.endpointdev.com/blog/2019/02/where-are-you-with-windows-2019/</id>
      <published>2019-02-12T00:00:00+00:00</published>
      <author>
        <name>Dan Briones</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2019/02/where-are-you-with-windows-2019/image-0.jpg&#34; alt=&#34;Windows home row&#34; /&gt;&lt;br&gt;&lt;a href=&#34;https://www.flickr.com/photos/bradleypjohnson/6139142250/&#34;&gt;Photo by bradleypjohnson&lt;/a&gt; · &lt;a href=&#34;https://creativecommons.org/licenses/by/2.0/&#34;&gt;CC BY 2.0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It should be of little surprise that on January 14, 2020, after a decade of Windows 7, Microsoft will stop providing security updates and support for this older operating system. Windows 7 was released in 2009, and due to its stability enjoyed many years as the go-to operating system for home and business alike.&lt;/p&gt;
&lt;p&gt;Even now, it is estimated by &lt;a href=&#34;https://netmarketshare.com/operating-system-market-share.aspx&#34;&gt;NetMarketShare&lt;/a&gt; that over 40% of businesses still rely on it. Despite Microsoft having ended mainstream support for Windows 7 in 2015, it still offered extended support because of the operating system’s popularity, and the generally slow adoption of newer releases. However, that support shall soon end, as will support for Windows Server 2008 R2 (release 2), which also remains in wide use. Organizations of all kinds will need to upgrade to newer operating systems to remain secure.&lt;/p&gt;
&lt;p&gt;The corporate adoption of Windows 8 and 8.1 may have been slow in part due to Microsoft’s radical changes to the user interface, such as replacing navigation menus with information-​filled “live” tiles. Windows 10, however, was designed as a compromise, providing a Windows 7-​like Start menu, while preserving the live tile interface for accessing applications and services from the desktop. There are many compelling reasons for moving from Windows 7 to Windows 10. The most notable is that Windows 7 will no longer receive any security updates, creating serious security risk and compliance issues.&lt;/p&gt;
&lt;p&gt;In 2018, Microsoft adopted a Semi-​Annual Channel (SAC) governed by the &lt;a href=&#34;https://support.microsoft.com/en-us/help/30881&#34;&gt;Modern Lifecycle Policy&lt;/a&gt;. This means that feature updates are released to the public twice a year, around March and September. Updates are cumulative. Updating to these releases is required to remain eligible for support from Microsoft. Security updates are released monthly and quarterly as rollups, and critical updates are released as needed. This is part of Microsoft’s plan to minimize vulnerabilities and security exposure in an ever-​changing digital world.&lt;/p&gt;
&lt;h3 id=&#34;time-to-change&#34;&gt;Time to change&lt;/h3&gt;
&lt;p&gt;At End Point we consider keeping our clients’ systems updated both fundamental and essential. Companies need stable systems in order to operate, and uptime is of critical importance. This is one reason we offer our RMM (Remote Management and Monitoring) services. We connect with our clients’ systems to receive custom-​defined policies for patching, then monitor and test updates before we deploy them on the cycle that best suits our customer’s workflow.&lt;/p&gt;
&lt;p&gt;We are committed to helping our clients transition safely and efficiently to Windows 10. It can be a lengthy process when accounting for the time it takes to properly test all business applications and processes before transitioning to a new OS, and the time it takes to make any necessary hardware changes and complete the update.&lt;/p&gt;
&lt;p&gt;See the charts below to learn when service will end for various versions of Windows, and contact us for a consultation on the best ways to manage your IT to keep your organization secure.&lt;/p&gt;
&lt;h3 id=&#34;windows10&#34;&gt;Windows 10&lt;/h3&gt;
&lt;hr&gt;
&lt;div class=&#34;table-scroll&#34;&gt;
&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;OS version&lt;/th&gt;&lt;th&gt;Date of availability&lt;/th&gt;&lt;th&gt;End of service for Home, Pro, and Pro for Workstation Editions&lt;/th&gt;&lt;th&gt;End of service for Enterprise and Education Editions&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
 &lt;tr&gt;&lt;td&gt;Windows&amp;nbsp;10, version 1809&lt;/td&gt;&lt;td&gt;November 13, 2018&lt;/td&gt;&lt;td&gt;May 12, 2020&lt;/td&gt;&lt;td&gt;May 11, 2021&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;Windows&amp;nbsp;10, version 1803&lt;/td&gt;&lt;td&gt;April 30, 2018&lt;/td&gt;&lt;td&gt;November 12, 2019&lt;/td&gt;&lt;td&gt;November 10, 2020&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;Windows&amp;nbsp;10, version 1709&lt;/td&gt;&lt;td&gt;October 17, 2017&lt;/td&gt;&lt;td&gt;April 9, 2019&lt;/td&gt;&lt;td&gt;April 14, 2020&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;Windows&amp;nbsp;10, version 1703&lt;/td&gt;&lt;td&gt;April 5, 2017&lt;/td&gt;&lt;td&gt;October 9, 2018&lt;/td&gt;&lt;td&gt;October 8, 2019&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;Windows&amp;nbsp;10, version 1607&lt;/td&gt;&lt;td&gt;August 2, 2016&lt;/td&gt;&lt;td&gt;April 10, 2018&lt;/td&gt;&lt;td&gt;April 9, 2019&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;Windows&amp;nbsp;10, version 1511&lt;/td&gt;&lt;td&gt;November 10, 2015&lt;/td&gt;&lt;td&gt;October 10, 2017&lt;/td&gt;&lt;td&gt;October 10, 2017&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;Windows&amp;nbsp;10, released July 2015 (version 1507)&lt;/td&gt;&lt;td&gt;July 29, 2015&lt;/td&gt;&lt;td&gt;May 9, 2017&lt;/td&gt;&lt;td&gt;May 9, 2017&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;h3 id=&#34;enterprise-ltscltsb-editions&#34;&gt;Enterprise LTSC/​LTSB Editions&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;Windows 10 LTSC/​LTSB editions also follow the Fixed Lifecycle policy. To learn more, see &lt;a href=&#34;https://support.microsoft.com/en-us/help/14085&#34;&gt;Microsoft Business, Developer and Desktop Operating Systems Policy&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;table-scroll&#34;&gt;
&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;OS version&lt;/th&gt;&lt;th&gt;Date of availability&lt;/th&gt;&lt;th&gt;Mainstream support end date&lt;/th&gt;&lt;th&gt;Extended support end date&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
 &lt;tr&gt;&lt;td&gt;Windows&amp;nbsp;10 Enterprise LTSC 2019 / Windows&amp;nbsp;10 IoT Enterprise LTSC 2019&lt;/td&gt;&lt;td&gt;November 13, 2018&lt;/td&gt;&lt;td&gt;January 9, 2024&lt;/td&gt;&lt;td&gt;January 9, 2029&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;Windows&amp;nbsp;10 Enterprise 2016 LTSB / Windows&amp;nbsp;10 IoT Enterprise 2016 LTSB&lt;/td&gt;&lt;td&gt;August 2, 2016&lt;/td&gt;&lt;td&gt;October 12, 2021&lt;/td&gt;&lt;td&gt;October 13, 2026&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;Windows&amp;nbsp;10 Enterprise 2015 LTSB / Windows&amp;nbsp;10 IoT Enterprise 2015 LTSB&lt;/td&gt;&lt;td&gt;July 29, 2015&lt;/td&gt;&lt;td&gt;October 13, 2020&lt;/td&gt;&lt;td&gt;October 14, 2025&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Note: Not all features in an update will work on all devices. A device may not be able to receive updates if the device hardware is incompatible, lacks current drivers, or is otherwise outside the original equipment manufacturer’s (OEM) support period.&lt;/p&gt;
&lt;p&gt;For more information on the Windows 10 lifecycle, see &lt;a href=&#34;https://support.microsoft.com/en-us/help/4076506&#34;&gt;Windows 10 Client and Windows Server Semi-​Annual Channel Lifecycle Policy update (February 1, 2018)&lt;/a&gt; or the &lt;a href=&#34;https://technet.microsoft.com/windows/release-info.aspx&#34;&gt;Windows 10 release information&lt;/a&gt; page. To learn more about the Windows 10 mobile lifecycle, see &lt;a href=&#34;https://support.microsoft.com/lifecycle/search?alpha=Windows%2010%20Mobile&#34;&gt;Windows 10 Mobile&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;windows81-and-7&#34;&gt;Windows 8.1 and 7&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;Prior releases of the Windows operating system are likewise governed by the Fixed Lifecycle Policy. This policy comprises two phases: mainstream support and extended support. See &lt;a href=&#34;https://support.microsoft.com/en-us/help/14085&#34;&gt;Microsoft Business, Developer and Desktop Operating Systems Policy&lt;/a&gt; for more details.&lt;/p&gt;
&lt;div class=&#34;table-scroll&#34;&gt;
&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;OS version&lt;/th&gt;&lt;th&gt;End of mainstream support&lt;/th&gt;&lt;th&gt;End of extended support&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
 &lt;tr&gt;&lt;td&gt;Windows&amp;nbsp;8.1&lt;/td&gt;&lt;td&gt;January 9, 2018&lt;/td&gt;&lt;td&gt;January 10, 2023&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;Windows&amp;nbsp;7, service pack 1*&lt;/td&gt;&lt;td&gt;January 13, 2015&lt;/td&gt;&lt;td&gt;January 14, 2020&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;* Support for Windows 7 RTM without service packs ended on April 9, 2013. Be sure to install &lt;a href=&#34;https://support.microsoft.com/en-us/help/15090&#34;&gt;Windows 7 Service Pack 1&lt;/a&gt; to continue to receive support and updates.&lt;/p&gt;
&lt;p&gt;Prior versions of Windows, including Windows 7 and Windows 8.1, have limited support when running on new processors and chipsets from manufacturers like Intel, AMD, Nvidia, and Qualcomm. For more information, see the &lt;a href=&#34;http://go.microsoft.com/fwlink/p/?LinkId=722733&#34;&gt;Microsoft Lifecycle Policy&lt;/a&gt;. A device may not be able to run prior versions of Windows if the device hardware is incompatible, lacks current drivers, or is otherwise outside the original equipment manufacturer’s (OEM) support period.&lt;/p&gt;
&lt;p&gt;(Windows life cycle charts and information were taken from Microsoft’s windows support &lt;a href=&#34;https://support.microsoft.com/en-us/help/13853/windows-lifecycle-fact-sheet&#34;&gt;site&lt;/a&gt;.)&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Data Center Relocation Initiatives: Daunting But Achievable</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2018/12/data_center_relocation_initiatives_daunting_but_achievable/"/>
      <id>https://www.endpointdev.com/blog/2018/12/data_center_relocation_initiatives_daunting_but_achievable/</id>
      <published>2018-12-20T00:00:00+00:00</published>
      <author>
        <name>Charles Chang</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2018/12/data_center_relocation_initiatives_daunting_but_achievable/banner.jpg&#34; alt=&#34;Datacenter room&#34;&gt;
&lt;a href=&#34;https://www.flickr.com/photos/seeweb/9771315606/&#34;&gt;Photo by Seeweb · CC BY-SA 2.0, cropped&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;A customer asked for our help dealing with logistical nightmares they encountered during a hardware update and data center relocation project. The customer had two active data centers, and wanted to relocate one of them to a modern Tier 4 facility to improve its performance and provide redundancy for critical systems. They also wanted to consolidate or decommission equipment to reduce recurring expenses and reduce their carbon footprint. The client decided to move to a Tier 4 data center because they provide across-​the-​board redundancy within the data center.&lt;/p&gt;
&lt;h3 id=&#34;moving-forward-with-tier-iv&#34;&gt;Moving forward with Tier IV&lt;/h3&gt;
&lt;p&gt;
&lt;img align=&#34;right&#34; src=&#34;/blog/2018/12/data_center_relocation_initiatives_daunting_but_achievable/data-center-1.jpg&#34; style=&#34;margin: 1em&#34; width=&#34;200&#34;&gt;
Enterprises typically transition to Tier 4 data centers because they offer the highest uptime guarantees, and have no single points of failure. These facilities are fully redundant in terms of electrical circuits, cooling, and networking. This architecture is best able to withstand even the most serious technical incidents without server availability being affected. Tier IV facilities have contracts with disaster management companies who will provide them, for example, with fuel in the event that a natural disaster damages the power grid.
&lt;/p&gt;
&lt;p&gt;(More information about the four data center levels is at the end of this post.)&lt;/p&gt;
&lt;h3 id=&#34;key-issues&#34;&gt;Key Issues&lt;/h3&gt;
&lt;p&gt;Some of the customer’s key concerns were:&lt;/p&gt;
&lt;p&gt;1. To safely move their virtual environment to the new data center.&lt;/p&gt;
&lt;p&gt;2. To protect assets during the relocation.&lt;/p&gt;
&lt;p&gt;3. To completely shut down the current data center and migrate seamlessly to the new data center.&lt;/p&gt;
&lt;p&gt;4. To update external DNS records without causing any downtime for the web applications used by their customers.&lt;/p&gt;
&lt;h3 id=&#34;project-planning&#34;&gt;Project Planning&lt;/h3&gt;
&lt;p&gt;To manage data center relocations is challenging because there are many moving parts and variables. Typically, planning starts 6 months ahead of the scheduled relocation date. We seek to understand the role of each system by consulting in-depth with all the teams involved. We analyze each part of the client’s tech infrastructure, break it down, and strategize about the best approach for handling the migration of each component. Additional time to plan can help especially when a large group of stakeholders is involved. Successful planning requires hard and sometimes extensive work, but makes an otherwise overwhelming data center migration smooth and worry free.&lt;/p&gt;
&lt;p&gt;Here are some of our procedures for pre-​migration preparation:&lt;/p&gt;
&lt;p&gt;1. Process the paperwork for new hardware. Identify, review, and approve all applications. Hire movers. Schedule and coordinate with internal management and key stakeholders like IT staff, system admins, contractors, circuit providers, etc.&lt;img align=&#34;right&#34; src=&#34;/blog/2018/12/data_center_relocation_initiatives_daunting_but_achievable/data-center-2.jpg&#34; style=&#34;margin: 1em&#34; width=&#34;200&#34;/&gt;&lt;/p&gt;
&lt;p&gt;2. Collect and analyze resource usage associated with the critical and non-critical systems and compare resource needs to resource availability at the new facility.&lt;/p&gt;
&lt;p&gt;3. Design and schedule the migration of critical systems to the new data center. Discuss the plan with key stakeholders.&lt;/p&gt;
&lt;p&gt;4. Make sure replicas of critical systems are up to date.&lt;/p&gt;
&lt;p&gt;5. Set up a new environment with new hardware in the new data center and establish network connections.&lt;/p&gt;
&lt;p&gt;6. Prepare hardware and virtualization technology in the new data center.&lt;/p&gt;
&lt;p&gt;7. Test, retest, and burn in the new hardware (2–4 weeks of testing).&lt;/p&gt;
&lt;p&gt;8. Create a non-​essential server within the virtualization environment and test it.&lt;/p&gt;
&lt;h3 id=&#34;a-challenge-eliminating-downtime&#34;&gt;A Challenge: Eliminating Downtime&lt;/h3&gt;
&lt;img align=&#34;right&#34; src=&#34;/blog/2018/12/data_center_relocation_initiatives_daunting_but_achievable/data-center-3.jpg&#34; style=&#34;margin: 1em&#34; width=&#34;200&#34;/&gt;
&lt;p&gt;To minimize or eliminate downtime requires very careful preparation. With this particular client, we had the luxury of their already having a secondary data center, which could accommodate a majority of the critical systems during the migration.&lt;/p&gt;
&lt;p&gt;We originally planned to leverage this by simply changing the external DNS records to point to this data center during the migration, but during planning determined that the external DNS record would not replicate worldwide quickly enough to meet the uptime needs of their global operation.&lt;/p&gt;
&lt;h3 id=&#34;solutions&#34;&gt;Solutions&lt;/h3&gt;
&lt;p&gt;After discussing various approaches, we ended up using a load balancer. A load balancer is a network device that routes incoming traffic destined for a single destination (web site, application, or service) and ‘shares’ the incoming connections across multiple destination devices or services. In this case, the data center we were to migrate to housed the client’s critical systems like web servers, database, etc. The secondary data center housed a replica of the critical systems using a replication technology, e.g. Actifio, Rubrik, SAN mirroring, VMWare SRM, or Zerto — we used Actifio in this scenario.
&lt;img align=&#34;right&#34; src=&#34;/blog/2018/12/data_center_relocation_initiatives_daunting_but_achievable/data-center-4.jpg&#34; style=&#34;margin: 1em&#34; width=&#34;200&#34;/&gt;&lt;/p&gt;
&lt;p&gt;The customer had multiple systems with external DNS records and public IP addresses. We did not change the public DNS names for the critical systems. We did change the public IP addresses associated with the public DNS names, to point to the load balancer, which then pointed to the appropriate data center throughout the process. This setup enabled a gradual, flexible, and fully controlled transition to the new data center.&lt;/p&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary&lt;/h3&gt;
&lt;img align=&#34;right&#34; src=&#34;/blog/2018/12/data_center_relocation_initiatives_daunting_but_achievable/data-center-5.jpg&#34; style=&#34;margin: 1em&#34; width=&#34;200&#34;/&gt;
&lt;p&gt;Our client wanted to reduce their servers’ power usage 40% by consolidating into a hyper-​converged system. Other goals were to reduce floor space by 50%, and monthly recurring data center charges by 50%. We transitioned them to a new hardware stack (compute, storage, network, backup environment) in a Tier 4 data center, and saved them 50% percent on data center operation costs. Additionally, during the process we corrected issues associated with disaster recovery and business continuity, leaving the client’s operations more resilient, affordable, and more secure.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;appendix-data-center-classifications&#34;&gt;Appendix: Data Center Classifications&lt;/h3&gt;
&lt;h4 id=&#34;tier-iv-best&#34;&gt;Tier IV (Best)&lt;/h4&gt;
&lt;p&gt;Tier IV data centers have redundancies for every process and data protection stream. No single outage or error can shut down the system. To keep Tier IV ranking, data centers must have 99.995% minimum uptime per year. They come equipped with 2N+1 infrastructure (two times the amount required for operation plus a backup), which is considered “fully redundant.”&lt;/p&gt;
&lt;h4 id=&#34;tier-iii-average&#34;&gt;Tier III (Average)&lt;/h4&gt;
&lt;p&gt;N+1 (the amount required for operation plus a backup) fault tolerance, which means a Tier III facility can undergo routine maintenance without a hiccup in operations. 99.982% minimum uptime per annum, used for maintenance and overwhelming emergencies.&lt;/p&gt;
&lt;h4 id=&#34;tier-ii-minimal&#34;&gt;Tier II (Minimal)&lt;/h4&gt;
&lt;p&gt;99.749% minimum uptime. Tier II facilities have considerably more downtime than Tier III facilities, primarily because Tier II facilities have less redundancy. They do however have partial cooling redundancy and multiple power redundancies.&lt;/p&gt;
&lt;h4 id=&#34;tier-i-basic-cheapest&#34;&gt;Tier I (Basic, Cheapest)&lt;/h4&gt;
&lt;p&gt;99.671% minimum uptime, with 28.8 hours of downtime each year.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Meet the End Point Windows consulting group</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2018/07/meet-the-end-point-windows-consulting-group/"/>
      <id>https://www.endpointdev.com/blog/2018/07/meet-the-end-point-windows-consulting-group/</id>
      <published>2018-07-27T00:00:00+00:00</published>
      <author>
        <name>Chris Hopkins</name>
      </author>
      <content type="html">
        &lt;p&gt;As the share of internet traffic passing through mobile devices hovers around 50%, it’s easy to forget that a lot of computing still happens on desktops and laptops—​and perhaps even easier to forget that the majority of those desktops and laptops are running Microsoft Windows.&lt;/p&gt;
&lt;p&gt;At End Point, we take pride in being a multi-platform organization and using open source technologies in real-world business environments. Our internal chat service, wiki, and many other libraries and tools we employ across our client base are all open source. However, for various reasons many companies choose Microsoft’s solutions including long-time standards Windows Server, Active Directory, and Exchange.&lt;/p&gt;
&lt;p&gt;In April 2017, &lt;strong&gt;Dan Briones&lt;/strong&gt; came to End Point to head up the company’s new Windows infrastructure services. In 2018 we added two new engineers to the mix, &lt;strong&gt;Chris Hopkins&lt;/strong&gt; and &lt;strong&gt;Charles Chang&lt;/strong&gt;, to form a full-service Windows consulting team, all local to our New York City office on Park Avenue.&lt;/p&gt;
&lt;h3 id=&#34;dan-briones&#34;&gt;Dan Briones&lt;/h3&gt;
&lt;img style=&#34;width: 300px&#34; alt=&#34;Dan Briones&#34; src=&#34;/blog/2018/07/meet-the-end-point-windows-consulting-group/dan_briones.jpg&#34; /&gt;
&lt;p&gt;Dan is the team lead and has over three decades of hands-on experience in IT systems management, systems integrations, migrations, virtualization, networking, security, orchestration, security, compliance, and maintenance, specializing in the Microsoft Windows ecosystem. He also develops applications using the .NET framework and SQL Server database. Dan works with many of our local New York clients, focusing on their network and infrastructure.&lt;/p&gt;
&lt;h3 id=&#34;charles-chang&#34;&gt;Charles Chang&lt;/h3&gt;
&lt;img style=&#34;width: 300px&#34; alt=&#34;Charles Chang&#34; src=&#34;/blog/2018/07/meet-the-end-point-windows-consulting-group/charles_chang.jpg&#34; /&gt;
&lt;p&gt;Charles has 21 years of experience in IT ranging from managing Windows infrastructure, to datacenter relocation and hardware refresh initiatives, office relocation, virtualization, disaster recovery and business continuity strategy. Charles has worked extensively with major vendors such as VMware, IBM, EMC, Cisco, and Dell in building enterprise environments in the datacenter. He also has experience in implementing data loss prevention technology, web and email filtering to protect and provide a healthy infrastructure.&lt;/p&gt;
&lt;h3 id=&#34;chris-hopkins&#34;&gt;Chris Hopkins&lt;/h3&gt;
&lt;img style=&#34;width: 300px&#34; alt=&#34;Chris Hopkins&#34; src=&#34;/blog/2018/07/meet-the-end-point-windows-consulting-group/chris_hopkins.jpg&#34; /&gt;
&lt;p&gt;Chris has 10 years of experience in IT, network support, and development. He has extensive cross-platform development and hardware knowledge. Chris excels at mail migrations, Active Directory and Windows Server environments, site-to-site website migrations, and cloud-based phone systems.&lt;/p&gt;
&lt;p&gt;Learn more about the &lt;a href=&#34;/expertise/windows-systems/&#34;&gt;services our Windows consulting group offers&lt;/a&gt; and talk to us today about how we can help you too!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Series Digital joins End Point!</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2017/06/series-digital-joins-end-point/"/>
      <id>https://www.endpointdev.com/blog/2017/06/series-digital-joins-end-point/</id>
      <published>2017-06-01T00:00:00+00:00</published>
      <author>
        <name>Jon Jensen</name>
      </author>
      <content type="html">
        &lt;p&gt;End Point has the pleasure to announce some very big news!&lt;/p&gt;
&lt;p&gt;After an amicable wooing period, End Point has purchased the software consulting company &lt;a href=&#34;http://www.seriesdigital.com/&#34;&gt;Series Digital&lt;/a&gt;, a NYC-based firm that designs and builds custom software solutions. Over the past decade, Series Digital has automated business processes, brought new ideas to market, and built large-scale dynamic infrastructure.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.seriesdigital.com/&#34;&gt;&lt;img align=&#34;right&#34; alt=&#34;Series Digital website snapshot&#34; src=&#34;/blog/2017/06/series-digital-joins-end-point/image-0.png&#34; style=&#34;width: 393px; height: 409px; margin-left: 1em&#34;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Series Digital launched in 2006 in New York City. From the start, Series Digital managed large database installations for financial services clients such as Goldman Sachs, Merrill Lynch, and Citigroup. They also worked with startups including Drop.io, Byte, Mode Analytics, Domino, and Brewster.&lt;/p&gt;
&lt;p&gt;These growth-focused, data-intensive businesses benefited from Series Digital’s expertise in scalable infrastructure, project management, and information security. Today, Series Digital supports clients across many major industry sectors and has focused its development efforts on the Microsoft .NET ecosystem. They have strong design and user experience expertise. Their client list is global.&lt;/p&gt;
&lt;p&gt;The Series Digital team began working at End Point on April 3rd, 2017.&lt;/p&gt;
&lt;p&gt;The CEO of Series Digital is Jonathan Blessing. He joins End Point’s leadership team as  Director of Client Engagements. End Point has had a relationship with Jonathan since 2010, and looks forward with great anticipation to the role he will play expanding End Point’s consulting business.&lt;/p&gt;
&lt;p&gt;To help support End Point’s expansion into .NET solutions, End Point has hired &lt;a href=&#34;/team/dan-briones/&#34;&gt;Dan Briones&lt;/a&gt;, a 25-year veteran of IT infrastructure engineering, to serve as Project and Team Manager for the Series Digital group. Dan started working with End Point at the end of March.&lt;/p&gt;
&lt;p&gt;The End Point leadership team is very excited by the addition of Dan, Jonathan, and the rest of the talented Series Digital team: Jon Allen, Ed Huott, Dylan Wooters, Vasile Laur, Liz Flyntz, Andrew Grosser, William Yeack, and Ian Neilsen.&lt;/p&gt;
&lt;p&gt;End Point’s reputation has been built upon its excellence in e-commerce, managed infrastructure, and database support. We are excited by the addition of Series Digital, which both deepens those abilities, and allows us to offer new services.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;/contact/&#34;&gt;Talk to us&lt;/a&gt; to hear about the new ways we can help you!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Easier IE Site Testing With RemoteIE</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2014/12/easier-ie-site-testing-with-remoteie/"/>
      <id>https://www.endpointdev.com/blog/2014/12/easier-ie-site-testing-with-remoteie/</id>
      <published>2014-12-02T00:00:00+00:00</published>
      <author>
        <name>Greg Davidson</name>
      </author>
      <content type="html">
        &lt;p&gt;Microsoft recently announced a new service which I’m finding very useful. &lt;a href=&#34;https://remote.modern.ie/&#34;&gt;RemoteIE&lt;/a&gt; lets you test your sites with IE (currently version 11) on Windows 10 Technical Preview. The service runs in Azure RemoteApp which is available for &lt;a href=&#34;https://web.archive.org/web/20171201025431/https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-clients&#34;&gt;several clients&lt;/a&gt; including Android, iOS and Windows Phone. What’s great about this is that you do not have to install and maintain your own virtual machine with VirtualBox or VMWare.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://remote.modern.ie/&#34; title=&#34;More information about RemoteIE from Microsoft&#34;&gt;&lt;img alt=&#34;RemoteIE&#34; border=&#34;0&#34; height=&#34;484&#34; src=&#34;/blog/2014/12/easier-ie-site-testing-with-remoteie/image-0.png&#34; title=&#34;remoteIE.png&#34; width=&#34;615&#34;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To use RemoteIE you’ll need a valid Microsoft account—​it’s easy to sign up if you don’t already one. Once you have an account and have downloaded &amp;amp; installed the Azure RemoteApp client of your choice it’s just a matter of starting it up and logging in. Happy Testing!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Updating Firefox and the Black Screen</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2014/10/updating-firefox-and-black-screen/"/>
      <id>https://www.endpointdev.com/blog/2014/10/updating-firefox-and-black-screen/</id>
      <published>2014-10-16T00:00:00+00:00</published>
      <author>
        <name>Jeff Boes</name>
      </author>
      <content type="html">
        &lt;p&gt;If you are updating your &lt;a href=&#34;https://support.mozilla.org/en-US/kb/update-firefox-latest-version&#34;&gt;Firefox installation&lt;/a&gt; for Windows and you get a puzzling black screen of doom, here’s a handy tip: disable graphics acceleration.&lt;/p&gt;
&lt;p&gt;The symptoms here are that after you upgrade Firefox to version 33, the browser will launch into a black screen, possibly with a black dialog box (it’s asking if you want to choose Firefox to be your default browser). Close this as you won’t be able to do much with it.&lt;/p&gt;
&lt;p&gt;Launch Firefox by holding down the SHIFT key and clicking on the Firefox icon. It will ask if you want to reset Firefox (Nope!) or launch in Safe mode (Yes).&lt;/p&gt;
&lt;p&gt;Once you get to that point, click the “Open menu” icon (three horizonal bars, probably at the far right of your toolbar). Choose “Preferences”, “Advanced”, and uncheck “Use hardware acceleration when available”.&lt;/p&gt;
&lt;p&gt;Close Firefox, relaunch as normal, and you should be AOK. You can try re-enabling graphics acceleration if and when your graphics driver is updated.&lt;/p&gt;
&lt;p&gt;Reference: &lt;a href=&#34;https://support.mozilla.org/questions/1025438&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>PostgreSQL Windows installer tip: passwords</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2009/07/windows-installer-tip-passwords/"/>
      <id>https://www.endpointdev.com/blog/2009/07/windows-installer-tip-passwords/</id>
      <published>2009-07-07T00:00:00+00:00</published>
      <author>
        <name>Selena Deckelmann</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;em&gt;Updated below!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When specifying a password for the Windows PostgreSQL one-click installer, you get this message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Please provide a password for the database superuser and service
account (postgres). If the service account already exists in Windows,
you must enter the current password for the account. If the account
does not exist, it will be created when you click ‘Next’.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;If you have already installed Postgres as a service, you will need to enter the &lt;strong&gt;current user postgres service user&lt;/strong&gt; password to get past the password dialog box. Meaning, if you’re logged in to Windows as ‘selena’, you need to enter selena’s password. As a non-Windows user, this baffled me, and &lt;a href=&#34;https://www.postgresql.org/message-id/937d27e10907021018o65776517heaee04605b088ad7@mail.gmail.com&#34;&gt;a few other people on this thread&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Otherwise, you can just enter a password that will be used for the ‘postgres’ database user. Hope this helps someone!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Further explanation from &lt;strong&gt;Dave Page&lt;/strong&gt;, the maintainer of the Windows package:&lt;/p&gt;
&lt;p&gt;Selena: It’s not the password for the user that you are logged in as that you need to enter, it’s the password for the service account (ie. postgres).&lt;/p&gt;
&lt;p&gt;Unlike *nix &amp;amp; Mac, service accounts on Windows need to have passwords so unfortunately we need to ensure we have the correct password to install the service. Hence, if there’s an existing postgres account, we need the existing password, otherwise the account will be created with whatever password you specify.&lt;/p&gt;
&lt;p&gt;In all OSes, we use the password entered on that page as the database superuser password.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>TrueCrypt whole-disk encryption for Windows</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2008/12/truecrypte-whole-disk-encryption-for/"/>
      <id>https://www.endpointdev.com/blog/2008/12/truecrypte-whole-disk-encryption-for/</id>
      <published>2008-12-13T00:00:00+00:00</published>
      <author>
        <name>Jon Jensen</name>
      </author>
      <content type="html">
        &lt;p&gt;A few months ago I had a chance to use a new computer with Windows Vista on it. This was actually kind of a fun experience, because Windows 98 was the last version I regularly used myself, though I was at least mildly familiar with Windows 2000 and XP on others’ desktops.&lt;/p&gt;
&lt;p&gt;Since I’ve been using encrypted filesystems on Linux since around 2003, I’ve gotten used to the comfort of knowing a lost or stolen computer would mean only lost hardware, not worries about what may happen with the data on the disk. Linux-Mandrake was the first Linux distribution I recall offering an easy encrypted filesystem option during setup. Now Ubuntu and Fedora have it too.&lt;/p&gt;
&lt;p&gt;I wanted to try the same thing on Windows, but found only folder-level encryption was commonly used out of the box. Happily, the open source &lt;a href=&#34;http://www.truecrypt.org/&#34;&gt;TrueCrypt&lt;/a&gt; software introduced whole-disk &lt;a href=&#34;https://www.truecrypt71a.com/documentation/system-encryption/&#34;&gt;system encryption&lt;/a&gt; for Windows with version 5. I’ve now used it with versions 6.0, 6.1, and 6.1a on three machines under Windows Vista and XP, and it really works well, with a few caveats.&lt;/p&gt;
&lt;p&gt;The installation is smooth, and system encryption is really easy to set up &lt;strong&gt;if&lt;/strong&gt; you don’t have any other operating systems on the machine. It will even encrypt on the fly while you’re still using the computer! It’s faster if you exit any programs that would use the disk, but it still works under active use. Very impressive.&lt;/p&gt;
&lt;p&gt;Some people have reported problems with logical (extended) partitions. Others have workarounds for dual-booting. I tried dual-booting GRUB with Windows Vista as per &lt;a href=&#34;https://web.archive.org/web/20080803080614/http://blog.redinnovation.com/2008/07/15/perfect-dual-boot-crypted-hard-disk-setup-with-truecrypt-and-luks/&#34;&gt;this blog post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That seemed to work well, and Linux booted. Vista also started but then partway through the boot process, after the GUI started up, it noticed something had changed and it died with the largest red “ERROR” message I’ve ever seen. Microsoft makes impressive error messages!&lt;/p&gt;
&lt;p&gt;I battled with dual-booting for a while but eventually gave up, as I was just playing around with it anyway. Sticking with TrueCrypt’s recommended Windows-only configuration, everything’s worked great. The additional CPU for encryption and decryption is negligible, and becomes increasingly so with multi-core CPUs.&lt;/p&gt;
&lt;p&gt;Everyone with a laptop should really be using encrypted filesystems. The peace of mind is well worth the minor initial work and the one extra passphrase to enter at boot time.&lt;/p&gt;
&lt;p&gt;As a footnote to my catch-up on the state of Windows, it’s really much easier to bear as a Unix and X Window System user with the now wide availability of open source software for Windows. I used 7zip, Audacity, Coolplayer, Cygwin, Firefox, Gimp, Git, Gnucash, Google Chrome, OpenOffice.org, Pidgin, Putty, Strawberry Perl, Vim, VirtualBox, VLC, WinMTR, WinPT (including GnuPG), WinSCP, Wireshark, and Xchat (from Silverex).&lt;/p&gt;
&lt;p&gt;Oh, and also helpful was somebody’s nice registry edit to remap the Caps Lock key as another Control key, so I don’t go crazy. The somewhat abandoned WinPT takes some prodding to get working on a few customer machines I’ve set it up on, but otherwise all the open source software I tried worked well on Windows. I’m sure there’s much more out there too. &lt;a href=&#34;https://web.archive.org/web/20080803082335/http://2008.utosc.com/presentation/54/&#34;&gt;This UTOSC presentation&lt;/a&gt;’s slides mentions more.&lt;/p&gt;
&lt;p&gt;However, it’s still no replacement for a fully free system. So despite the brief investigation, I’ll be sticking with Linux. :)&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>64-bit Windows naming fun</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2008/09/64-bit-windows-naming-fun/"/>
      <id>https://www.endpointdev.com/blog/2008/09/64-bit-windows-naming-fun/</id>
      <published>2008-09-30T00:00:00+00:00</published>
      <author>
        <name>Jon Jensen</name>
      </author>
      <content type="html">
        &lt;p&gt;At OSNews.com the article &lt;a href=&#34;http://www.osnews.com/story/20330/Windows_x64_Watch_List&#34;&gt;Windows x64 Watch List&lt;/a&gt; describes some of the key differences between 64-bit and 32-bit Windows. It’s pretty interesting, and mostly pretty reasonable. But this one caught my eye:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are now separate system file sections for both 32-bit and 64-bit code&lt;/p&gt;
&lt;p&gt;Windows x64’s architecture keeps all 32-bit system files in a directory named “C:\WINDOWS\SysWOW64”, and 64-bit system files are place in the the oddly-named “C:\WINDOWS\system32” directory. For most applications, this doesn’t matter, as Windows will re-direct all 32-bit files to use “SysWOW64” automatically to avoid conflicts.&lt;/p&gt;
&lt;p&gt;However, anyone (like us system admins) who depend on VBScripts to accomplish tasks, may have to directly reference “SysWOW64” files if needed, since re-direction doesn’t apply as smoothly.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;I’ve been using 64-bit Linux since 2005 and found there to be some learning curve there, with distributors taking different approaches to supporting 32-bit libraries and applications on a 64-bit operating system.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.debian-administration.org/articles/534&#34;&gt;Debian Etch approach&lt;/a&gt; is to treat the 64-bit architecture as “normal”, for lack of a better word, with 64-bit libraries residing in /lib and /usr/lib as always. It’s recommended to run a 32-bit chroot with important libraries in &lt;a href=&#34;https://web.archive.org/web/20090726073930/http://packages.debian.org/stable/ia32-libs&#34;&gt;the ia32-libs package&lt;/a&gt; going into /emul/ia32-linux. &lt;a href=&#34;https://web.archive.org/web/20110813093451/https://help.ubuntu.com/community/32bit_and_64bit&#34;&gt;Ubuntu is similar&lt;/a&gt;, but its ia32-libs puts its ia32-libs files into /usr/lib32.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://web.archive.org/web/20080915055508/http://www.redhat.com/magazine/009jul05/features/multilib/&#34;&gt;Red Hat approach&lt;/a&gt; called “multilib” keeps 32-bit libraries in /lib and /usr/lib with new 64-bit libraries living in /lib64 and /usr/lib64. (I mentioned this a while back while discussing &lt;a href=&#34;/blog/2008/07/building-perl-on-64-bit/&#34;&gt;building a custom Perl on 64-bit Red Hat OSes&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Each way has its tradeoffs, and causes a bit of trouble. That’s just the cost of dealing with multiple architectures in a single running OS, where no such support was previously needed.&lt;/p&gt;
&lt;p&gt;But the Windows way? Putting your 32-bit libraries in C:\WINDOWS\SysWOW64 and your 64-bit libraries in C:\WINDOWS\system32? It hurts to see the names be exactly backwards. That’s really tops for confusion.&lt;/p&gt;

      </content>
    </entry>
  
</feed>
