'3. Implementation/C#'에 해당되는 글 17건

  1. 2013.12.10 Run a sudo command using RunCommand
  2. 2012.02.20 ILMerge : merge multiple .NET assemblies into a single assembly
  3. 2012.02.17 How to load an assembly at runtime that is located in a folder that is not the bin folder of the application
  4. 2012.01.31 재귀와 반복
  5. 2011.08.16 How to invoke with more than one parameter
  6. 2011.01.03 CustomQueryInterface - IDispatch and Aggregation
  7. 2010.12.08 ListView 깜박임 제거
  8. 2010.12.08 비동기로 실행하기
  9. 2010.10.22 하드웨어 정보 가져오기 1
  10. 2010.04.26 어셈블리 보기: ILDASM
  11. 2010.04.23 Snoop: a WPF utility
  12. 2010.04.22 WPF 와 Windows Form Control 간의 상호 운용
  13. 2010.04.21 How to register .NET components with COM
  14. 2010.04.01 AutoDual ClassInterfaceType을 사용하지 마십시오
  15. 2010.04.01 Writing an ActiveX Control in .NET
  16. 2010.03.26 C# Delegate 사용하기
  17. 2010.03.25 A Simple C# Global Low Level Keyboard Hook
2013. 12. 10. 06:54

Run a sudo command using RunCommand

I had googled for this and got the useful information:



Unfortunalty, when yo execute a command using RunCommand you cannot run it using su or sudo.

The reason is that command executes as one single unit and have no knowledge or previous commands or shell it executes in.

It seems that SSH Server creates context for command execution, executes it and the deletes this context.

One thing you can try to execute the command is shell object, this way it creates shell, pretty much like you do with putty, and lets you send text and get text back, which you can analyze later.



Here is alternative to run a command


client.RunCommand("echo \"userpwd\" | sudo -S command").Execute()


-S key tells sudo to take password from stdin, which is piped from the previous echo command


Source: https://sshnet.codeplex.com/discussions/269667


If sudo command doesn't prompt password, output will be like the following:


administrator@ubuntu:~$ echo "test" | sudo -S ls
[sudo] password for administrator: Sorry, try again.
[sudo] password for administrator:
Sorry, try again.
[sudo] password for administrator:
Sorry, try again.
sudo: 3 incorrect password attempts


If you use RunCommand, it will be ok because there is no connection (or context) between each RunCommand. I mean that sudo command using RunCommand will prompt password all the time.


Here is Sample codes.


using (SshClient client = new SshClient(connectionInfo)) { client.Connect(); using (var cmd = client.CreateCommand("echo \"password\" | sudo -S ls")) { cmd.CommandTimeout = TimeSpan.FromSeconds(10); var asynch = cmd.BeginExecute(); var reader = new StreamReader(cmd.OutputStream); while (!asynch.IsCompleted) { var result = reader.ReadToEnd(); if (string.IsNullOrEmpty(result)) continue; Console.Write(result); } cmd.EndExecute(asynch); client.Disconnect(); } }


2012. 2. 20. 20:38

ILMerge : merge multiple .NET assemblies into a single assembly

같은 이름의 다른 위치에 있는 파일 로딩 문제를 고민하다가 Microsoft Research 에서 만든 ILMerge 라는 툴을 발견하였습니다.  간단히 설명하면 여러개의 dll 을 하나로 합쳐서 배포할 수 있게 해주는 툴입니다. 

아래 링크에서 최신 버전을 받아서 설치합니다.

http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=17630 

설치가 완료되면 

ilmerge /target:winexe /out:test.exe MyApp.exe lib1.dll lib2.dll lib3.dll

결과가 dll 이면 /target:library 로 하면 됩니다. 그리고 자세한 옵션은 Ilmerge 의 명령어 도움말을 보시면 됩니다.

훌륭합니다, Microsoft~!

참고:
http://research.microsoft.com/en-us/people/mbarnett/ILMerge.aspx
http://stackoverflow.com/questions/4635573/merging-dll-files-with-ilmerge-failing-to-work
2012. 2. 17. 06:39

How to load an assembly at runtime that is located in a folder that is not the bin folder of the application

A.dll
B.dll
Common.dll 

이 있습니다. Common.dll 은 A, B 모두에게 사용되기 때문에 같이 개발되고 빌드됩니다. 하지만 A.dll 과 B.dll 은 각기 다른 목적을 가지고 있기 때문에 다른 위치에 배포됩니다. 예를 들어

Test1/
A.dll
Common.dll
Test2/
B.dll
Common.dll

이렇게 배포를 했는데 문제가 생겼습니다. Test1, Test2 는 각기 다르게 배포되고 Common.dll 은 여러버전이 존재할 수 있습니다. A 가 처음 로딩될 때는 Test1 의 Common.dll 이 정상적으로 로딩되었으나, 그 다음에 B가 로디오될 때는 Test2 에 있는 Common.dll 이 아니라 이미 로딩되어 있는 Test1/Common.dll 을 그대로 사용하는 문제였습니다. (A.dll 과 B.dll 은 모두 COM 이기 때문에 배포시 'regasm.exe /codebase a.dll" 과 같이 codebase 로 글로벌하게 등록되어 있습니다.) 

이 문제를 수정하기 위해 자료를 찾다가 MS 에서 제공하는 아래 링크 정보를 찾았습니다.

http://support.microsoft.com/kb/837908 

3가지 방법을 소개 하고 있는데 그중에 3번째인 AssemblyResolve 이벤트라는 재밌는 녀석이 나옵니다.

핸들러 등록 방법

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += 
    new ResolveEventHandler(MyResolveEventHandler);

핸들러 코드 예제

private Assembly MyResolveEventHandler(object sender,ResolveEventArgs args)
{
	//This handler is called only when the common language runtime tries to bind to the assembly and fails.

	//Retrieve the list of referenced assemblies in an array of AssemblyName.
	Assembly MyAssembly,objExecutingAssemblies;
	string strTempAssmbPath="";

	objExecutingAssemblies=Assembly.GetExecutingAssembly();
	AssemblyName [] arrReferencedAssmbNames=objExecutingAssemblies.GetReferencedAssemblies();
			
	//Loop through the array of referenced assembly names.
	foreach(AssemblyName strAssmbName in arrReferencedAssmbNames)
	{
		//Check for the assembly names that have raised the "AssemblyResolve" event.
		if(strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(","))==args.Name.Substring(0, args.Name.IndexOf(",")))
		{
			//Build the path of the assembly from where it has to be loaded.				
			strTempAssmbPath="C:\\Myassemblies\\"+args.Name.Substring(0,args.Name.IndexOf(","))+".dll";
			break;
		}

	}
	//Load the assembly from the specified path. 					
	MyAssembly = Assembly.LoadFrom(strTempAssmbPath);					

	//Return the loaded assembly.
	return MyAssembly;			
}

주의: 위 코드가 제기된 문제를 해결했다는 건 아닙니다. 아직 적용을 해보지 못했습니다.  
 
2012. 1. 31. 07:08

재귀와 반복

구현할 때 재귀와 반복의 문제를 고민할 때가 있습니다. 제 경험으로는 반복보다는 재귀로 작성하는게 훨 쉽습니다. 그리고 이게 더 코드가 깔끔하다고 생각했었는데 이 재귀를 다시 반복으로 구현하는 것도 나쁘지 않다는 생각을 갖게 되었습니다. 

왜 이런 재귀와 반복의 변환을 고민하게 되었냐면은 재귀로 작성했던 기능이 있는데 이 기능이 함수 하나로만 작성되어야할 필요가 생겼습니다. 그래서 내키지 않았지만 어쩔수 없이 반복으로 재작성하였습니다. 해놓고 보니 나쁘지 않더군요.

재귀와 반복 구현에 대해 마이크로소프트에서 제공하는 아주 좋은 예제가 있어 공유해 드립니다.

출처:   http://msdn.microsoft.com/ko-kr/library/bb513869.aspx

렉토리 탐색하기

1. 재귀를 이용한 방법 (Recusive File Search)

public class RecursiveFileSearch
{
    static System.Collections.Specialized.StringCollection log = new System.Collections.Specialized.StringCollection();

    static void Main()
    {
        // Start with drives if you have to search the entire computer.
        string[] drives = System.Environment.GetLogicalDrives();

        foreach (string dr in drives)
        {
            System.IO.DriveInfo di = new System.IO.DriveInfo(dr);

            // Here we skip the drive if it is not ready to be read. This
            // is not necessarily the appropriate action in all scenarios.
            if (!di.IsReady)
            {
                Console.WriteLine("The drive {0} could not be read", di.Name);
                continue;
            }
            System.IO.DirectoryInfo rootDir = di.RootDirectory;
            WalkDirectoryTree(rootDir);
        }

        // Write out all the files that could not be processed.
        Console.WriteLine("Files with restricted access:");
        foreach (string s in log)
        {
            Console.WriteLine(s);
        }
        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key");
        Console.ReadKey();
    }

    static void WalkDirectoryTree(System.IO.DirectoryInfo root)
    {
        System.IO.FileInfo[] files = null;
        System.IO.DirectoryInfo[] subDirs = null;

        // First, process all the files directly under this folder
        try
        {
            files = root.GetFiles("*.*");
        }
        // This is thrown if even one of the files requires permissions greater
        // than the application provides.
        catch (UnauthorizedAccessException e)
        {
            // This code just writes out the message and continues to recurse.
            // You may decide to do something different here. For example, you
            // can try to elevate your privileges and access the file again.
            log.Add(e.Message);
        }

        catch (System.IO.DirectoryNotFoundException e)
        {
            Console.WriteLine(e.Message);
        }

        if (files != null)
        {
            foreach (System.IO.FileInfo fi in files)
            {
                // In this example, we only access the existing FileInfo object. If we
                // want to open, delete or modify the file, then
                // a try-catch block is required here to handle the case
                // where the file has been deleted since the call to TraverseTree().
                Console.WriteLine(fi.FullName);
            }

            // Now find all the subdirectories under this directory.
            subDirs = root.GetDirectories();

            foreach (System.IO.DirectoryInfo dirInfo in subDirs)
            {
                // Resursive call for each subdirectory.
                WalkDirectoryTree(dirInfo);
            }
        }            
    }
}

2. 반복을 이용한 방법 (Stack based Iteration)

public class StackBasedIteration
{
    static void Main(string[] args)
    {
        // Specify the starting folder on the command line, or in 
        // Visual Studio in the Project > Properties > Debug pane.
        TraverseTree(args[0]);

        Console.WriteLine("Press any key");
        Console.ReadKey();
    }

    public static void TraverseTree(string root)
    {
        // Data structure to hold names of subfolders to be
        // examined for files.
        Stack<string> dirs = new Stack<string>(20);

        if (!System.IO.Directory.Exists(root))
        {
            throw new ArgumentException();
        }
        dirs.Push(root);

        while (dirs.Count > 0)
        {
            string currentDir = dirs.Pop();
            string[] subDirs;
            try
            {
                subDirs = System.IO.Directory.GetDirectories(currentDir);
            }
            // An UnauthorizedAccessException exception will be thrown if we do not have
            // discovery permission on a folder or file. It may or may not be acceptable 
            // to ignore the exception and continue enumerating the remaining files and 
            // folders. It is also possible (but unlikely) that a DirectoryNotFound exception 
            // will be raised. This will happen if currentDir has been deleted by
            // another application or thread after our call to Directory.Exists. The 
            // choice of which exceptions to catch depends entirely on the specific task 
            // you are intending to perform and also on how much you know with certainty 
            // about the systems on which this code will run.
            catch (UnauthorizedAccessException e)
            {                    
                Console.WriteLine(e.Message);
                continue;
            }
            catch (System.IO.DirectoryNotFoundException e)
            {
                Console.WriteLine(e.Message);
                continue;
            }

            string[] files = null;
            try
            {
                files = System.IO.Directory.GetFiles(currentDir);
            }

            catch (UnauthorizedAccessException e)
            {

                Console.WriteLine(e.Message);
                continue;
            }

            catch (System.IO.DirectoryNotFoundException e)
            {
                Console.WriteLine(e.Message);
                continue;
            }
            // Perform the required action on each file here.
            // Modify this block to perform your required task.
            foreach (string file in files)
            {
                try
                {
                    // Perform whatever action is required in your scenario.
                    System.IO.FileInfo fi = new System.IO.FileInfo(file);
                    Console.WriteLine("{0}: {1}, {2}", fi.Name, fi.Length, fi.CreationTime);
                }
                catch (System.IO.FileNotFoundException e)
                {
                    // If file was deleted by a separate application
                    //  or thread since the call to TraverseTree()
                    // then just continue.
                    Console.WriteLine(e.Message);
                    continue;
                }
            }

            // Push the subdirectories onto the stack for traversal.
            // This could also be done before handing the files.
            foreach (string str in subDirs)
                dirs.Push(str);
        }
    } 
} 
2011. 8. 16. 22:33

How to invoke with more than one parameter

C#에 익숙하지 않아서인지 이런 구문이 자꾸 헷갈리네요. MFC 에 비해서 워낙 쉽다는 느낌을 많이 받아서인지 그다지 C# 고유의 문법에 깊이 빠져들지 못합니다. 아래 예제는 Invoke 메소드를 이용하여 여러 파라미터를 넘기는 방법에 대해서 소개하고 있습니다. 이전까지는 매번 같은 파라미터를 가지는 delegate 를 선언했었는데, 역시 stupid 한 방법이었습니다. ㅋㅋ

public void DoSomething(string foo, int bar)
{
    if (this.InvokeRequired) {
        this.Invoke((MethodInvoker)delegate {
            DoSomething(foo,bar);
        });
        return;
    }
    // do something with foo and bar
    this.Text = foo;
    Console.WriteLine(bar);
}


출처: http://stackoverflow.com/questions/729430/c-how-to-invoke-with-more-than-one-parameter
2011. 1. 3. 23:00

CustomQueryInterface - IDispatch and Aggregation

C# 에서 IDispatch 인터페이스를 직접 구현하는 방법을 찾다가 발견한 링크입니다. 비록 다른 방법을 이용하여 해결하였지만 이 방법도 혹시 나중에 유용하게 쓰일수 있지 않을까 해서 keep 해 둡니다.

Source: http://clrinterop.codeplex.com/releases/view/32350

In the CLR v4 there is a new interface called ICustomQueryInterface. This very cool new feature will enable developers to provide their own managed implementation of custom and standard COM interfaces (except IUnknown). One interesting scenario, which will be illustrated in the sample below, is dynamic managed aggregation with a flexible implementation of IDispatch

In this sample, we will show an implementation of ICustomQueryInterface through
  • a managed IDispatch implementation that overrides the default IDispatch implementation by the CLR
  • a managed COM aggregation system where both Outer and Inner objects are managed objects

2010. 12. 8. 03:15

ListView 깜박임 제거


아래 코드를 이용하면 꼴사나운 LiveView 의 깜박임 문제를 어느정도 해결할 수 있습니다.


class ListViewNF : System.Windows.Forms.ListView
{
    public ListViewNF()
    {
        //Activate double buffering
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);

        //Enable the OnNotifyMessage event so we get a chance to filter out 
        // Windows messages before they get to the form's WndProc
        this.SetStyle(ControlStyles.EnableNotifyMessage, true);
    }

    protected override void OnNotifyMessage(Message m)
    {
        //Filter out the WM_ERASEBKGND message
        if(m.Msg != 0x14)
        {
            base.OnNotifyMessage(m);
        }
    }
}


2010. 12. 8. 03:03

비동기로 실행하기

UI 업데이트를 비동기로 실행하는 코드 예이다. C# 에서는 PostMessage 와 유사한 기능을 아래처럼 쉽게 구현할 수 있습니다.


public class FormFoo : Form
{
   Label label = new Label();
   public static void Main()
   {
       Application.Run(new FormFoo());
   }

   public FormFoo()
   {
      InitializeComponent();

      Thread t = new Thread(new ThreadStart(ChangeLabel));
      t.Start();
   }

   private void ChangeLabel()
   {
       for (int i = 0; i<100; ++i)
       {
          SetLabelText(i);
          Thread.Sleep(1000);
       }
   }
   private delegate void SetLabelTextDelegate(int number);
   private void SetLabelText(int number)
   {
      // label.Text = number.ToString();
      // Do NOT do this, as we are on a different thread.

      // Check if we need to call BeginInvoke.
      if (this.InvokeRequired)
      {
         // Pass the same function to BeginInvoke,
         // but the call would come on the correct
         // thread and InvokeRequired will be false.
         this.BeginInvoke(new SetLabelTextDelegate(SetLabelText), 
                                          new object[] {number});

         return;
      }

      label.Text = number.ToString();
   }
}

참고한 사이트의 중요한 부분은 다음과 같습니다.

Why and when to call BeginInvoke

With all that stuff inside our head now, we can easily figure out the reason for the existence of BeginInvoke. It essentially does a PostMessage. Whenever you want to update a control from a thread that didn't create it, instead of directly calling the method/property to update it, you need to wrap it in a BeginInvoke call. According to MSDN: "There are four methods on a control that are safe to call from any thread: Invoke,BeginInvokeEndInvoke, and CreateGraphics. For all other method calls, you should use one of the invoke methods to marshal the call to the control's thread". One of the invoke methods, you say, what are the others? Well, the Control class provides one property and two methods to do the stuff we discussed.

  • InvokeRequired: This bool property returns true if the thread on which this property is called is not the thread that created this control. Basically, if InvokeRequired returns true, you need to call one of the two Invoke methods.
  • BeginInvoke: This is a functionally similar to the PostMessage API function. It posts a message to the queue and returns immediately without waiting for the message to be processed. BeginInvoke returns an IAsyncResult, just like the BeginInvoke method on any delegate. And you can use IAsyncResult to wait for the message to be processed, just as usual. And you can call EndInvoke to get return values or outparameter values, as usual.
  • Invoke: This is like the SendMessage API function in that it waits till the message gets processed, but it does not do a SendMessageinternally, it also does a PostMessage. The difference is that it waits till the delegate is executed on the UI thread before returning. So while there is a chance for the deadlock problem to occur, you can be sure that the other problems associated with SendMessage won't happen.Invoke returns the value that the function wrapped by the delegate returned.

2010. 10. 22. 07:16

하드웨어 정보 가져오기

원본: http://www.codeproject.com/KB/system/GetHardwareInformation.aspx

WMI 를 이용하는 것이므로, 비슷한 방식으로 Script 에서도 사용가능해 보임.

1. 네임스페이스 선언
using System.Management;
2. ManagementObjectSearcher 클래스 생성

ManagementObjectSearcher searcher = new ManagementObjectSearcher(
    "select * from " + Key);
3. Key 리스트

Win32_1394Controller
Win32_1394ControllerDevice
Win32_Account
Win32_AccountSID
Win32_ACE
Win32_ActionCheck
Win32_AllocatedResource
Win32_ApplicationCommandLine
Win32_ApplicationService
Win32_AssociatedBattery
Win32_AssociatedProcessorMemory
Win32_BaseBoard
Win32_BaseService
Win32_Battery
Win32_Binary
Win32_BindImageAction
Win32_BIOS
Win32_BootConfiguration
Win32_Bus
Win32_CacheMemory
Win32_CDROMDrive
Win32_CheckCheck
Win32_CIMLogicalDeviceCIMDataFile
Win32_ClassicCOMApplicationClasses
Win32_ClassicCOMClass
Win32_ClassicCOMClassSetting
Win32_ClassicCOMClassSettings
Win32_ClassInfoAction
Win32_ClientApplicationSetting
Win32_CodecFile
Win32_COMApplication
Win32_COMApplicationClasses
Win32_COMApplicationSettings
Win32_COMClass
Win32_ComClassAutoEmulator
Win32_ComClassEmulator
Win32_CommandLineAccess
Win32_ComponentCategory
Win32_ComputerSystem
Win32_ComputerSystemProcessor
Win32_ComputerSystemProduct
Win32_COMSetting
Win32_Condition
Win32_CreateFolderAction
Win32_CurrentProbe
Win32_DCOMApplication
Win32_DCOMApplicationAccessAllowedSetting
Win32_DCOMApplicationLaunchAllowedSetting
Win32_DCOMApplicationSetting
Win32_DependentService
Win32_Desktop
Win32_DesktopMonitor
Win32_DeviceBus
Win32_DeviceMemoryAddress
Win32_DeviceSettings
Win32_Directory
Win32_DirectorySpecification
Win32_DiskDrive
Win32_DiskDriveToDiskPartition
Win32_DiskPartition
Win32_DisplayConfiguration
Win32_DisplayControllerConfiguration
Win32_DMAChannel
Win32_DriverVXD
Win32_DuplicateFileAction
Win32_Environment
Win32_EnvironmentSpecification
Win32_ExtensionInfoAction
Win32_Fan
Win32_FileSpecification
Win32_FloppyController
Win32_FloppyDrive
Win32_FontInfoAction
Win32_Group
Win32_GroupUser
Win32_HeatPipe
Win32_IDEController
Win32_IDEControllerDevice
Win32_ImplementedCategory
Win32_InfraredDevice
Win32_IniFileSpecification
Win32_InstalledSoftwareElement
Win32_IRQResource
Win32_Keyboard
Win32_LaunchCondition
Win32_LoadOrderGroup
Win32_LoadOrderGroupServiceDependencies
Win32_LoadOrderGroupServiceMembers
Win32_LogicalDisk
Win32_LogicalDiskRootDirectory
Win32_LogicalDiskToPartition
Win32_LogicalFileAccess
Win32_LogicalFileAuditing
Win32_LogicalFileGroup
Win32_LogicalFileOwner
Win32_LogicalFileSecuritySetting
Win32_LogicalMemoryConfiguration
Win32_LogicalProgramGroup
Win32_LogicalProgramGroupDirectory
Win32_LogicalProgramGroupItem
Win32_LogicalProgramGroupItemDataFile
Win32_LogicalShareAccess
Win32_LogicalShareAuditing
Win32_LogicalShareSecuritySetting
Win32_ManagedSystemElementResource
Win32_MemoryArray
Win32_MemoryArrayLocation
Win32_MemoryDevice
Win32_MemoryDeviceArray
Win32_MemoryDeviceLocation
Win32_MethodParameterClass
Win32_MIMEInfoAction
Win32_MotherboardDevice
Win32_MoveFileAction
Win32_MSIResource
Win32_NetworkAdapter
Win32_NetworkAdapterConfiguration
Win32_NetworkAdapterSetting
Win32_NetworkClient
Win32_NetworkConnection
Win32_NetworkLoginProfile
Win32_NetworkProtocol
Win32_NTEventlogFile
Win32_NTLogEvent
Win32_NTLogEventComputer
Win32_NTLogEventLog
Win32_NTLogEventUser
Win32_ODBCAttribute
Win32_ODBCDataSourceAttribute
Win32_ODBCDataSourceSpecification
Win32_ODBCDriverAttribute
Win32_ODBCDriverSoftwareElement
Win32_ODBCDriverSpecification
Win32_ODBCSourceAttribute
Win32_ODBCTranslatorSpecification
Win32_OnBoardDevice
Win32_OperatingSystem
Win32_OperatingSystemQFE
Win32_OSRecoveryConfiguration
Win32_PageFile
Win32_PageFileElementSetting
Win32_PageFileSetting
Win32_PageFileUsage
Win32_ParallelPort
Win32_Patch
Win32_PatchFile
Win32_PatchPackage
Win32_PCMCIAController
Win32_Perf
Win32_PerfRawData
Win32_PerfRawData_ASP_ActiveServerPages
Win32_PerfRawData_ASPNET_114322_ASPNETAppsv114322
Win32_PerfRawData_ASPNET_114322_ASPNETv114322
Win32_PerfRawData_ASPNET_ASPNET
Win32_PerfRawData_ASPNET_ASPNETApplications
Win32_PerfRawData_IAS_IASAccountingClients
Win32_PerfRawData_IAS_IASAccountingServer
Win32_PerfRawData_IAS_IASAuthenticationClients
Win32_PerfRawData_IAS_IASAuthenticationServer
Win32_PerfRawData_InetInfo_InternetInformationServicesGlobal
Win32_PerfRawData_MSDTC_DistributedTransactionCoordinator
Win32_PerfRawData_MSFTPSVC_FTPService
Win32_PerfRawData_MSSQLSERVER_SQLServerAccessMethods
Win32_PerfRawData_MSSQLSERVER_SQLServerBackupDevice
Win32_PerfRawData_MSSQLSERVER_SQLServerBufferManager
Win32_PerfRawData_MSSQLSERVER_SQLServerBufferPartition
Win32_PerfRawData_MSSQLSERVER_SQLServerCacheManager
Win32_PerfRawData_MSSQLSERVER_SQLServerDatabases
Win32_PerfRawData_MSSQLSERVER_SQLServerGeneralStatistics
Win32_PerfRawData_MSSQLSERVER_SQLServerLatches
Win32_PerfRawData_MSSQLSERVER_SQLServerLocks
Win32_PerfRawData_MSSQLSERVER_SQLServerMemoryManager
Win32_PerfRawData_MSSQLSERVER_SQLServerReplicationAgents
Win32_PerfRawData_MSSQLSERVER_SQLServerReplicationDist
Win32_PerfRawData_MSSQLSERVER_SQLServerReplicationLogreader
Win32_PerfRawData_MSSQLSERVER_SQLServerReplicationMerge
Win32_PerfRawData_MSSQLSERVER_SQLServerReplicationSnapshot
Win32_PerfRawData_MSSQLSERVER_SQLServerSQLStatistics
Win32_PerfRawData_MSSQLSERVER_SQLServerUserSettable
Win32_PerfRawData_NETFramework_NETCLRExceptions
Win32_PerfRawData_NETFramework_NETCLRInterop
Win32_PerfRawData_NETFramework_NETCLRJit
Win32_PerfRawData_NETFramework_NETCLRLoading
Win32_PerfRawData_NETFramework_NETCLRLocksAndThreads
Win32_PerfRawData_NETFramework_NETCLRMemory
Win32_PerfRawData_NETFramework_NETCLRRemoting
Win32_PerfRawData_NETFramework_NETCLRSecurity
Win32_PerfRawData_Outlook_Outlook
Win32_PerfRawData_PerfDisk_PhysicalDisk
Win32_PerfRawData_PerfNet_Browser
Win32_PerfRawData_PerfNet_Redirector
Win32_PerfRawData_PerfNet_Server
Win32_PerfRawData_PerfNet_ServerWorkQueues
Win32_PerfRawData_PerfOS_Cache
Win32_PerfRawData_PerfOS_Memory
Win32_PerfRawData_PerfOS_Objects
Win32_PerfRawData_PerfOS_PagingFile
Win32_PerfRawData_PerfOS_Processor
Win32_PerfRawData_PerfOS_System
Win32_PerfRawData_PerfProc_FullImage_Costly
Win32_PerfRawData_PerfProc_Image_Costly
Win32_PerfRawData_PerfProc_JobObject
Win32_PerfRawData_PerfProc_JobObjectDetails
Win32_PerfRawData_PerfProc_Process
Win32_PerfRawData_PerfProc_ProcessAddressSpace_Costly
Win32_PerfRawData_PerfProc_Thread
Win32_PerfRawData_PerfProc_ThreadDetails_Costly
Win32_PerfRawData_RemoteAccess_RASPort
Win32_PerfRawData_RemoteAccess_RASTotal
Win32_PerfRawData_RSVP_ACSPerRSVPService
Win32_PerfRawData_Spooler_PrintQueue
Win32_PerfRawData_TapiSrv_Telephony
Win32_PerfRawData_Tcpip_ICMP
Win32_PerfRawData_Tcpip_IP
Win32_PerfRawData_Tcpip_NBTConnection
Win32_PerfRawData_Tcpip_NetworkInterface
Win32_PerfRawData_Tcpip_TCP
Win32_PerfRawData_Tcpip_UDP
Win32_PerfRawData_W3SVC_WebService
Win32_PhysicalMemory
Win32_PhysicalMemoryArray
Win32_PhysicalMemoryLocation
Win32_PNPAllocatedResource
Win32_PnPDevice
Win32_PnPEntity
Win32_PointingDevice
Win32_PortableBattery
Win32_PortConnector
Win32_PortResource
Win32_POTSModem
Win32_POTSModemToSerialPort
Win32_PowerManagementEvent
Win32_Printer
Win32_PrinterConfiguration
Win32_PrinterController
Win32_PrinterDriverDll
Win32_PrinterSetting
Win32_PrinterShare
Win32_PrintJob
Win32_PrivilegesStatus
Win32_Process
Win32_Processor
Win32_ProcessStartup
Win32_Product
Win32_ProductCheck
Win32_ProductResource
Win32_ProductSoftwareFeatures
Win32_ProgIDSpecification
Win32_ProgramGroup
Win32_ProgramGroupContents
Win32_ProgramGroupOrItem
Win32_Property
Win32_ProtocolBinding
Win32_PublishComponentAction
Win32_QuickFixEngineering
Win32_Refrigeration
Win32_Registry
Win32_RegistryAction
Win32_RemoveFileAction
Win32_RemoveIniAction
Win32_ReserveCost
Win32_ScheduledJob
Win32_SCSIController
Win32_SCSIControllerDevice
Win32_SecurityDescriptor
Win32_SecuritySetting
Win32_SecuritySettingAccess
Win32_SecuritySettingAuditing
Win32_SecuritySettingGroup
Win32_SecuritySettingOfLogicalFile
Win32_SecuritySettingOfLogicalShare
Win32_SecuritySettingOfObject
Win32_SecuritySettingOwner
Win32_SelfRegModuleAction
Win32_SerialPort
Win32_SerialPortConfiguration
Win32_SerialPortSetting
Win32_Service
Win32_ServiceControl
Win32_ServiceSpecification
Win32_ServiceSpecificationService
Win32_SettingCheck
Win32_Share
Win32_ShareToDirectory
Win32_ShortcutAction
Win32_ShortcutFile
Win32_ShortcutSAP
Win32_SID
Win32_SMBIOSMemory
Win32_SoftwareElement
Win32_SoftwareElementAction
Win32_SoftwareElementCheck
Win32_SoftwareElementCondition
Win32_SoftwareElementResource
Win32_SoftwareFeature
Win32_SoftwareFeatureAction
Win32_SoftwareFeatureCheck
Win32_SoftwareFeatureParent
Win32_SoftwareFeatureSoftwareElements
Win32_SoundDevice
Win32_StartupCommand
Win32_SubDirectory
Win32_SystemAccount
Win32_SystemBIOS
Win32_SystemBootConfiguration
Win32_SystemDesktop
Win32_SystemDevices
Win32_SystemDriver
Win32_SystemDriverPNPEntity
Win32_SystemEnclosure
Win32_SystemLoadOrderGroups
Win32_SystemLogicalMemoryConfiguration
Win32_SystemMemoryResource
Win32_SystemNetworkConnections
Win32_SystemOperatingSystem
Win32_SystemPartitions
Win32_SystemProcesses
Win32_SystemProgramGroups
Win32_SystemResources
Win32_SystemServices
Win32_SystemSetting
Win32_SystemSlot
Win32_SystemSystemDriver
Win32_SystemTimeZone
Win32_SystemUsers
Win32_TapeDrive
Win32_TemperatureProbe
Win32_Thread
Win32_TimeZone
Win32_Trustee
Win32_TypeLibraryAction
Win32_UninterruptiblePowerSupply
Win32_USBController
Win32_USBControllerDevice
Win32_UserAccount
Win32_UserDesktop
Win32_VideoConfiguration
Win32_VideoController
Win32_VideoSettings
Win32_VoltageProbe
Win32_WMIElementSetting
Win32_WMISetting
4. ManagementObjectSearcher 의 Get() 메소드 호출

foreach (ManagementObject share in searcher.Get())
{
// Some Codes ...

}
5. Properties 속성 사용

foreach (PropertyData PC in share.Properties)
{
 //some codes ...

}

2010. 4. 26. 22:55

어셈블리 보기: ILDASM

ILDASM 을 이용하여 어셈블리를 볼 수 있다. Visual Studio Cmd 창을 열어서 ildasm 을 입력하면 된다.


자주 활용하자.
2010. 4. 23. 07:03

Snoop: a WPF utility


UISpy 와 비슷한 툴이지만, 3D 로 보여주는 기능도 있다. 소스도 오픈되어 있음.
(http://blois.us/Snoop/)




2010. 4. 22. 23:21

WPF 와 Windows Form Control 간의 상호 운용

왜 이문제를 고민했냐면, WPF 작성한 Application 을 ActiveX Control 로 재작성해야할 필요성이 생겼다. 근데 WPF 는 ActiveX Control 을 작성하지 못하는 것 같았고(?), Windows Form Control 은 ActiveX Control 을 작성하는 방법을 이미 알고 있었다. 그래서 WPF 로 작성한 Application 을 Control 로 조금 수정하고, 이를 Windows Form 형태의 Proxy Control (WPF Control 을 hosting 함)을 만들어서 ActiveX 컨트롤로 작성하기 위해서였다. 약간 트릭이긴 하지만... 그래도 이 방법이 시간과 비용을 절약하는 최선의 방법인것 같았다.

Walkthrough: Hosting a Windows Forms Control in WPF
(
http://msdn.microsoft.com/en-us/library/ms751761.aspx)

To host the MaskedTextBox control
1.Create a WPF Application project named HostingWfInWpf.

2.In Solution Explorer, add a reference to the WindowsFormsIntegration assembly, which is named WindowsFormsIntegration.dll.

3.In Solution Explorer, add a reference to the Windows Forms assembly, which is named System.Windows.Forms.dll.

4.Open Window1.xaml in the WPF Designer.

5.Replace the automatically generated XAML in Window1.xaml with the following XAML.

<Window x:Class="HostingWfInWpf.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="HostingWfInWpf"
Loaded="WindowLoaded"
    >
    <Grid Name="grid1">

    </Grid>
</Window>

6.In the Code Editor, open Window1.xaml.cs.

7.Replace the code in Window1.xaml.cs with the following code.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using
System.Windows.Media;
using System.Windows.Shapes;

using System.Windows.Forms;

namespace HostingWfInWpf
{  
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void WindowLoaded(object sender, RoutedEventArgs e)
        {
            // Create the interop host control.
            System.Windows.Forms.Integration.WindowsFormsHost host =
                new System.Windows.Forms.Integration.WindowsFormsHost();

            // Create the MaskedTextBox control.
            MaskedTextBox mtbDate = new MaskedTextBox("00/00/0000");

            // Assign the MaskedTextBox control as the host control's child.
            host.Child = mtbDate;

            // Add the interop host control to the Grid
            // control's collection of child controls.
            this.grid1.Children.Add(host);
        }
    }
}

ElementHost Class
(http://msdn.microsoft.com/en-us/library/system.windows.forms.integration.elementhost.aspx)


A Windows Forms control that can be used to host a Windows Presentation Foundation (WPF) element. 
Use the ElementHost control to place a WPF UIElement on your Windows Forms control or form. To host a Windows Forms control in a WPF element, use the WindowsFormsHost element.

Note

WindowsFormsIntegration.dll is installed with the WPF assemblies. The default location for the assembly is %programfiles%\Reference Assemblies\Microsoft\Framework\v3.0\WindowsFormsIntegration.dll.


To host a WPF element in a Windows Form, you must assign the WPF element to the Child property.

Use the PropertyMap property to assign custom mappings between an ElementHost control and its hosted WPF element. For more information, see Windows Forms and WPF Property Mapping

private void Form1_Load(object sender, EventArgs e)
{
    // Create the ElementHost control for hosting the
    // WPF UserControl.
    ElementHost host = new ElementHost();
    host.Dock = DockStyle.Fill;

    // Create the WPF UserControl.
    HostingWpfUserControlInWf.UserControl1 uc =
        new HostingWpfUserControlInWf.UserControl1();

    // Assign the WPF UserControl to the ElementHost control's
    // Child property.
    host.Child = uc;

    // Add the ElementHost control to the form's
    // collection of child controls.
    this.Controls.Add(host);
}


참고: Walkthrough: Hosting a WPF Control in Windows Forms (내용이 좀 길다)
(
http://msdn.microsoft.com/en-us/library/ms742215.aspx)

2010. 4. 21. 23:16

How to register .NET components with COM

Building the project on a development machine

  • Use: On a development machine
 
When you want to register an assembly for COM interop on a development machine, the simplest way is to open the project in Visual Studio 2005, ensure the project-level Register for COM Interop property is set to true, then build the project.
 
To check a project's settings, click Project Properties from the Project menu, select the Build (C#) or Compile (VB.NET) page, and select the Register for COM Interop check box.
 

Registering by command, using the Regasm utility

  • Use: When testing on a different machine and you do not have an installation program
 
Sometimes you may want to register an assembly for COM interop without building the project; for example, when first testing your component or if you do not have access to the assemblies source code.
 
In this case, you can use the assembly registration utility Regasm that ships with the .NET Framework Software Development Kit (SDK) or Visual Studio 2005. Regasm will add entries to the registry, which allows a COM (unmanaged) application to consume .NET classes via COM interop.
 
Machines with either Visual Studio 2005 or the freely available .NET Framework SDK will have this utility installed and other machines may not; therefore. this is not a viable solution for general deployment of your components.
 
Using the Regasm command line utility
To use the Regasm command line utility:
  • If the target machine has Visual Studio installed, open the Visual Studio 2005 command prompt (the ordinary command prompt will not have the appropriate environment variables set to use this tool).
  • If the target machine does not have Visual Studio installed but does have the .NET Framework SDK installed, use the SDK command prompt by choosing Programs, then Microsoft .NET Framework SDK v2.0. If you cannot find it, open a command prompt at the path where Regasm is located. For example, the .NET Framework 2.0 default installation path is C:\Windows\Microsoft.NET\Framework\v2.0.50727.
 
The following example shows the command used to register the assembly called EditTools with COM. The full path to the assembly should be given unless the current directory of the command prompt is the directory where the assembly is located:
 
regasm EditTools.dll /codebase
 
The /codebase parameter is an optional parameter that adds information to the registry specifying the path on disk of the assembly. If the component is not to be deployed to the global assembly cache (GAC), then this option will be required for ArcGIS to find your component successfully; if the component is installed to the GAC, the option is not required. Regasm has many other options; for a full list, type regasm /? or refer to Microsoft Developer Network (MSDN).
 
Regasm can also be used to unregister assemblies from COM interop, as shown in the following example:
 
regasm EditTools.dll /unregister 
 

Using an installation program

  • Use: When deploying to your user
 
Finally, you can create an installation program, which will deploy your component and add to the installation program an automatic registration step that will register your component for COM interop.
 
You can create installation programs by using either third-party installation software or using a Visual Studio Setup Project. For an example of how to create a setup project for a component using WISE, see How to deploy an application.
 

Type libraries for managed components


A type library (.tlb) can also be exported that contains information describing the types in the assembly. You may want to generate a type library for a component if that component will be used from another development environment, such as within the Visual Basic for Applications (VBA) environment embedded with the ArcGIS applications. If you want to add custom commands and tools using the Customize dialog box within the ArcGIS applications, you need to generate a type library.
 
Visual Studio will generate this .tlb automatically if you have checked the Register for COM Interop setting. If you do not have a .tlb for an existing component, one can be generated by using the Regasm utility and the /tlb option. See the following:
 
2010. 4. 1. 00:46

AutoDual ClassInterfaceType을 사용하지 마십시오


이중 인터페이스를 사용하는 형식에서는 클라이언트가 특정 인터페이스 레이아웃에 바인딩할 수 있습니다. 이후 버전에서 해당 형식이나 기본 형식의 레이아웃이 변경되면 인터페이스에 바인딩된 COM 클라이언트의 바인딩이 해제될 수 있습니다. 기본적으로 ClassInterfaceAttribute 특성이 지정되어 있지 않으면 디스패치 전용 인터페이스가 사용됩니다.

따로 표시되지 않은 경우 제네릭이 아닌 모든 public 형식은 COM에서 볼 수 있으며 public이 아닌 모든 제네릭 형식은 COM에서 볼 수 없습니다.

이 규칙 위반 문제를 해결하려면 ClassInterfaceAttribute 특성의 값을 None으 로 변경하고 인터페이스를 명시적으로 정의합니다.

다음 예제에서는 이 규칙을 위반하는 클래스와 명시적 인터페이스를 사용하도록 클래스를 다시 선언하는 방법을 보여 줍니다.

 
using System;
using System.Runtime.InteropServices;

[assembly: ComVisible(true)]
namespace InteroperabilityLibrary
{
   // This violates the rule.
   [ClassInterface(ClassInterfaceType.AutoDual)]
   public class DualInterface
   {
      public void SomeMethod() {}
   }

   public interface IExplicitInterface
   {
      void SomeMethod();
   }

   [ClassInterface(ClassInterfaceType.None)]
   public class ExplicitInterface : IExplicitInterface
   {
      public void SomeMethod() {}
   }
}

출처 : http://msdn.microsoft.com/ko-kr/library/ms182205.aspx

2010. 4. 1. 00:19

Writing an ActiveX Control in .NET

2010. 3. 26. 01:13

C# Delegate 사용하기

Delegate 도 클래스와 마찬가지로 두가지 단계를 거친다.

1. Delegate 정의 (변수 선언이 아님을 주의하자!)

delegate void VoidOperation(uint x);
delegate double TwoLongsOp(long L1, long L2);
delegate string GetAsString();
public delegate string GetAsString();

2. Delegate의 인스턴스 생성

 static void Main(string[] args)
{
    int X = 40;
    GetAsString FirstStringMethod = new GetAsString(X.ToString);  // 메소드를 파라미터로 전달
    Console.WriteLine("String is" + FirstStringMethod());
}

  • Delegate 는 형식 안전하므로 호출되는 메소드의 signature 가 제대로 되었다는 것이 보장된다.
  • 메소드가 정적 메소드 혹은 인스턴스 메소드인지 신경쓰지 않는다.
3. Multicast Delegate

+, -, -=, += 의 연산자를 이용하여 Delegate 를 추가/삭제 할 수 있으며, void 형으로 선언한다.

delegate void DoubleOp(double value);

class MathOperations
{
    public static void MultiplyByTwo(double value)
    {
        double result = value*2;
        Console.WriteLine("Multiplying by 2: {0} gives {1}", value, result);
    }

    public static void Squre(double value)
    {
        double result = value*value;
        Console.WriteLine("Squaring: {0} gives {1}", value, result);
    }
}
static void Main(string[] args)
{
    DoubleOp operations = new DoubleOp(MathOperations.MultiplyByTwo);
    operations += new DoubleOp(MathOperations.Square);

    ProcessAndDisplayNumber(operations, 2.0);
    ProcessAndDisplayNumber(operations, 7.94);
    Console.WriteLine();
}

참고 : Professional C# - 정보 문화사
2010. 3. 25. 05:28

A Simple C# Global Low Level Keyboard Hook

UISpy 비슷한 App 을 개발하는 중에 Control 키를 전역후킹할 필요가 있었다. 그래서 Code Project 에 있는 샘플을 활용하여 개발하였다.

아래는 샘플 App 이미지와 Control 키 후킹을 테스트 해본 코드. 원본은 아래에 링크를 걸어 두었다.




http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx