Replacing thrown exception with more descriptive exception during file I/O
Give your code some room to breathe with a few new lines, they're free.

Before:

public MyUpdater(...)
{
    _reader = ...;
    try {
        // Open immediately to ensure we can read the file:
        _reader.AccessForReading();
    } catch (IOException ioex) {
        var extype = ioex.GetType();
        if (extype == typeof(FileNotFoundException) || extype == typeof(DirectoryNotFoundException)) {
            // This is an explicit failure scenario in which case we do not want the raw IOException to escape
            throw new InvalidOperationException("File to update does not exist! It may have been moved because of foobar reason xyz ...", ioex);
        } else {
            // re-throw all other
            throw;
        }
    }
}


After:

public MyUpdater(...)
{
    _reader = ...;

    try 
    {
        // Open immediately to ensure we can read the file:
        _reader.AccessForReading();
    } 
    catch (IOException ioex) 
    {
        var extype = ioex.GetType(); 

        if (extype == typeof(FileNotFoundException) || extype == typeof(DirectoryNotFoundException)) 
       {
            // This is an explicit failure scenario in which case we do not want the raw IOException to escape
            throw new InvalidOperationException("File to update does not exist! It may have been moved because of foobar reason xyz ...", ioex);
        } 
        else 
        {
            // re-throw all other
            throw;
        }
    }
}


Secondly, catching, filtering and then rethrowing seems wasteful here, why not just catch the explicit exceptions you hope to catch?

public MyUpdater(...)
{
    _reader = ...;

    try 
    {
        // Open immediately to ensure we can read the file:
        _reader.AccessForReading();
    } 
    catch (FileNotFoundException ex) 
    {
            // This is an explicit failure scenario in which case we do not want the raw IOException to escape
            throw new InvalidOperationException("File to update does not exist! It may have been moved because of foobar reason xyz ...", ex);
    }
    catch (DirectoryNotFoundException ex) 
    {
            // This is an explicit failure scenario in which case we do not want the raw IOException to escape
            throw new InvalidOperationException("File to update does not exist! It may have been moved because of foobar reason xyz ...", ex);
    }
}


Granted, this breaks DRY a little, but it is significantly easier to read. You can reduce duplication further by extraction your exception creation to another method.

public MyUpdater(...)
{
    _reader = ...;

    try 
    {
        // Open immediately to ensure we can read the file:
        _reader.AccessForReading();
    } 
    catch (FileNotFoundException ex) 
    {
            // This is an explicit failure scenario in which case we do not want the raw IOException to escape
            throw CreateUpdateFileMissingException(ex);
    }
    catch (DirectoryNotFoundException ex) 
    {
            // This is an explicit failure scenario in which case we do not want the raw IOException to escape
            throw CreateUpdateFileMissingException(ex);
    }
}

public InvalidOperationException CreateUpdateFileMissingException(Exception ex)
{
    return new InvalidOperationException("File to update does not exist! It may have been moved because of foobar reason xyz ...", ex)
}


On the other hand this bonus is negated if there are a lot of exception types you want to catch, so if that list grows, then sticking with your filtering method may be the better course of action.

As for what exception you should be throwing here, it appears that the error is that the file cannot be found, so what's wrong with a FileNotFoundException with a different message?

Lastly, the comment // re-throw all other is simply describing what your code is doing. That is your code's job. Comments should explain why you have made certain choices. If the code is too complex to understand it should be refactored and comments explaining what code does should only be considered in extreme circumstances where refactoring is a poor choice.