/// <summary> /// Opens the appropriate Media Viewer window for the requested LaunchMode. /// </summary> /// <param name="LaunchMode"></param> /// <param name="hWnd"></param> private void OpenAppropriateWindow(LaunchModality LaunchMode, IntPtr hWnd) { Log("OpenAppropriateWindow() entered."); // Based on Launch Mode, show the correct window in the correct place if (LaunchMode == LaunchModality.DT_Configure) { Log(" OpenAppropriateWindow(): LaunchMode = DT_Configure"); ShowSettings(); } else if (LaunchMode == LaunchModality.CP_Configure) { Log(" OpenAppropriateWindow(): LaunchMode = CP_Configure"); ShowSettings(hWnd); } else if (LaunchMode == LaunchModality.ScreenSaver) { Log(" OnStartup(): LaunchMode = ScreenSaver"); ShowScreenSaver(false); } else if (LaunchMode == LaunchModality.ScreenSaverWindowed) { Log(" OpenAppropriateWindow(): LaunchMode = ScreenSaverWindowed"); ShowScreenSaver(true); } else if (LaunchMode == LaunchModality.CP_MiniPreview) { Log(" OpenAppropriateWindow(): LaunchMode = CP_MiniPreview"); ShowPreview(hWnd); } else if (LaunchMode == LaunchModality.Undecided) { Log(" ** OpenAppropriateWindow() Error: LaunchMode == LaunchModality.Undecided"); #if DEBUG // if we are in DEBUG and there's a debugger attached, offer to break into it if (System.Diagnostics.Debugger.IsAttached) { Log(" ** OpenAppropriateWindow() Breaking into debugger..."); MessageBoxResult mbr = MessageBox.Show("Apparently we are still in LaunchMode.Undecided. Cancel to break into debugger, or OK to launch in Full Screen mode." + Environment.NewLine + Environment.NewLine + "CommandLine: " + Environment.CommandLine, this.ProductName, MessageBoxButton.OKCancel, MessageBoxImage.Exclamation); if (mbr == MessageBoxResult.Cancel) { System.Diagnostics.Debugger.Break(); } } #endif // In release version, we'll just quietly fail here, and launch in desktop Configure mode Log(" ** OpenAppropriateWindow(): we fell through to Mode.Undecided, calling ShowSettings()."); ShowSettings(); } Log("OpenAppropriateWindow() exiting."); }
/// <summary> /// Parses command line options, sets modes, and calls the Launch Code /// </summary> /// <param name="mainArgs"></param> static void ProcessCommandLineAndExecute(string[] mainArgs) { Logging.LogIf(fDebugTrace, " ProcessCommandLineAndExecute(): calling ProcessCommandLineAndExecute()..."); // The only args that this exe cares about are: // 1. no mode args passed = M_NO_MODE (open screensaver in last remembered non-ScreenSaverStyle window, with no Slideshow) // 2. /scr, which tells us that we were launched from the .scr stub, // and therefore need to respect arguments with window handles // 3. /dt_configure (open settings dialog on desktop) // 4. /c (same as dt_configure) // 5. /cp_configure -windowHandle (open settings owned by control panel) // 6. /cp_minipreview -windowHandle (put minipreview form in control panel) // 7. /screensaver (run the default screen saver with slideshow) // 8. /s (same as /screensaver) // 9. /popdbgwin (pop up the debugoutputwindow on a timer after launch) // 10. any 'unofficial' args we process with SetDebugOutputAndHostOptions() and/or HandleUnofficialArgs() // By the time we get to this method, the command line will have been scanned once by // SetDebugOutputAndHostOptions(), and certain LaunchManager.Modes will have been set: // 1. fRunFromScreenSaverStub // 2. VSHOSTED // 3. fPopUp // 4. fMaintainBuffer IntPtr hWnd = IntPtr.Zero; string launchString = M_SCREENSAVER; // First, handle only the very rigorous "we were launched from the scr stub" case. // Note "/scr" was already detected, and noted in fRunFromScreenSaverStub int lastProcessedIndex = -1; if (fRunFromScreenSaverStub) // set for us by SetDebugOutputAndHostOptions() { // Logic: // A. If /scr exists, it must be first // B. If /scr, only one /scr arg allowed // C. If /scr, one /scr arg required // D. If /scr, validate that windowHandles parse to IntPtr // E. If /scr, non-scr args not allowed except /popdbgwin or /startbuffer // first argument must be /scr if ((mainArgs.Length > 0) && (mainArgs[0].ToLowerInvariant() != @"/scr")) { Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): /scr can only be the first argument."); throw new ArgumentException(@"CommandLine: /scr can only be the first argument." + Environment.NewLine + Environment.CommandLine); } lastProcessedIndex = 0; // second arg must be one of four valid /scr-related arguments if ((mainArgs.Length > 1) && !scrArgs.Contains(mainArgs[1].ToLowerInvariant())) { Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): /scr can only be followed by a valid /scr-related argument."); throw new ArgumentException(@"CommandLine: /scr can only be followed by a valid /scr-related argument." + Environment.NewLine + Environment.CommandLine); } lastProcessedIndex = 1; // if second arg starts with cp_ it must be followed with a valid window handle if (mainArgs[1].ToLowerInvariant() == M_CP_CONFIGURE || mainArgs[1].ToLowerInvariant() == M_CP_MINIPREVIEW) { if ((mainArgs.Length > 2) && mainArgs[2].ToLowerInvariant().StartsWith("-")) { string subArg = mainArgs[2].ToLowerInvariant(); string longCandidate = subArg.Substring(1); if (!String.IsNullOrEmpty(longCandidate)) { long val; bool worked = long.TryParse(longCandidate, out val); if (worked) { hWnd = new IntPtr(val); } else // bad parse { Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): invalid window handle passed: " + longCandidate); throw new ArgumentException(@"CommandLine: invalid window handle passed: " + longCandidate + Environment.NewLine + Environment.CommandLine); } } else // null or empty { Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): null or empty window handle passed."); throw new ArgumentException(@"CommandLine: null or empty window handle passed." + Environment.NewLine + Environment.CommandLine); } } else // missing required sub argument { Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): /cp_ argument missing required subargument."); throw new ArgumentException(@"CommandLine: /cp_ argument missing required subargument." + Environment.NewLine + Environment.CommandLine); } lastProcessedIndex = 2; } // at this point, lastProcessedIndex is either 1 or 2. The only valid arguments past here are // either /dgbwin or /startbuffer, which will already have been detected, but not validated // in position. They are only allowed in index 2 or 3. // validate StartBuffer bool DidProcess = false; if (fMaintainBuffer) // this was detected earlier { if ((mainArgs[lastProcessedIndex + 1].ToLowerInvariant() != POPDBGWIN) && (mainArgs[lastProcessedIndex + 1].ToLowerInvariant() != STARTBUFFER)) { string invalid = POPDBGWIN + " or " + STARTBUFFER; Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): " + invalid + " detected but not at valid index."); throw new ArgumentException(@"CommandLine:" + invalid + " detected but not at valid index." + Environment.NewLine + Environment.CommandLine); } DidProcess = true; ; } // validate POPDBGWIN appears at proper point in args if (fPopUpDebugOutputWindowOnTimer) // this was detected earlier { if (mainArgs[lastProcessedIndex + 1].ToLowerInvariant() != POPDBGWIN) { Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): " + POPDBGWIN + " detected but not at valid index."); throw new ArgumentException(@"CommandLine:" + POPDBGWIN + " detected but not at valid index." + Environment.NewLine + Environment.CommandLine); } DidProcess = true; } if (DidProcess) lastProcessedIndex++; // starting at lastProcessedIndex, there should be NO arguments if ((mainArgs.Length - 1) > lastProcessedIndex) { Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): " + POPDBGWIN + " detected but not at valid index."); throw new ArgumentException(@"CommandLine: too many arguments past /scr." + Environment.NewLine + Environment.CommandLine); } // by this point, a valid mode is in mainArgs[1] and hWnd is either IntPtr.Zero or a numerically validated hWnd. launchString = mainArgs[1].ToLowerInvariant(); } else // we were not launched from .scr stub. { // So valid args are: // - no args // - one of the four scrArgs // - and possibly one of two subArgs // - one of the old args, which we'll map to a scrArg // - /popdbgwin, which we will already have detected // Apply some rules // 1. acceptable: no scrArg, no oldArg // 2. if any scrArg, only one allowed // 2. if any scrArg, no oldArgs allowed // 3. if no scrArg, only one oldArg allowed // 4. if scrArg or oldArg exists, it must be first // 5. if scrArg exists, any subArg must be second launchString = M_NO_MODE; int countOfscrArgsDetected = 0; int countOfoldArgsDetected = 0; if (mainArgs.Length > 0) { foreach (string arg in mainArgs) { string testMe = arg.ToLowerInvariant().Trim(); if (scrArgs.Contains(testMe)) countOfscrArgsDetected++; if (oldArgs.Contains(testMe)) countOfoldArgsDetected++; if (testMe == M_DT_CONFIGURE) launchString = M_DT_CONFIGURE; if (testMe == M_SCREENSAVER) launchString = M_SCREENSAVER; if (testMe == OLDCONFIGURE) launchString = M_DT_CONFIGURE; if (testMe == OLDSCREENSAVER) launchString = M_SCREENSAVER; if (testMe == M_CP_CONFIGURE) launchString = M_CP_CONFIGURE; if (testMe == M_CP_MINIPREVIEW) launchString = M_CP_MINIPREVIEW; } // no multiple modes or mixing old and new if (countOfoldArgsDetected > 1 || countOfscrArgsDetected > 1 || (countOfoldArgsDetected + countOfscrArgsDetected > 1)) { Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): only one scrArg allowed, or only one oldArg allowed, or scrArg and oldArg cannot be combined."); throw new ArgumentException("CommandLine: only one scrArg allowed, or only one oldArg allowed, or scrArg and oldArg cannot be combined." + Environment.NewLine + Environment.CommandLine); } // mode must be first argument; so if we have a mode, compare it to first argument if (launchString != M_NO_MODE) { if (mainArgs[0].ToLowerInvariant().Trim() != launchString) { // this may be because of old vs new args. check that first if ((mainArgs[0].ToLowerInvariant().Trim() == OLDCONFIGURE && launchString == M_DT_CONFIGURE) || (mainArgs[0].ToLowerInvariant().Trim() == OLDSCREENSAVER && launchString == M_SCREENSAVER) ) { // do nothing, that's expected } else { // mode argument was out of order. Reject. Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): any mode argument must be the first argument."); throw new ArgumentException("CommandLine: any mode argument must be the first argument." + Environment.NewLine + Environment.CommandLine); } } } // require and validate window handles if ((launchString == M_CP_CONFIGURE) || (launchString == M_CP_MINIPREVIEW)) { if ((mainArgs.Length > 2) && mainArgs[2].ToLowerInvariant().StartsWith("-")) { string subArg = mainArgs[1].ToLowerInvariant().Trim(); string longCandidate = subArg.Substring(1); if (!String.IsNullOrEmpty(longCandidate)) { long val; bool worked = long.TryParse(longCandidate, out val); if (worked) { hWnd = new IntPtr(val); } else // bad parse { Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): invalid window handle passed: " + longCandidate); throw new ArgumentException(@"CommandLine: invalid window handle passed: " + longCandidate + Environment.NewLine + Environment.CommandLine); } } else // null or empty { Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): null or empty window handle passed."); throw new ArgumentException(@"CommandLine: null or empty window handle passed." + Environment.NewLine + Environment.CommandLine); } } else // missing required sub argument { Logging.LogIf(fDebugTrace, @" * ProcessCommandLineAndExecute(): /cp_ argument missing required subargument."); throw new ArgumentException(@"CommandLine: /cp_ argument missing required subargument." + Environment.NewLine + Environment.CommandLine); } } } } // Now map launchString to LaunchMode enum LaunchMode = LaunchModality.Undecided; if (launchString == M_NO_MODE) LaunchMode = LaunchModality.ScreenSaverWindowed; if (launchString == M_CP_CONFIGURE) LaunchMode = LaunchModality.CP_Configure; if (launchString == M_CP_MINIPREVIEW) LaunchMode = LaunchModality.CP_MiniPreview; if (launchString == M_DT_CONFIGURE) LaunchMode = LaunchModality.DT_Configure; if (launchString == M_SCREENSAVER) LaunchMode = LaunchModality.ScreenSaver; // Handle any 'unofficial' arguments HandleUnofficialArguments(mainArgs); // Now launch us LaunchWindow(LaunchMode, hWnd); }
private void GetLaunchMode(StartupEventArgs SEArgs, out LaunchModality LaunchMode, out IntPtr hWnd) { Log("GetLaunchMode(): entered."); string[] mainArgs = SEArgs.Args; bool retVal = true; hWnd = IntPtr.Zero; // The only mainArgs that this exe cares about are: // 1. no mode mainArgs passed = M_NO_MODE (open screensaver in last remembered non-ScreenSaverStyle window, with no Slideshow) // 2. /scr, which tells us that we were launched from the .scr stub, // and therefore need to respect arguments with window handles // 3. /dt_configure (open settings dialog on desktop) // 4. /c (same as dt_configure) // 5. /cp_configure -windowHandle (open settings owned by control panel) // 6. /cp_minipreview -windowHandle (put minipreview form in control panel) // 7. /screensaver (run the default screen saver with slideshow) // 8. /s (same as /screensaver) // 9. /popdbgwin (pop up the debugoutputwindow on a timer after launch) // 10. any 'unofficial' mainArgs we process with SetDebugOutputAndHostOptions() and/or HandleUnofficialArgs() // By the time we get to this method, the command line will have been scanned once by // SetDebugOutputAndHostOptions(), and certain LaunchManager.Modes will have been set: // 1. fRunFromScreenSaverStub // 2. VSHOSTED string launchString = M_SCREENSAVER; // TODO: Joe, translate exceptions into MsgBox errors. // First, handle only the very rigorous "we were launched from the scr stub" case. // Note "/scr" was already detected, and noted in fRunFromScreenSaverStub if (fLaunchedFromStub) // set for us by SetDebugOutputAndHostOptions() { // Logic: // A. If /scr exists, it must be first // B. If /scr, only one /scr arg allowed // C. If /scr, one /scr arg required // D. If /scr, validate that windowHandles parse to IntPtr // E. If /scr, non-scr mainArgs not allowed except /popdbgwin or /startbuffer // first argument must be /scr if ((mainArgs.Length > 0) && (mainArgs[0].ToLowerInvariant() != @"/scr")) { Log(@" * GetLaunchMode(): /scr can only appear as the first argument."); throw new ArgumentException(@"CommandLine: /scr can only appear as the first argument." + Environment.NewLine + Environment.CommandLine); } // second arg must be one of four valid /scr-related arguments if ((mainArgs.Length > 1) && !scrArgs.Contains(mainArgs[1].ToLowerInvariant())) { Log(@" * GetLaunchMode(): /scr must be followed by a valid /scr-related argument."); throw new ArgumentException(@"CommandLine: /scr must be followed by a valid /scr-related argument." + Environment.NewLine + Environment.CommandLine); } // if second arg starts with cp_ it must be followed with a valid window handle if (mainArgs[1].ToLowerInvariant() == M_CP_CONFIGURE || mainArgs[1].ToLowerInvariant() == M_CP_MINIPREVIEW) { if ((mainArgs.Length > 2) && mainArgs[2].ToLowerInvariant().StartsWith("-")) { string subArg = mainArgs[2].ToLowerInvariant(); string longCandidate = subArg.Substring(1); if (!String.IsNullOrEmpty(longCandidate)) { long val; bool worked = long.TryParse(longCandidate, out val); if (worked) { hWnd = new IntPtr(val); } else // bad parse { Log(@" * GetLaunchMode(): invalid window handle passed: " + longCandidate); throw new ArgumentException(@"CommandLine: invalid window handle passed: " + longCandidate + Environment.NewLine + Environment.CommandLine); } } else // null or empty { Log(@" * GetLaunchMode(): null or empty window handle passed."); throw new ArgumentException(@"CommandLine: null or empty window handle passed." + Environment.NewLine + Environment.CommandLine); } } else // missing required sub argument { Log(@" * GetLaunchMode(): /cp_ argument missing required subargument."); throw new ArgumentException(@"CommandLine: /cp_ argument missing required subargument." + Environment.NewLine + Environment.CommandLine); } } // by this point, a valid mode is in mainArgs[1] and hWnd is either IntPtr.Zero or a numerically validated hWnd. launchString = mainArgs[1].ToLowerInvariant(); } else { launchString = M_NO_MODE; } // If not launched from stub, all commandline args are ignored. // Now map launchString to LaunchMode enum LaunchMode = LaunchModality.Undecided; if (launchString == M_NO_MODE) LaunchMode = LaunchModality.ScreenSaverWindowed; if (launchString == M_CP_CONFIGURE) LaunchMode = LaunchModality.CP_Configure; if (launchString == M_CP_MINIPREVIEW) LaunchMode = LaunchModality.CP_MiniPreview; if (launchString == M_DT_CONFIGURE) LaunchMode = LaunchModality.DT_Configure; if (launchString == M_SCREENSAVER) LaunchMode = LaunchModality.ScreenSaver; // Handle any 'unofficial' arguments here // HandleUnofficialArguments(mainArgs); Log("GetLaunchMode(): exiting, returning:" + retVal); }
/// <summary> /// Opens the necessary window, based on conditions and arguments. /// </summary> /// <param name="LaunchMode"></param> /// <param name="hWnd"></param> static void LaunchWindow(LaunchModality LaunchMode, IntPtr hWnd) { Logging.LogLineIf(fDebugTrace, "LaunchWindow(): entered."); // Store away the actual command line for debugging purposes Logging.LogLineIf(fDebugTrace, " LaunchWindow(): Mode = " + LaunchMode.ToString()); #if DEBUG // Uncomment the following lines and in DEBUG builds not attached to a debugger (ie, in Control Panel) // we'll put up this dialog every time we launch, showing command line and launch mode. //if (Logging.CannotLog()) // there's no debugger, so we'll put up a dialog //{ // MessageBox.Show("CommandLine: " + cmdLine + Environment.NewLine + Environment.NewLine + // "Launch Mode = " + LaunchMode.ToString(), Application.ProductName, // MessageBoxButtons.OK, MessageBoxIcon.Information); //} #endif // Based on Launch Mode, show the correct window in the correct place if (LaunchMode == LaunchModality.DT_Configure) { ShowSettings(); } else if (LaunchMode == LaunchModality.CP_Configure) { ShowSettings(hWnd); } else if (LaunchMode == LaunchModality.ScreenSaver) { fOpenInScreenSaverMode = true; ShowScreenSaver(); } else if (LaunchMode == LaunchModality.ScreenSaverWindowed) { fOpenInScreenSaverMode = false; ShowScreenSaver(); } else if (LaunchMode == LaunchModality.CP_MiniPreview) { ShowMiniPreview(hWnd); } else if (LaunchMode == LaunchModality.NOLAUNCH) { MessageBox.Show("Command: " + Environment.CommandLine + Environment.NewLine + Environment.NewLine + "Sorry, an error prevented this screen saver from running.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); // since Application.Run was never called, exe will now terminate... // TODO: JOE: verify fallthough behavior } else if (LaunchMode == LaunchModality.Undecided) { Logging.LogLineIf(fDebugOutput, "Error: Apparently we are still in LaunchMode == Undecided."); #if DEBUG if (System.Diagnostics.Debugger.IsAttached) { MessageBox.Show("Error: Apparently we are still in LaunchMode == Undecided. Gonna break into debugger now.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); System.Diagnostics.Debugger.Break(); } #endif // In release, we'll just quietly fail here, and launch in Configure mode ShowSettings(); Logging.LogLineIf(fDebugOutput, " ** LaunchWindow(): we fell through to Mode.Undecided, calling Application.Run()."); Application.Run(); Logging.LogLineIf(fDebugTrace, "LaunchWindow(): exiting for realsies."); } }