Friday, June 22, 2018

Finding the default application for a file extension in WIndows

Copyright © 2018, Steven E. Houchin. All rights reserved.

A client of mine has a Windows application that lists various data files, and when a data file is clicked, opens the associated application for the file's extension, using an established API to do that.  It has worked fine for a long time, but gives unexpected results on Windows 10 for html files. The default program for html on the system is configured for MS Edge, but a click on the html file in the application always brought up Internet Explorer.

Sure enough, following the traditional file association scheme in the Registry showed IE, not Edge.  The traditional scheme is:

HKEY_CLASSES_ROOT\.html
    (Default) = program_identifier
HKEY_CLASSES_ROOT\program_identifier\shell\open\command
    (Default) = full path to default program

By doing more research, I discovered that M*Soft changed the file association scheme starting, I think, with Vista.  The old scheme may still work for some file types, but finding the right browser requires using the new scheme.

The new post-Vista scheme I found requires looking into file associations for Window Explorer and following from there.

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\
  FileExts\.html\UserChoice
    ProgId = program_identifier
HKEY_CLASSES_ROOT\program_identifier\shell\open\command
    (Default) = full path to default program

In the new scheme, for MS Edge, the ProgId value could be something strange like "AppXq0fevzme2pys62n3e0fbqa7peapykr8v", whereas the Firefox browser may be "FirefoxURL". The obvious advantage of this new scheme is that using HKEY_CURRENT_USER allows for user-by-user default program setting, where, I think, the traditional scheme sets it for all users.

So, by writing my own Registry traverser for the new scheme, I finally got MS Edge to open as the default browser. If the new scheme fails to find the default program, my code falls back to the traditional scheme shown before.



Friday, September 22, 2017

Making a Modal Dialog with C# and WPF

Copyright © 2017, Steven E. Houchin. All rights reserved.

For a unit test program I'm developing to validate a new library API, I created a window to show some attributes of an object. I wanted that window to display as follows:

  • normal modal dialog
  • centered on parent window
  • not shown in taskbar
  • can be resized
  • can be minimized

I'm using .NET Framework 4, C# and WPF on a Windows 10 system.

Here are some observations about how to properly set up a dialog as I describe above.

First, to show as a modal dialog, I call the Window class's ShowDialog method to open and show the dialog from the parent Window class:


    // Create the Detail View Controller object
    IDetailViewControl view_controller =
            app.MakeDetailViewController();

    // Create the Detail View Object, passing in this
    // Window class as a parent
    MyDetailView detail =
            new MyDetailView(myDataObject, view_controller, this);
                
    // Show the Detail dialog
    detail.ShowDialog();

Second, to center the dialog on its parent window, the MyDetailView dialog class's constructor sets its Owner property to the Window object passed by the caller:


    public partial class MyDetailView : Window
    {
        public MyDetailView (MyData dataObject,
                             IDetailViewControl controller,
                             Window owner)
        {
            this.Owner = owner;   // set parent window as owner
            InitializeComponent();

            // other constructor initialization
        }
    }



Note that, in the above code, the parent Window code could have set itself as Owner using the 'detail' object before calling ShowDialog, but I chose to have the dialog take care of that. Finally, to complete a centered dialog when open, the dialog Window's XAML properties must specify:

    WindowStartupLocation="CenterOwner"

Third, I set the dialog Window's XAML property to not show in the taskbar:

    ShowInTaskbar="False"

Set to False, it means this dialog will not show in the taskbar, but Restoring the parent window from the taskbar brings the MyDetailView dialog to the top with it.

Lastly, I set the dialog Window's XAML property so it can be resized and minimized:

    ResizeMode="CanResize"

The ResizeMode setting can instead be set to CanMinimize if resizing isn't desired. The CanResize value implies CanMinimize, since minimizing and maximizing is assumed to be part of any resize operation.

So, with the WPF Window implemented this way, it acts like a classic modal dialog we're all accustomed to.

Monday, August 28, 2017

Design Pattern example: Singleton and Observer (Part III)

Copyright © 2017, Steven E. Houchin. All rights reserved.

In my last two postings on this subject, I outlined a Logger class used by my Parser class for logging errors.  In this article, I show a more sophisticated approach for the application to register and unregister as an interested Observer with Logger, so it is notified when an error message is posted to Logger.

First, the Observer class must derive from the ILoggerObserver interface:

///
/// Interface to be implemented by objects who wish to
/// observe changes on the Logger object's data.
///
public interface ILoggerObserver
{
    void didAddLogMessage(string message);
}


In my original posting, I showed the following code snippet showing the Observer register and unregister sequence:


public class MyParser : ILoggerObserver
{
    ...

    public void MyParseLogic()
    {
        // Register to log any parsing errors
        Logger log = Logger.Instance;
        log.Attach(this);

        // Parse my data file
        Parser p = new Parser(my_file_path_to_be_parsed);
        p.Parse(); // will call the same Logger instance

        log.Detach(this); // resign as a Logger observer

        ...
    }

    /// Implement the ILoggerObserver interface
    public void didAddLogMessage(string message)
    {
        // Output the message to a TextBlock control or
        // pop up a Message Box.
        ...
    }

} // end class MyParser

Note that before parsing is done, the MyParser class calls Logger's Attach method to register as an observer, and after finishing with the parsing, calls Detach to unregister. But I later came up with a better design so Detach can be done automatically. I accomplish this by taking advantage of the .NET IDisposable interface.

I created a new container class named LoggerObserverDisposer, derived from IDisposable. Its only job is to call Logger's Detach for the Observer when it's being disposed by .NET. The target Observer object is provided to its constructor and remembered for when the Detach is done.

Here is that new Disposer class:


/// Container class for an observer, which terminates its observing
/// when out of scope.
public class LoggerObserverDisposer : IDisposable
{
    protected ILoggerObserver _observer = null;
    public LoggerObserverDisposer(ILoggerObserver observer)
    {
        // Remember the observer object to be disposed
        _observer = observer;
    }

    public void Dispose()
    {
        Dispose(true);  // call our Dispose method below
        // prevent redundant Dispose during garbage collection
        GC.SuppressFinalize(this); 
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Get the Logger object
            Logger logger = Logger.Instance;

            // Make operation atomic
            Monitor.Enter(logger);
            if (_observer != null)
            {
                // Remove the observer from Logger
                logger.Detach(_observer);
                _observer = null;
            }
            Monitor.Exit(logger);
        }
    }
}   // end class LoggerObserverDisposer


Previously, here is what Logger's Attach method looked like:


    /// Add an Observer object to the list of those
    /// to be notified of changes.
    public void Attach(ILoggerObserver observer)
    {
        if (null != observer)
        {
            // Add this observer to the list, but just once
            Detach(observer);
            _observers.Add(observer);
        }
    }


Now, it is changed to make use of our new LoggerObserverDisposer class. Attach returns a new LoggerObserverDisposer instance for the Observer, but only if requested by the caller.


    /// Add an Observer object to the list of those to be notified
    /// of changes, and return a Disposer object for the observer,
    /// if requested.
    /// 
    /// Params:
    /// "observer" - The Observer object to add to the list.
    /// "doMakeDisposer" - true to return a Disposer object.
    /// Returns: A Disposer object, if requested, or null
    public LoggerObserverDisposer Attach(ILoggerObserver observer,
                                       bool doMakeDisposer = false)
    {
        if (null != observer)
        {
            // Add this observer to the list
            Detach(observer);
            _observers.Add(observer);
        }

        // Return an object the caller can include in a
        // 'using' statement so the observer is automatically
        // removed when the Disposer goes out of scope
        return (doMakeDisposer) ?
                new LoggerObserverDisposer(observer) : null;
    }


Finally, the MyParser class changes to use this new version of Logger's Attach, but never needs to explicitly call Detach:

    public void MyParseLogic()
    {
        // Register to log any parsing errors
        Logger log = Logger.Instance;
        using (logger.Attach(this, true))
        {
            // Parse my data file
            Parser p = new Parser(my_file_path_to_be_parsed);
            p.Parse(); // will call the same Logger instance
        }

        ...
    }

The changed code takes advantage of the C# "using" statement, which expects an IDisposable-derived object. When the "using" block goes out of scope, that object's Dispose method is called. In our case, the new Attach method returns a LoggerObserverDisposer object (rather than void as before), which remains in scope throughout the "using", even though I never assign it to a variable. Thus, LoggerObserverDisposer::Dispose is called when the "using" block loses scope, which in turn calls Logger's Detach for the Observer MyParser class.

This logic saves the programmer from having to remember to manually Detach, and possibly leave a dangling Observer that has since been destroyed.

Monday, August 21, 2017

Design Pattern example: Singleton and Observer (Part II)

Copyright © 2017, Steven E. Houchin. All rights reserved.


In my previous post on this subject, I introduced a class named Logger, which is used by my parser class to log parsing errors. It is implemented using the Singleton design pattern. The Logger class also uses the Observer design pattern where other interested objects can register with Logger to be notified when new messages are logged.

This article shows the notification logic used by Logger.  But first, a quick review of Logger:

public class Logger : object
{
    // The Singleton instance
    protected static Logger _instance;

    // List of Observer objects to be notified of
    // changes to the log
    protected List(lt)ILoggerObserver(gt) _observers;

    /// Hidden constructor
    private Logger()
    {
         _observers = new List(lt)ILoggerObserver(gt)();
    }

    ...

    /// Add an Observer object to the list of those
    /// to be notified of changes.
    public void Attach(ILoggerObserver observer)
    {
        if (null != observer)
        {
            // Add this observer to the list, but just once
            Detach(observer);
            _observers.Add(observer);
        }
    }

    /// Remove an Observer object from the list.
    public void Detach(ILoggerObserver observer)
    {
        if (null != observer)
            _observers.Remove(observer);
    }

    ...

    public void LogError(string msg)
    {
        // ... do something to log the error somewhere ...
    }
}

Objects wishing to be notified must implement the abstract interface Logger calls:

///
/// Interface to be implemented by objects who wish to
/// observe changes on the Logger object's data.
///
public interface ILoggerObserver
{
    void didAddLogMessage(string message);
}

Now, let's look at the implementation of the LogError method. It needs to notify the observers that a message has been logged, so:


    public void LogError(string msg)
    {
        if ((null == msg) || (0 == msg.Length))
           return;

        // Prepend an identifier prefix, then notify observers
        Notify(@"[Error] " + msg);
    }

    ///
    /// Notify all observers of the logged message.
    ///
    protected void Notify(string message)
    {
        foreach (ILoggerObserver observer in _observers)
        {
            // Notify the Observer of the logged message
            observer.didAddLogMessage(message);
        }
    }


Above, we have given substance to the LogError method, which in turn calls the Notify method to do the actual work of notifying the observer objects. The observer objects each implement the didAddLogMessage method, where the message reaches it's ultimate destination, such as a log file or a UI control. With the Notify method separated out like this, the class can easily be enhanced to add LogWarning and LogInfo methods, which prepend a different prefix to show the message's severity.

In a follow-up posting, I'll show an improved way to attach and detach an observer object from the Logger class.

Friday, July 21, 2017

Design Pattern example: Singleton and Observer (Part I)

Copyright © 2017, Steven E. Houchin. All rights reserved.

I've lately been developing a parser library for a certain standard file format used for data interchange between some programs.  At various points in the parsing process, my code detects errors, and I wanted a mechanism to log those errors.  The parser consists of a gaggle of classes (in C#) that encapsulate various data structures, any of which may generate errors or warnings about file format issues.  I certainly didn't want to pass a reference to a logger object as a parameter to every method in every class to accomplish the error logging.

Thinking about the functionality of logging errors, multiple instances of a logger object didn't make sense.  So, I designed a logger class based upon the Singleton design pattern, where one instance of the class is created at first use, and that same instance is retained for subsequent uses:


public class Logger : object
{
    // The Singleton instance
    protected static Logger _instance;

    /// Hidden constructor
    private Logger()
    {
    }

    /// Get the only instance of the class
    public static Logger Instance
    {
        get
        {
            // Get the only instance, creating new if necessary
            if (_instance == null)
            {
                _instance = new Logger();
            }
            return _instance;
        }
    }
        
    public static void Free()
    {
        // Free the only instance when done with the parser
        _instance = null;
    }

    public void LogError(string msg)
    {
        // ... do something to log the error somewhere ...
    }
} // end class Logger

The parser library methods simply get a reference to Logger's class instance like this:

   
    Logger log = Logger.Instance;
    log.LogError("Parse error.");

Each call to the Logger's Instance property returns the same object instance, no matter where in the code it is called.

My next design task was to decide how and where to log the error message itself.  Ultimately, I decided the Logger class shouldn't be burdened with the detail of "where" to log the error. What if App1 wants the library to log to a file, and App2 wants the log rendered to the UI?  At first, I just dumped the messages into an ArrayList, and the parent App would pull them out at its leisure at a later time.  But that was inelegant and didn't notify the App of the error in real time.

The key word I just used there is "notify."  That idea implies a callback, and that brought to mind the Observer design pattern, for which notification is a central part of the concept. For example, Object-A's state changes via some event, and it notifies Object-B of the change. In Observer, though, notifications may also be sent to Objects C and D and E.  So, Objects B through E must register as interested observers with Object-A, and unregister when no longer interested.

To implement Observer, my Logger class needed a callback interface for the observers, registration/deregistration methods, and a structure of some kind to keep track of each observer.

First, the callback interface:


///
/// Interface to be implemented by objects who wish to
/// observe changes on the Logger object's data.
///
public interface ILoggerObserver
{
    void didAddLogMessage(string message);
}

Each of the observer classes must derive from the above ILoggerObserver interface and implement the didAddLogMessage method, which allows the observer to do whatever it wishes to log the message.

Next, a List to keep track of the observer registrations:


public class Logger : object
{
    // The Singleton instance
    protected static Logger _instance;

    // List of Observer objects to be notified of
    // changes to the log
    protected List(lt)ILoggerObserver(gt) _observers;

    /// Hidden constructor
    private Logger()
    {
         _observers = new List(lt)ILoggerObserver(gt)();
    }

    ...

}

Of course, the (lt) and (gt) above are really < and > that don't render well in the HTML code snippet above.

Now, we need the registration/deregistration methods in the Logger class.  These will be made more sophisticated in a follow-on posting.

    /// Add an Observer object to the list of those
    /// to be notified of changes.
    public void Attach(ILoggerObserver observer)
    {
        if (null != observer)
        {
            // Add this observer to the list, but just once
            Detach(observer);
            _observers.Add(observer);
        }
    }

    /// Remove an Observer object from the list.
    public void Detach(ILoggerObserver observer)
    {
        if (null != observer)
            _observers.Remove(observer);
    }

So, finally, the user's parser code initializes logging by registering as an Observer, and calls the parser:

public class MyParser : ILoggerObserver
{
    ...

    public void MyParseLogic()
    {
        Logger log = Logger.Instance;
        log.Attach(this); // become a Logger observer

        Parser p = new Parser(my_file_path_to_be_parsed);
        p.Parse(); // will call the same Logger instance

        log.Detach(this); // resign as a Logger observer

        ...
    }

    /// Implement the ILoggerObserver interface
    public void didAddLogMessage(string message)
    {
        // Output the message to a TextBlock control or
        // pop up a Message Box.
        ...
    }

} // end class MyParser

With follow on postings, I'll show the Logger's notification logic, and a better way to unregister as an observer.

Wednesday, July 29, 2015

UITableViewCell and backgroundView


Copyright © 2015, Steven E. Houchin. All rights reserved.

I have some code that modifies a table view cell so that it acts like a gradient-colored button within a grouped table view. I'm developing for iOS 6.1. When the cell is to be shown (via tableView:willDisplayCell:forRowAtIndexPath:) the gradient color is rendered into a UIView using a CAGradientLayer object.  Actually, I create two of these UIViews: one for the normal button state and one for the pressed state.  Each of these two views are saved into the UITableViewCell's "backgroundView" and "selectedBackgroundView" properties, thus giving the button-like behavior.

But, while doing this, I ran into a problem: cell reuse. In my tableView:cellForRowAtIndexPath: callback, I was using dequeueReusableCellWithIdentifier: to get all of my table's cells - even the gradient-colored ones. One of the issues with cell reuse this way is that you must make sure to reset the reused cell's properties to a known default state.  Otherwise a cell can inherit properties set for a completely different cell last time through.

Well, I was doing just that - resetting properties - except for "backgroundView" and "selectedBackgroundView".  By not resetting those, the gradient colors appeared in cells where they were not intended.  So, I added this to my cell reset code:
[tableView setBackgroundView:nil];
[tableView setSelectedBackgroundView:nil];
Well, the result was a mess.  All of the grouped table view cells lost their rounded-edge borders.  It turns out that these background view properties have view objects set by default that provide the grouped table view cells their rounded look, so can't be set to null.  I suppose I could have copied the values and saved them somewhere to restore later when resetting the reused cell properties, but that seemed like the wrong thing to do.

The solution was to create a pool of separate reusable cells for the gradient cells. For these cells, which are within their own table view sections, I used the table view method dequeueReusableCellWithIdentifier:forIndexPath:, specifying a different identifier string for it than for the standard cells.  But, one glitch with this approach is that, to use this method, I also had to first register the cell identifier string for the class in my viewDidLoad method:
[[self tableView] registerClass:[UITableViewCell class]
               forCellReuseIdentifier:@"GradientCellId"];
Once I did that, then cell reuse in tableView:cellForRowAtIndexPath: worked great for both the gradient cells and the normal cells since they now draw from different reuse pools:
UITableViewCell *cell;
NSString *cellid;
if (MyTableSectionGradient == [indexPath section])
{
        cellid = @"GradientCellId";
        cell = [tableView dequeueReusableCellWithIdentifier:cellid
                                               forIndexPath:indexPath];
}
else
{
        cellid = @"NormalCellId";
        cell = [tableView dequeueReusableCellWithIdentifier:cellid];
}
if (!cell)
{
        cell = [[UITableViewCell alloc]
                                  initWithStyle:UITableViewCellStyleDefault
                                reuseIdentifier:cellid];
}


Monday, January 14, 2013

OSX AuthorizationExecuteWithPrivileges example

Copyright © 2013, Steven E. Houchin. All rights reserved.

I've read various posts online about developers' travails with OSX's AuthorizationExecuteWithPrivileges API, and misunderstanding about how it works.  So, here is some of what I've learned about it.

Apple's documentation states that it "Runs an executable tool with root privileges."  But, users soon discover that the new process does not, in fact, run as root.  In reality, the new process executes at an elevated privilege level that allows it to become the root user by calling 'setuid(0)'.  For example:

// Fork a child process
pid_t child_pid = fork();
if(child_pid == 0)
{
  // This is done by the child process
           
  // Change to the root user
  uid_t userid = getuid();
  setuid(0);  // set root permissions 

  // Do things as root ... 

  // Restore normal permissions
  setuid(userid);
  exit(0);
}

Note that there is danger in using AuthorizationExecuteWithPrivileges.  For example, your app might invoke a helper tool named 'grok' that will execute with the elevated privileges.   If a hacker figures out that 'grok' is started this way, he can replace 'grok' with his own trojan binary, which can then make itself root and thus do nasty things to your system. It isn't really hard for a hacker to determine that 'grok' is invoked this way, because the MAC's Console utility logs that AuthorizationExecuteWithPrivileges was called to execute 'grok.'   So, if you must execute 'grok' this way, your app should first validate the 'grok' binary in some way to make sure it has not been tampered with.  What I did was to open 'grok' as a binary data file and then I scan it for a known string used in the code, such as an innocuous printf format string.

The first parameter to AuthorizationExecuteWithPrivileges is an AuthorizationRef object.  This is obtained via a call to AuthorizationCreate:

AuthorizationRef authorizationRef;
OSStatus status = AuthorizationCreate(NULL,
                       kAuthorizationEmptyEnvironment,
                       kAuthorizationFlagDefaults,
                       &authorizationRef);
if (status != errAuthorizationSuccess)
{
    // Notify user of the error ...
}

The actual elevated rights you request are specified via a call to AuthorizationCopyRights, at which time the user is prompted to enter his password.  Along with requesting certain rights, you can specify a custom icon and text for the password popup.  Note however that your icon will not appear if it resides in a directory beneath any ancestor directory that lacks Everyone access.  Here's what the icon specification looks like, which is passed as the AuthorizationEnvironment parameter to AuthorizationCopyRights:

AuthorizationItem kAuthEnv[1];
const char *iconPath = "/Applications/MyApp.app/Resources/myicon.icns";
kAuthEnv[0].name = kAuthorizationEnvironmentIcon;
kAuthEnv[0].valueLength = strlen(iconPath);
kAuthEnv[0].value = (void *)iconPath; // fully qualified path
kAuthEnv[0].flags = 0;
AuthorizationEnvironment authorizationEnvironment;
authorizationEnvironment.items = kAuthEnv;
authorizationEnvironment.count = 1;

Next, in order to use AuthorizationExecuteWithPrivileges, you must request the "system.privilege.admin" right.  You set this up as follows:

const char *grokPath = "/Utilities/grokUtil/grok";
AuthorizationItem executeRight = {
                        kAuthorizationRightExecute,
                        strlen(grokPath)
                        (void *)grokPath,
                        0};
AuthorizationRights rightsSet = {1, &executeRight};

Note that kAuthorizationRightExecute is defined as "system.privilege.admin" in the Security framework's AuthorizationTags.h.  This is then used in AuthorizationCopyRights to actually acquire the rights for the AuthorizationRef object:

AuthorizationFlags flags =
                  kAuthorizationFlagDefaults |
                  kAuthorizationFlagInteractionAllowed |
                  kAuthorizationFlagPreAuthorize |
                  kAuthorizationFlagExtendRights;

// Call AuthorizationCopyRights to determine
// or extend the allowable rights
OSStatus status = AuthorizationCopyRights(
                                authorizationRef,
                                &rightsSet,
                                &authorizationEnvironment,
                                flags,
                                NULL);
if (errAuthorizationCanceled == status)
{
    // User canceled authentication  ...
}
else if (status != errAuthorizationSuccess)
{
    // Notify the user of the error ...
}

All that's left at this point is to execute the privileged helper tool:

FILE *fpStdout = NULL;
status = AuthorizationExecuteWithPrivileges(
                        authorizationRef,
                        (const char *)grokPath,
                        kAuthorizationFlagDefaults,
                        argv,  // normal argv array of program args
                        &fpStdout);
bool success = (status == errAuthorizationSuccess);
pid_t newProcId;
if (success)
{
   // Get the new process id
   newProcId = fcntl(fileno(fpStdout), F_GETOWN, 0);
   fclose(fpStdout);
}
else
{
   // Notify user of the error ...
}

AuthorizationExecuteWithPrivileges returns as soon as the new process has started.  It does not execute it as a child of the current process, so a waitpid on the resulting process id gives an error.