3 Nov 2021

Tenda Nova MW12 MW6 cannot connect to wireless printer on mesh network from wired computer

I have a home network on a TP-Link Archer C7 router, which I was using for WiFi, but also have some computers wired directly on ethernet connections. It's been a fairly reliable router, but the WiFi has never been great. 

I finally replaced the WiFi part of it using a 3-node Tenda Nova MW12 mesh system. To do this, I plugged the primary Tenda node into one of the ports on the router. Then I placed the other Tenda nodes around the house, turned off the old router's wireless function, and we were off! Well, after changing the SSID of the Tenda mesh to be the same as the old router's SSID, with same password, so I wouldn't have to update the wireless connection details on all the devices around the house...

Anyway, all was fine until I wanted to print to my wireless HP M252DW printer, from one of the computers that were still wired to the old router. My windows machine could no longer see the wireless printer on the network. Turns out, the Tenda mesh is on a different IP subnet to the old router. By default the mesh devices were on the 192.168.5.x subnet, whereas the old router subnet was 192.168.0.x. 

After a lot of faffing about, it turns out that Tenda have anticipated my use case, and I just hadn't configured the mesh properly. By default, the Tenda system is set to DHCP mode under Internet Settings > Connection Type. All I had to do was change it to Bridge mode. Then the mesh started using 192.168.0.x IP addresses assigned by the old router instead, and I was now able to print to the mesh-bound wireless printer, from the old wired network.

If anybody is interested in my thoughts of the Tenda Nova MW12 mesh, it's early days but the WiFi is markedly faster than via the old Archer C7, and the coverage around the house is now superb. Haven't had any dropouts yet. The MW12 also has a PPPoE mode, and port forwarding, so really I should be able to bin my old router completely. I will be doing this as soon as I get a cheap ethernet hub, as I need more ports than the Tenda node provides.

17 Mar 2021

Download SFTP file and send to Azure Blob Storage with minimal memory usage

 

In Azure we use the Renci SSH.NET library to download a file from an SFTP server and put it into Blob Storage.

Our first approach was simple: Downloading the file in entirety to memory, and then uploading to blob store.

using (var memStream = new MemoryStream())
{
    sftpClient.DownloadFile("sftpFilePath", memStream);
    memStream.Position = 0;
    var container = cloudBlobClient.GetContainerReference("blobContainerName");
    var blob = container.GetBlockBlobReference("blobName");
    await blob.UploadFromStreamAsync(memStream);
}
However, we soon realized this approach meant we consumed as much memory as the file's size. We fixed this by instead opening a writeable stream to the blob, and connecting that directly to the sftp client's DownloadFile method: 
var container = cloudBlobClient.GetContainerReference("blobContainerName");
var blob = container.GetBlockBlobReference("blobName");
using (var blobStream = blob.OpenWrite())
{
    sftpClient.DownloadFile("sftpFilePath", blobStream);
}

Note however that with this approach you may run into the limit of 100,000 uncommitted blocks that azure blob storage enforces. We have to select the block size, which is the size of each "chunk" of blob that the SDK uploads. You do this by setting the blob's StreamWriteSizeInBytes property, which can be between 16Kb and 100Mb. So for 4Mb blocks, do: 

blob.StreamWriteSizeInBytes = 4 * 1024 * 1024;


However, in version 11.1.0.0 of the azure storage library, we noticed that this setting seemed to be ignored when using OpenWrite, and the actual block size was something like 5Kb! This meant we hit the uncommitted block error for files over 450Mb in size. So, to handle very large file uploads we had to instead revert to using UploadFromStreamAsync (which does honour the StreamWriteSizeInBytes property), and had to do some extra work to surface the reading stream to pass to it.

1 Feb 2021

Find and kill a Windows 10 process on a given port

 

FIND the naughty process PID:

netstat -a -n -o | findstr *PORT_#_HERE*


KILL the naughty process:

taskkill /f /pid *PID_#_HERE*


9 Apr 2018

Windows 10 Start Menu "Best Match" won't open

If you open your Win 10 start menu, search for an app and then click or press enter on the "Best Match" result, and it won't open, it's ANNOYING.

The solution is also annoying. There's a folder in your AppSettings that you're going to need to delete:

C:\Users\YOUR_USERNAME\AppData\Local\Packages\Microsoft.Windows.Cortana_cw5n1h2txyewy

However, you can't delete it while you're logged in. So you're going to need to:


  1. Create a new user, or use an existing other account that isn't currently logged in.
  2. Make it Admin or give it write permissions on your user folder mentioned above.
  3. Log out of your problem account.
  4. Log into the new account.
  5. Find the folder mentioned above and delete it.
  6. Log out of the new account.
  7. Log back into your old account and the problem should be fixed.
  8. Don't forget to remove Admin role from the other user and remove any permissions you gave it.


1 May 2017

Pick up Emails from IMAP

            
using (ImapClient client = new ImapClient("server.name", 993, "account.name", "account.passwd", AuthMethod.Login, true))
            {

                IEnumerable<uint> uids = client.Search(SearchCondition.SentSince(DateTime.Now.AddDays(-7)));
                IEnumerable<mailmessage> messages = client.GetMessages(uids, FetchOptions.HeadersOnly);
            }

22 Sept 2016

IIS 503 Service Unavailable - Classic ASP

Just had the horrible 503 Service Unavailable issue when trying to view a Classic ASP site hosted on Windows 10 IIS. Turns out the Windows 10 Anniversary update broke it... but I digress....

In IIS I saw that the Classic ASP App Pool had stopped. But if restarted, it just stopped again when I hit the website.

Event Viewer said "The Module DLL C:\WINDOWS\system32\inetsrv\rewrite.dll failed to load. The data is the error." This is the IIS Rewrite 2 module.

So I went into Programs and Features, located "IIS URL Rewrite Module 2" and hit "Repair".

Then I restarted the crashed Classic App Pool in IIS, viewed the website, and the problem was fixed.

13 Nov 2015

Use Technicolor modem as slave wireless access point

1) Used "other" easy setup wizard to gain access to turn off DHCP on slave router
2) Set slave IP to be out of the DHCP range of the main router, but within the subnet.
3) Setup wifi SSID, password etc to match the main router, but use different wireless channel.
4) Put slave at opposite end of house, connected over powerline.

Bingo... Seamless wireless transition throughout the house and garden. Can also connect devices to the slave via cable.

11 Sept 2015

Bluetooth Issues with Lenovo ThinkPad T410 - Error 1935

Horrible recurring problems with this machine where the Bluetooth drivers get screwed up.

I tried to fix by downloading the latest ThinkPad Bluetooth with Enhanced Data Rate Software for Windows 7 and reinstalling, but it kept failing with the dreaded Error 1935. An error occurred during the installation of assembly 'Microsoft.VC80.ATL error.

The only thing that fixed this was by running the Microsoft Fix It tool, telling it that I had a problem with Installing the Thinkpad Bluetooth software. It fixed stuff, rebooted my machine (without asking!) and I was then able to install the software.

17 Mar 2015

IIS 7 URL Rewrite - Ensure SSL/HTTPS and Ensure Fully Qualified Domain Name (FQDN) as Hostname

I had the goal of ensuring all traffic on a web site was via SSL, and also using the canonical hostname, i.e. www.mysite.com rather than just mysite.com.

After installing URL Rewrite 2.0 on IIS, this was achieved by adding the following to the site's root web.config file.


    
        
            
                
                    
                    
                        
                    
                    
                
                
                    
                    
                        
                    
                    
                
            
           
    

16 Feb 2015

Get Inserted ID from SQLOLEDB ADO Recordset.AddNew with SQL Server

Migrating a legacy ASP site to SQL Server, had a prob whereby lots of code that previously used RecordSet.AddNew() with RecordSet.Update(), and then immeditately retrieved the inserted ID from the RecordSet, suddenly failed to get the inserted ID.

The solution was to set the RecordSet CursorType to adOpenKeyset (constant value 1)

10 Feb 2015

Edit Web.Config from File Explorer in Windows 7 / 8 / 2012 - Read Only for Administrator

Don't you hate that UAC thing whereby you can't edit your site's web.config file directly from File Explorer? It lets you open it in notepad and then won't let you save. Even though you're an Administrator! ANNOYING!

It's because of the default Access Control List on the Inetpub folder. When you edit any file under that folder, Windows busts you down to User level permissions, even though your user is a member of the Administrators group.

A quick fix is to grant full access permissions over Inetpub to your explicit user account. Run this in an elevated (Run As Administrator) command prompt (Note you don't need to type your actual username in here, the environment variables will be interpolated for you automatically):

icacls %systemdrive%\inetpub /grant  %userdomain%\%username%:(OI)(CI)(F) /grant %userdomain%\%username%:F

27 Nov 2014

Lenovo ThinkPad T410 Fingerprint Reader stopped working after update

Did a long-put-off update on my Thinkpad with all its recommended Lenovo drivers from the ThinkVantage tool. All dandy, apart from the fingerprint reader stopped working. It used to have a little green light on to show it was ready, now it was off in sleep mode.

Simple solution: Go to Device Manager > Biometric Devices > TouchChip Fingerprint Coprocessor > Properties > Power Management and untick the "Allow the computer to turn off this device" option.

18 Nov 2014

Remote Desktop connection failed

Couldn't connect via RDC via an RD Gateway. Tried all sorts but in the end tried going into Device Manager, showing all hidden devices, and removed all the ISATAP virtual tunneling adapters that various Virtual Machines had added. It worked!

22 Oct 2014

Installation Ended Prematurely - MVC Hotfix MS14-059

Just had a scary moment when a production MVC application went down due to MS Updates removing the MVC 3.0.0.0 dll and replacing it with MVC 3.0.0.1.

Although we located the MS Hotfix (MS14-059), the installer gave us a worrying "Installer Ended Prematurely" error.

The solution was simple - the server needed a reboot to allow it to install some pending updates before the Hotfix could be run.

21 Oct 2014

VBScript / Classic ASP value equivalency crib sheet


DBNULL VALUE

Equivalent to: NULL

ZERO VALUE 

Equivalent to: FALSE

STRING NUMBER VALUE (e.g "0")

Equivalent to: NUMBER VALUE (but STRING ZERO is not FALSE!)

EMPTY VALUE / UNDEFINED VALUE / UNPROVIDED REQUEST VALUE

Equivalent to: FALSE (but not NULL!)

EMPTY STRING ("")

Not equivalent to FALSE, EMPTY, ZERO or NULL!


NOTE: If you compare NULL with anything, it just returns NULL, not TRUE/FALSE

NOTE: While 0 is equivalent to FALSE, 1 is NOT equivalent to TRUE


19 Sept 2014

A simple script for scheduled Access DB backups

Here's a simple wee backup script to save as a VBS file (e.g. backup.vbs) and then run from Windows Task Scheduler.

Saves a copy with a datestamp in the filename e.g. Data_2014-09-07.mdb

Dim oldfilePath
Dim newfilePath

oldfilePath = "C:\LivePath\Data.mdb"
newfilePath = "D:\Data_Backups\Data_"

newfilePath = newfilePath & datepart("yyyy", date()) & "-"
newfilePath = newfilePath & Right("0" & DatePart("m",Date), 2) & "-"
newfilePath = newfilePath & Right("0" & DatePart("d",Date), 2) & ".mdb"

Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")

fso.CopyFile oldfilePath, newfilePath, true

Set fso = Nothing
 

25 Aug 2014

Adding a Clear Filter / Clear Search Button to DataTables

I wanted a generic way to add a "clear filter" button to the text filter on all the DataTables on a site.

One way would be to change the input type of the filter to "search" - then HTML5 browsers will automatically show a clear widget. However, you'd have to press return after clicking it, so I wanted a one-click solution.

Here's what I came up with. It works with DataTables 1.9.


// Setup DataTable Defaults
$.extend( $.fn.dataTable.defaults, {
 fnInitComplete: function(oSettings, json) {

  // Add "Clear Filter" button to Filter
  var btnClear = $('<button class="btnClearDataTableFilter">CLEAR</button>');
  btnClear.appendTo($('#' + oSettings.sTableId).parents('.dataTables_wrapper').find('.dataTables_filter'));
  $('#' + oSettings.sTableId + '_wrapper .btnClearDataTableFilter').click(function () {
   $('#' + oSettings.sTableId).dataTable().fnFilter('');
  });
 }
});

16 May 2014

A ValueInjecter Injection that ignores null values

Want to use ValueInjecter but don't want to copy null values into your model?

public class NoNullsInjection : ConventionInjection
{
    protected override bool Match(ConventionInfo c)
    {
        return c.SourceProp.Name == c.TargetProp.Name
                && c.SourceProp.Value != null;
    }
}

Usage:

target.InjectFrom(new NoNullsInjection(), source);

15 Apr 2014

Access MDB activity causes Visual Studio 2012 "File Modified Outside Environment" warning

I've found a way to stop this when it starts. Close VS2012 and delete your Visual Studio solution's (hidden) SUO file, which you will find with the SLN file.
If I helped you out today, you can buy me a beer below. Cheers!