If in MS Windows, process WM_QUERYENDSESSION and WM_ENDSESSION. See http://msdn.microsoft.com/en-us/library/aa376890(VS.85).aspx for more details. It seems that a regular application cannot know whether the session end is due to a log off or a shutdown, though.
Windows Services, on the other hand, can distinguish between the two.