Thursday, August 25, 2011

SilentSkype v0.2

Here's a revised listing for SilentSkype.exe. This one fixes the main bug from the previous code which was that after it hid the Skype window, you couldn't actually restore it again. A bit of a significant problem there. It turned 'silent' Skype into 'coma Skype'. Thanks go to Philipp who helped with that part. I'm still new to the Windows API, but getting there!


using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;

namespace SilentSkype
{
class Program
{
#region Constants

///
/// Tells the window that the other parameter is a system command.
///

private const uint WM_SYSCOMMAND = 0x0112;

///
/// Closes the window.
///

private const uint SC_CLOSE = 0xF060;

#endregion

#region Private Variables

///
/// The executable path to Skype. (The original shortcut had "/nosplash /minimized" on the end.)
///

private static string _exePath = null;

///
/// The caption of the secondary window. This defaults to "Skype Home"
/// but can be specified by the user via the command line.
///

private static string _captionText = "Skype Home";

///
/// The handle to the main Skype window.
///

private static IntPtr _mainWindowHandle = IntPtr.Zero;

///
/// The handle to the infamous "Skype Home" window.
///

private static IntPtr _skypeHomeHandle = IntPtr.Zero;

///
/// The name of the Skype process, to allow checking for it already running.
/// If left as null, the program will not check for an existing instance
/// and will always attempt to launch a new process.
///

private static string _processName = null;

///
/// The maximum length of time to wait for the Skype Home window to appear before giving up.
///

private static TimeSpan _maxWaitTime = new TimeSpan(0, 0, 30);

///
/// The time the process started, so we can ensure we don't spend forever waiting.
/// This defaults to MinValue so that when we subtract it from DateTime.Now,
/// if it hasn't been initiated it'll fail the first time.
///

private static DateTime _startTime = DateTime.MinValue;

///
/// Details of the Skype process we are starting.
///

private static Process _skypeProcess = null;

///
/// The number of ms to wait between trying things.
///

private static int _pauseTime = 500;

#endregion

///
/// The main entrypoint into the application.
/// Everything is done with static variables and methods rather than bothering with
/// creating an instance of something.
///

/// static void Main(string[] args)
{
try
{
if (!ProcessArgs(args))
return; // Something was wrong with the args, so we quit here.

try
{
_startTime = DateTime.Now; // Start timing the overall process, so we don't run too long.

// Start the Skype process.
Console.WriteLine("Checking Skype is running.");
_skypeProcess = StartSkype();

// Ensure the window handles are zero to begin with.
_mainWindowHandle = IntPtr.Zero;
_skypeHomeHandle = IntPtr.Zero;

// Wait for the "Skype Home" window first of all, to avoid getting the handle on the wrong main window.
// The login window appears first of all, and if we're not careful, we can get the handle on that instead
// of the compact view.
while (_skypeHomeHandle == IntPtr.Zero && CanKeepGoing())
{
Console.WriteLine("Waiting for \"Skype Home\" window to be created...");
// Wait a short time.
Thread.Sleep(_pauseTime);
_skypeHomeHandle = FindWindowByCaption(IntPtr.Zero, _captionText);
}

// Update the handle to the main Skype window.
while (_mainWindowHandle == IntPtr.Zero && CanKeepGoing())
{
Console.WriteLine("Waiting for main window to be created...");
// Wait a short time.
Thread.Sleep(_pauseTime);
_skypeProcess.Refresh();
_mainWindowHandle = _skypeProcess.MainWindowHandle;
}

Console.WriteLine("Done getting handles.");

if (_mainWindowHandle != IntPtr.Zero && _skypeHomeHandle != IntPtr.Zero && CanKeepGoing())
{
// Wait for the windows to become visible.
bool mainWindowVisible = false;
bool skypeHomeVisible = false;

do
{
Console.WriteLine("Waiting for windows to become visible.");
// Wait a short time.
Thread.Sleep(_pauseTime);

if (!mainWindowVisible)
mainWindowVisible = IsWindowVisible(_mainWindowHandle);

if (!skypeHomeVisible)
skypeHomeVisible = IsWindowVisible(_skypeHomeHandle);

} while ((!mainWindowVisible || !skypeHomeVisible) && CanKeepGoing());

Console.WriteLine("Closing Skype windows...");

// Close the "Skype Home" window.
if (_skypeHomeHandle != IntPtr.Zero && skypeHomeVisible)
SendMessage(_skypeHomeHandle, WM_SYSCOMMAND, (IntPtr)SC_CLOSE, IntPtr.Zero);

// Close the main window.
if (_mainWindowHandle != IntPtr.Zero && mainWindowVisible)
SendMessage(_mainWindowHandle, WM_SYSCOMMAND, (IntPtr)SC_CLOSE, IntPtr.Zero);

Console.WriteLine("All done.");
}
}
finally
{
// Dispose the process here.
if (_skypeProcess != null)
{
_skypeProcess.Dispose();
_skypeProcess = null;
}
}
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("Unhandled Exception: " + ex.Message);
Console.WriteLine(ex.StackTrace);
}
}

///
/// This processes the command line arguments and populates variables where relevant.
/// If any problems are detected, the user is notified and validation fails.
///

/// The command line arguments/// True if validation was successful, false otherwise
private static bool ProcessArgs(string[] args)
{
if (args.Length < 1) { Console.WriteLine("Usage: SilentSkype.exe ExePath [CaptionText] [ProcessName] [MaxWaitTime]"); Console.WriteLine(); Console.WriteLine("ExePath: The path to the executable, including the filename."); Console.WriteLine("CaptionText: The caption of the window to be located."); Console.WriteLine("ProcessName: The name of the process, to check if it's already running."); Console.WriteLine("MaxWaitTime: The maximum length of time (in seconds) that the program will wait for the UI to appear."); return false; } _exePath = args[0]; if (args.Length > 1)
_captionText = args[1];

if (args.Length > 2)
_processName = args[2];

if (args.Length > 3)
{
int maxWaitTime = 0;

if (int.TryParse(args[3], out maxWaitTime))
{
_maxWaitTime = new TimeSpan(0, 0, maxWaitTime);
}
else
{
Console.WriteLine("Could not parse MaxWaitTime as an integer: {0}", args[3]);
return false;
}
}

if (!File.Exists(_exePath))
{
// Return if the executable does not exist.
Console.WriteLine("File not found: {0}", _exePath);
return false;
}

return true;
}

///
/// Checks to see if Skype is already running and start if it's not.
///

/// Details of the Skype process
private static Process StartSkype()
{
Process skypeProcess = null;

if (!String.IsNullOrEmpty(_processName))
{
// Look for a matching process.
Console.WriteLine("Looking for matching process...");
var matchingProcesses = Process.GetProcessesByName(_processName).Where(mp => !mp.HasExited);

if (matchingProcesses.Count() > 0)
{
Console.WriteLine("Skype is already running.");
// Match found - Skype must be running already.
skypeProcess = matchingProcesses.First(); // Take the first instance.

// Dispose of any processes we don't need to keep.
foreach (var item in matchingProcesses)
{
if (item != skypeProcess)
item.Dispose();
}

matchingProcesses = null;
}
else
{
Console.WriteLine("Skype is not running.");
}
}

if (skypeProcess != null)
return skypeProcess;

Console.Write("Launching Skype...");
skypeProcess = Process.Start(_exePath);
Console.WriteLine("done.");

return skypeProcess;
}

///
/// True if we can keep waiting for handles to be created,
/// windows to be visible etc. We should stop if:
/// a) The process has exited. (in case we pick up a closing process by accident)
/// b) We have run out of time
///

/// True if we can keep going, false otherwise
private static bool CanKeepGoing()
{
if (_skypeProcess.HasExited)
return false; // The process has exited for some reason or other.
else if (DateTime.Now - _startTime >= _maxWaitTime)
return false; // Ran out of time
else
return true; // No other reason to stop.
}

#region Interop

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindowVisible(IntPtr hWnd);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

#endregion

}
}

6 comments:

  1. Top-line pay tables typically aren't obtainable in multiplier video games, however even lower-paying games are helped by Super Stacks. If you play 7-5 Bonus Poker, it's often a 98.01-percent return game, however that rises to 98.eighty two % with Super Stacks. Perhaps the best advantage of video poker is that you could see precisely how a lot have the ability to|you probably can} count on to win—essentially, your return on funding —while enjoying in}. This makes video poker a beatable game and the best value for your greenback. Winning at poker is about being constant and https://casino.edu.kg/betmove.html this doesn’t actually apply with video poker.

    ReplyDelete
  2. Yeom mentioned online gamblers can be bodily on island or not, however off-island gamblers can only place bets from international locations the place online playing is authorized. Another thing to look out for in terms of|when it comes to|by method of} funds is the place your cash is saved when you play. Some playing authorities, all of the best ones 리턴벳 really, regulate what the casino can do along with your cash whereas they're holding it.

    ReplyDelete
  3. If you could have} a 1xbet alternative between physical roulette and online one, then you must to} choose the net version. Almost all casinos have both variations obtainable for gamers. Some prefer to play the American version and some prefer to play the European version. However, skilled gamers always choose the European version because of|as a result of} it has better chances of profitable, together with better payouts. It is a game the place a ball spins on a wheel a few of} instances, then it settles down on a spot that has a quantity. If the ball stops on the player’s spot, then the home pays the participant 35 instances the bet or 38 instances the bet.

    ReplyDelete
  4. You can often use an unique bonus code when accessing a PA on line casino bonus. Simply enter the promo code in the box offered on the registration type. However, for most retention bonuses aimed toward regular customers, there’s no must enter a code. To declare a reload bonus or join a leaderboard challenge you simply must choose in to the provide on 토토사이트 your account web page.

    ReplyDelete
  5. The Center Court on-line slot allows you to take house a big money trophy. The developers took the world-famous tennis championship Wimbledon as the idea for the development of the slot. The Golden Games on-line slot has 5 reels, 25 paylines, heaps of|and a lot of} bonus features. Everyone can methods to|learn to} play this slot outcome of|as a result of} it's pretty simple. Visit GamingLyfe.com for all your latest gaming information, reviews, Esports highlights, 1xbet reside streaming information, Cosplay, and GLYFE Merchandise. The worst bet by the numbers was the sooner noted penny slots with 9.85 % maintain and the popular quarter slots, from which casinos saved 8.04 % from the three,568 items statewide.

    ReplyDelete
  6. It looks like people are buying ad-space for pages with viruses in them web site .

    ReplyDelete