Wednesday, August 24, 2011

Introducing Silent Skype

I've been working on my own alternative to Kill Skype Home since I don't really like downloading mystery .exe files. Mine is called SilentSkype.exe and can be run from the command line as follows:

SilentSkype.exe [ExePath] [Window Caption] [Process Name] [Max Wait Time]

e.g.

SilentSkype.exe Skype.exe "Skype Home" Skype 10

The path to the .exe can be absolute or relative, depending on where you put SilentSkype.exe to begin with.

The Window Caption is used to locate the Skype Home window. If for any reason the caption changes in a future version, change the value passed here. The program will always attempt to close the main window. (I'm assuming compact mode here, it's not perfect yet!)

The Process Name can be used to help locate an instance already running. If you supply this parameter, SilentSkype will attempt to use the existing instance of Skype rather than spawning a new one.

Finally, Max Wait Time is the maximum length of time (in seconds) that the program will wait for the Skype Home window to appear.

Here's the source code for anyone who wants to compile it. It's written in C#.NET. Note that this is the very first release, so it's probably full of bugs!


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

namespace SilentSkype
{
class Program
{
///
/// Hides the window and activates another window.
///

private const uint SW_HIDE = 0;

#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 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);

#endregion

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

Process skypeProcess = null;
IntPtr mainWindowHandle = IntPtr.Zero;
IntPtr skypeHomeHandle = IntPtr.Zero;

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

Console.WriteLine("Looking for window handles.");

// Get a handle to the main Skype window.
mainWindowHandle = skypeProcess.MainWindowHandle;

// Get a handle to the "Skype Home" window.
if (!String.IsNullOrEmpty(_captionText))
skypeHomeHandle = FindWindowByCaption(IntPtr.Zero, _captionText);

Console.WriteLine("Hiding windows...");

// Hide the "Skype Home" window.
if (skypeHomeHandle != IntPtr.Zero)
ShowWindow(skypeHomeHandle, SW_HIDE);

// Hide the main window.
if (mainWindowHandle != IntPtr.Zero)
ShowWindow(mainWindowHandle, SW_HIDE);

Console.WriteLine("Windows hidden!");
}
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);

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

// Dispose of any processes we don't need to keep.
for (int i = 1; i < matchingProcesses.Length; i++)
{
matchingProcesses[i].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.");

// Wait for the main window to become visible.
DateTime start = DateTime.Now; // Start waiting for the window to open.

while (String.IsNullOrEmpty(skypeProcess.MainWindowTitle) && DateTime.Now - start < _maxWaitTime)
{
Console.WriteLine("Waiting for UI to load...");
Thread.Sleep(500);
// Refresh the process to see if the main window has now been loaded.
skypeProcess.Refresh();
}

Console.WriteLine("UI detected.");
return skypeProcess;
}

#region Interop

///
/// Find window by Caption only. Note you must pass IntPtr.Zero as the first parameter.
///

/// This must be IntPtr.Zero
/// The caption of the window to be found
/// A handle for the window, or IntPtr.Zero if no match was found.
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
public static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

///
/// Changes the state of the window. Can be used to show, hide, close etc.
///

/// A handle for the window in question
/// The command to be sent to the window
/// True if the operation was a success, false otherwise.
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hwnd, uint cmdShow);

#endregion

}
}


18 comments:

  1. Hi, since you made yourself the trouble to post some code, I would like to contribute.

    However, is there a possibility to attach a file instead of code only.

    The code got a bit bigger.

    The key for closing the windows is to send a Windows Message like this. It works fine.

    NativeMethods.PostMessage(skypeHomeHandle, (uint)NativeMethods.WMCode.WM_SYSCOMMAND, 0xF060, 0);

    NativeMethods.WMCode.WM_SYSCOMMAND is 0x0112
    0xF060 means SC_CLOSE


    I have also a possibility to inject code directly into skype, so that skype can be modified with an extra thread checking for the Home window. Its a nice snipped from the microsoft tool Snoop.

    However, code gets too long to post in your blog, unless you tell me to do so.

    cheers

    Philipp

    ReplyDelete
  2. Hi Philipp,

    Thanks so much for your feedback. I've done very little with the Windows API and the whole idea of interacting with other processes is still a bit of a mystery to me, although exciting considering we can do handy hacks like this. I suppose asking a window to close is nicer than setting it to hidden. Although the both result in a hidden window, I suppose the better way is if the app that owns it still knows what's going on!

    Your code sounds interesting. I'd like to see it. I don't know about how attaching files could work, though. Maybe if you could upload it somewhere else you could link to it?

    I'd like to get some hosting of my own sorted out so I could upload the source code and even some compiled code.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Hi Philipp,

    For some reason the download doesn't work for me. Perhaps the link expired?

    I'd like to learn how to snoop the resources within skype.exe so that we can find where the text "Skype Home" comes from. Then we could look it up at runtime so that it would work for all languages!

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Hi Ken

    I took the liberty of publishing my code (which is based on yours) here:

    http://sourceforge.net/projects/skypesedator/

    Please feel free to join.

    P.S. Sorry to make your blog looking like a mess.

    ReplyDelete
  9. Numerous people as of now have decreased, or crossed out their property line phone lines for reasons which incorporate comfort, investment funds, and includes; and have changed to web or remote telephone numbers.https://800support.net/sign-up/gmail-sign-up-gmail-register/

    ReplyDelete
  10. I am extremely delighted in for this web journal. Its a useful subject. It help me all that much to take care of a few issues. Its chance are so awesome and working style so rapid. Skype Offline Installer

    ReplyDelete
  11. Online Casino Bonus with bet365 Link 2021 ᐉ Enjoy Online
    Check the best online dafabet link casinos for you ✓ Play bet365 casino games with bet365 Link ✓ Huge selection of casino games 10cric ✓ Play for free or for real money!

    ReplyDelete
  12. Casino Restaurants Near Casino & Resort, Reno - Mapyro
    Casino Restaurants Near Casino & Resort, Reno 나주 출장마사지 · 853 Casino Drive, Reno, NV, 85301 · More Info · Hours, 진주 출장마사지 Accepts Credit 용인 출장마사지 Cards, 경산 출장마사지 Parking · 삼척 출장안마 Map · Amenities · More Info.

    ReplyDelete
  13. DisclaimerAll content on this web site, together with dictionary, thesaurus, literature, geography, and other reference knowledge is for informational functions solely. This data should not be thought-about complete, updated, and isn't meant to be used in place of a visit, session, or recommendation of a legal, medical, or some other skilled. All that's requested of you is to enter some primary data like your full name, 우리카지노 date of birth, and e mail address.

    ReplyDelete
  14. The identical particular person keeps the bank 스포츠 토토 till either all of the playing cards have been dealt or till the banker loses every little thing or retires voluntarily. Once the banker has put up a stake, the other players place their bets. If any participant wishes to guess the entire value of the bank in opposition to the banker, they name 'banco'.

    ReplyDelete
  15. Its very good chemical resistance is also be|can be} why it's utilized in chemical processing crops. Big tennis coloured set with racket and ball one line artwork. steady line drawing of tennis, string, sport, sports activities, activity, membership, recreation, training, tools, professional championship play, shade. 7 After an ingot is made, it's faraway from the furnace and inspected for titanium watch defects.

    ReplyDelete
  16. The non-slip base of this toy additionally provides you the option to turn it right into a strap-on harness for partner play. Safety dildoes –Avoid poisonous supplies, low cost producers, and nasty looking dildos. Kegel balls are normally weighted so want to|you must} squeeze your vagina to maintain them inside your body. Some are hollow with smaller balls inside that roll and bounce if you transfer, making a jiggling sensation.

    ReplyDelete
  17. Being licensed by the Malta Gaming Authority and controlled by eCOGRA means our security measures, recreation equity and repair all meet the very highest worldwide requirements. With progressive video games like Lightning Roulette, Casino Hold’em and Evolution Live Blackjack, you’re by no means in need of|wanting} live gaming leisure at JackpotCity Casino. Playing at JackpotCity Mobile Casino is all the time a beautiful option. The supplier has developed a dedicated app and you can access it anytime in your Android, Apple, or Windows. 더킹 카지노 The customer service at Jackpot City works 24/7 through email and live chat. Agents are available in quantity of} languages, so you won’t have problems when reaching them.

    ReplyDelete
  18. Roulette is still on high of each other casino casino.edu.kg recreation, adopted by poker. Poker is not appreciated by people due to its difficult guidelines, while roulette is very easy. The smartest thing about this platform is its organized interface. As quickly as you enter internet site}, you get the sensation of a professional setting. The web site keeps updating the winners' names, plus tips and methods are freely obtainable. Moreover, you may also|you can even} check which games have the most effective odds and the biggest stakes so you'll be able to|you possibly can} try your luck there.

    ReplyDelete