인쇄용 버전       전송     
평가 및 의견을 보내려면 클릭하십시오.
Popular Articles

Jason Clark

MSDN Magazine July 2003

...

Read more!

See how routed events and routed commands in Windows Presentation Foundation form the basis for communication between the parts of your UI.

Brian Noyes

MSDN Magazine September 2008

...

Read more!

Jeff Prosise explains when it's better to use UpdatePanel and when it's better to use asynchronous calls to WebMethods or page methods instead.

Jeff Prosise

MSDN Magazine June 2007

...

Read more!

This article introduces 10 development tools that can increase your productivity, give you a better understanding of .NET, and maybe even change the way that you develop applications. The tools covered include NUnit to write unit tests, Reflector to examine assemblies, FxCop to police your code, Regulator to build regular expressions, NDoc to create code documentation and five more.

James Avery

MSDN Magazine July 2004

...

Read more!

One-time passwords offer solutions to dictionary attacks, phishing, interception, and lots of other security breaches. Here's how it all works.

Dan Griffin

MSDN Magazine May 2008

...

Read more!

© 2004 Microsoft Corporation. All rights reserved.
Figure 1 Win32API.cs
// Win32API: wrapper for selected Win32 API functions
// To compile:
//    csc /t:library /out:Win32API.dll Win32API.cs
//
using System;
using System.Drawing;
using System.Text;
using System.Runtime.InteropServices;

//////////////////
// namespace to wrap Win32 API functions. Add them here as you need...
//
namespace Win32API {
   [StructLayout(LayoutKind.Sequential)]
   public struct POINT {
      public POINT(int xx, int yy) { x=xx; y=yy; }
      public int x;
      public int y;
      public override string ToString() {
         String s = String.Format("({0},{1})", x, y);
         return s;
      }
   }

   [StructLayout(LayoutKind.Sequential)]
   public struct SIZE {
      public SIZE(int cxx, int cyy) { cx=cxx; cy=cyy; }
      public int cx;
      public int cy;
      public override string ToString() {
         String s = String.Format("({0},{1})", cx, cy);
         return s;
      }
   }

   [StructLayout(LayoutKind.Sequential)]
   public struct RECT {
      public int left;
      public int top;
      public int right;
      public int bottom;
      public int Width()      { return right - left; }
      public int Height()     { return bottom - top; }
      public POINT TopLeft()  { return new POINT(left,top); }
      public SIZE  Size()     { return new SIZE(Width(), Height()); }
      public override string ToString() {
         String s = String.Format("{0}x{1}", TopLeft(), Size());
         return s;
      }
   }

   public class Win32 {
      [DllImport("user32.dll")]
      public static extern bool IsWindowVisible(int hwnd);

      [DllImport("user32.dll")]
      public static extern int GetWindowText(int hwnd,
         StringBuilder buf, int nMaxCount);

      [DllImport("user32.dll")]
      public static extern int GetClassName(int hwnd,
         [MarshalAs(UnmanagedType.LPStr)] StringBuilder buf,
         int nMaxCount);

      [DllImport("user32.dll")]
      public static extern int GetWindowRect(int hwnd, ref RECT rc);

      [DllImport("user32.dll")]
      // note the runtime knows how to marshal a Rectangle
      public static extern int GetWindowRect(int hwnd, ref Rectangle rc);

      // ... add more here
   }
}
Figure 2 WinArray.cs
// WinArray: generate ArrayList of top-level windows using EnumWindows.
//
using System;
using System.Collections;
using System.Runtime.InteropServices;

namespace WinArray {

   public class WindowArray : ArrayList {
      private delegate bool EnumWindowsCB(int hwnd, IntPtr param);

      // This is declared private since only I use it—no need
      [DllImport("user32")]
      private static extern int EnumWindows(EnumWindowsCB cb, 
         IntPtr param); 

      private static bool MyEnumWindowsCB(int hwnd, IntPtr param) {
         GCHandle gch = (GCHandle)param;
         WindowArray itw = (WindowArray)gch.Target;
         itw.Add(hwnd);
         return true;
      }

      // This is the only public method, the only one you need to call
      public WindowArray() {
         GCHandle gch = GCHandle.Alloc(this);
         EnumWindowsCB ewcb = new EnumWindowsCB(MyEnumWindowsCB);
         EnumWindows(ewcb, (IntPtr)gch);
         gch.Free();
      }
   }
}
Figure 3 ListWin.cs
using System;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Win32API; // home-brew wrapper for native API
using WinArray; // home-brew window iterator

class MyApp {
   // global command-line switches
   static bool bRectangle = false; // show window rect using Rectangle
   static bool bRect = false;      // show window Rect using RECT
   static bool bClassName = false; // show class name
   static bool bTitle = false;     // show title
   static bool bHwnd = false;      // show HWND

   [STAThread]
   // main entry point
   static int Main(string[] args) {
      // Parse command line. Switches can come in any order.
      if (args.GetLength(0)<=0)
         return help();
      for (int i=0, len=args.GetLength(0); i<len; i++) {
         if (args[i].StartsWith("/") || args[i].StartsWith("-") ) {
            for (int j=1; j<args[i].Length; j++) {
               switch (args[i][j]) {
               case 'c': bClassName = true; break;
               case 'h': bHwnd = true; break;
               case 'r': bRect = true; break;
               case 'R': bRectangle = true; break;
               case 't': bTitle = true; break;
               case '?': default: return help();
               }
            }
         }
      }
      
      WindowArray itw = new WindowArray();
      foreach (int hwnd in itw) {
         if (Win32.IsWindowVisible(hwnd)) {
            if (bHwnd) {
               Console.Write("{0:x8}", hwnd);
            }
            if (bClassName) {
               StringBuilder cname = new StringBuilder(256);
               Win32.GetClassName(hwnd, cname, cname.Capacity);
               Console.Write(" {0}",cname);
            }
            if (bRectangle) {
               Rectangle rc = new Rectangle();
               Win32.GetWindowRect(hwnd, ref rc);
               Console.Write(" {0}",rc);
            } else if (bRect) {
               RECT rc = new RECT();
               Win32.GetWindowRect(hwnd, ref rc);
               Console.Write(" {0}",rc);
            }
            if (bTitle) {
               StringBuilder title = new StringBuilder(256);
               Win32.GetWindowText(hwnd, title, title.Capacity);
               Console.Write(" {0}",title);
            }
            Console.WriteLine();
         }
      }
      return 0;
   }

   static int help() {
      Console.WriteLine("ListWin:  List top-level windows.");
      Console.WriteLine("          Copyright 2002 Paul DiLascia.");
      Console.WriteLine("Format:   ListWin [/chrRt]");
      Console.WriteLine("Options:");
      Console.WriteLine(" /c(lassname) show window class name");
      Console.WriteLine(" /h(wnd)      show HWNDs");
      Console.WriteLine(" /t(itle)     show title (caption)");
      Console.WriteLine(" /r(ect)      show window rect using RECT");
      Console.WriteLine(" /R(ectangle) show window rect using Rectangle");
      Console.WriteLine("");
      return 0;
   }
}
Figure 6 kp
#include "stdafx.h"
#include "EnumProc.h"

typedef list<string> CStringList;         // like MFC, but with STL
inline BOOL isswitch(TCHAR c) { return c==L'/' || c==L'-'; }

int main(int argc, TCHAR* argv[], TCHAR* envp[])
{
    CStringList cmdargs;         // command-line args (processes to kill)
    BOOL bDisplayOnly=FALSE;     // don't kill, just show results
    BOOL bQuiet=FALSE;           // suppress error messages
    BOOL bZap=FALSE;             // force-kill process

    // Parse command line. Switches can come in any order.
    for (int i=1; i<argc; i++) {
        if (isswitch(argv[i][0])) {
            for (UINT j=1; j<strlen(argv[i]); j++) {
                switch(tolower(argv[i][j])) {
                case '?':    help();    return 0;
                case 'n':    bDisplayOnly=TRUE; break;
                case 'q':    bQuiet=TRUE;       break;
                case 'z':    bZap=TRUE;         break;
                default:
                    return help();
                }
            }
        } else {
            cmdargs.push_back(argv[i]);     // got a non-switch arg: add 
                                            // to list
        }
    }
    if (cmdargs.size()<=0)
        help();

    // Now iterate args (module names), killing each one
    CStringList::iterator it;
    for (it=cmdargs.begin(); it!=cmdargs.end(); it++) {
        CFindKillProcess fkp;
        DWORD pid = fkp.FindProcess(it->c_str());
        if (pid) {
            if (bDisplayOnly) {
                _tprintf(_T("Kill process %d(0x%08x)\n"),pid,pid);
            } else {
                fkp.KillProcess(pid, bZap);
            }
        } else if (!bQuiet) {
            _tprintf(_T("Error: Can't find process '%s'.\n"),it-
            >c_str());
        }
    }
    return 0;
}
Figure 7 EnumProc

EnumProc.h
// Code from last month's column not shown: CProcessIterator,
// CWindowIterator, etc.

//////////////////
// Handy class to facilitate finding and killing a process by name.
//
class CFindKillProcess {
public:
    CFindKillProcess();
    ~CFindKillProcess();
    DWORD FindProcess(LPCTSTR lpModname, BOOL bAddExe=TRUE);
    BOOL  KillProcess(DWORD pid, BOOL bZap);
};
EnumProc.cpp
#include "stdafx.h"
#include "EnumProc.h"

// Code from last month's column not shown: CProcessIterator,
// CWindowIterator, etc.

////////////////////////////////////////////////////////////////
// CFindKillProcess - to find/kill a process by module name.
//
CFindKillProcess::CFindKillProcess()
{
}

CFindKillProcess::~CFindKillProcess()
{
}

//////////////////
// Search for process whose module name matches parameter.
// Finds "foo" or "foo.exe"
//
DWORD CFindKillProcess::FindProcess(LPCTSTR modname, BOOL bAddExe)
{
    CProcessIterator itp;
    for (DWORD pid=itp.First(); pid; pid=itp.Next()) {
        TCHAR name[_MAX_PATH];
        CProcessModuleIterator itm(pid);
        HMODULE hModule = itm.First(); // .EXE
        if (hModule) {
            GetModuleBaseName(itm.GetProcessHandle(),
                hModule, name, _MAX_PATH);

            string sModName = modname;
            if (strcmpi(sModName.c_str(),name)==0)
                return pid;
            sModName += ".exe";
            if (bAddExe && strcmpi(sModName.c_str(),name)==0)
                return pid;
        }
    }
    return 0;
}

//////////////////
// Kill a process cleanly: Close main windows and wait.
// bZap=TRUE to force kill.
//
BOOL CFindKillProcess::KillProcess(DWORD pid, BOOL bZap)
{
    CMainWindowIterator itw(pid);
    for (HWND hwnd=itw.First(); hwnd; hwnd=itw.Next()) {
        DWORD bOKToKill = FALSE;
        SendMessageTimeout(hwnd, WM_QUERYENDSESSION, 0, 0,
            SMTO_ABORTIFHUNG|SMTO_NOTIMEOUTIFNOTHUNG, 100, &bOKToKill);
        if (!bOKToKill)
            return FALSE;  // window doesn't want to die: abort
        PostMessage(hwnd, WM_CLOSE, 0, 0);
    }

    // I've closed the main windows; now wait for process to die. 
    BOOL bKilled = TRUE;
    HANDLE hp=OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE,FALSE,pid);
    if (hp) {
        if (WaitForSingleObject(hp, 5000) != WAIT_OBJECT_0) {
            if (bZap) { // didn't die: force kill it if zap requested
                TerminateProcess(hp,0);
            } else {
                bKilled = FALSE;
            }
        }
        CloseHandle(hp);
    }
    return bKilled;
}
Page view tracker