반응형

* C# WMI 를 이용한 USB 연결 및 연결해제 예제...

- WMI 를 사용하기 위해 참조 -> System.Management dll 을 추가 -> 소스 코드 using System.Management


Main

 

- 사용한 컨트롤 : ListView 1개, Button 2개

 

전체 소스 코드

Form1.cs

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Management;


namespace CSharp_WMI_USB_Detect
{
    public partial class Form1 : Form
    {
        ManagementEventWatcher mewWatcher;
        string strUSBDriveName;
        string strUSBDriveLetter;
        int iCount = 0;

        public Form1()
        {
            InitializeComponent();
            //크로스 스레드 
            CheckForIllegalCrossThreadCalls = false;
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);

            if (mewWatcher != null)
            {
                mewWatcher.Stop();
                mewWatcher.Dispose();
            }

        }

        void mewWatcher_EventArrived(object sender, System.Management.EventArrivedEventArgs e)
        {
            ManagementBaseObject mbo1;
            ManagementBaseObject mbo2;

            mbo1 = e.NewEvent as ManagementBaseObject;
            mbo2 = mbo1["TargetInstance"] as ManagementBaseObject;

            switch (mbo1.ClassPath.ClassName)
            {
                case "__InstanceCreationEvent":
                {
                    if (mbo2["InterfaceType"].ToString() == "USB")
                    {
                        strUSBDriveName = mbo2["Caption"].ToString();
                        strUSBDriveLetter = mbo2["Name"].ToString();

                        ListViewItem lvi = new ListViewItem();
                        lvi.Text = (iCount + 1).ToString();
                        lvi.SubItems.Add(strUSBDriveName + " : " + strUSBDriveLetter + " 연결 되었습니다.");

                        listView1.Items.Add(lvi);
                        iCount += 1;
                    }

                    break;
                }
                case "__InstanceDeletionEvent":
                {
                    if (mbo2["InterfaceType"].ToString() == "USB")
                    {
                        if (mbo2["Caption"].ToString() == strUSBDriveName)
                        {
                            ListViewItem lvi = new ListViewItem();
                            lvi.Text = (iCount + 1).ToString();
                            lvi.SubItems.Add(strUSBDriveName + " : " + strUSBDriveLetter + " 해제 되었습니다.");

                            listView1.Items.Add(lvi);
                            iCount += 1;

                            strUSBDriveLetter = "";
                            strUSBDriveName = "";
                        }
                    }

                    break;
                }
            }

            this.Refresh();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //start
            //ManageMentEventWatcher 가 null 이면 생성...
            if (mewWatcher == null) mewWatcher = new ManagementEventWatcher();

            WqlEventQuery weQuery = new WqlEventQuery("SELECT * FROM __InstanceOperationEvent WITHIN 1 " + "WHERE TargetInstance ISA 'Win32_DiskDrive'");
            mewWatcher.Query = weQuery;
            //Event Create
            mewWatcher.EventArrived += new EventArrivedEventHandler(mewWatcher_EventArrived);
            mewWatcher.Start();

        }

        private void button2_Click(object sender, EventArgs e)
        {
            //stop
            mewWatcher.Stop();
            mewWatcher.Dispose();
        }
    }
}

 

위 구문에서 보듯이 CheckfoCheckForIllegalCrossThreadCalls 를 사용 (크로스 스레드 예제 https://kdsoft-zeros.tistory.com/22 참조)

 

- 아래 클래스에 붉은색 표시 -> 소스코드에 사용한 필드 !!

 

[Dynamic, Provider("CIMWin32"), UUID("{8502C4B2-5FBB-11D2-AAC1-006008C78BC7}"), AMENDMENT]
class Win32_DiskDrive : CIM_DiskDrive
{
  uint16   Availability;
  uint32   BytesPerSector;
  uint16   Capabilities[];
  string   CapabilityDescriptions[];
  string   Caption;
  string   CompressionMethod;
  uint32   ConfigManagerErrorCode;
  boolean  ConfigManagerUserConfig;
  string   CreationClassName;
  uint64   DefaultBlockSize;
  string   Description;
  string   DeviceID;
  boolean  ErrorCleared;
  string   ErrorDescription;
  string   ErrorMethodology;
  string   FirmwareRevision;
  uint32   Index;
  datetime InstallDate;
  string   InterfaceType;
  uint32   LastErrorCode;
  string   Manufacturer;
  uint64   MaxBlockSize;
  uint64   MaxMediaSize;
  boolean  MediaLoaded;
  string   MediaType;
  uint64   MinBlockSize;
  string   Model;
  string   Name;
  boolean  NeedsCleaning;
  uint32   NumberOfMediaSupported;
  uint32   Partitions;
  string   PNPDeviceID;
  uint16   PowerManagementCapabilities[];
  boolean  PowerManagementSupported;
  uint32   SCSIBus;
  uint16   SCSILogicalUnit;
  uint16   SCSIPort;
  uint16   SCSITargetId;
  uint32   SectorsPerTrack;
  string   SerialNumber;
  uint32   Signature;
  uint64   Size;
  string   Status;
  uint16   StatusInfo;
  string   SystemCreationClassName;
  string   SystemName;
  uint64   TotalCylinders;
  uint32   TotalHeads;
  uint64   TotalSectors;
  uint64   TotalTracks;
  uint32   TracksPerCylinder;
};

 

 

*예제 결과

 

- 연결된 모습

 

-연결 해제된 모습

 

* 참조 (마이크로소프트)

https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-diskdrive

 

Win32_DiskDrive class - Win32 apps

Win32_DiskDrive class In this article --> The Win32_DiskDrive WMI class represents a physical disk drive as seen by a computer running the Windows operating system. The following syntax is simplified from Managed Object Format (MOF) code and includes all o

docs.microsoft.com

 

https://kdsoft-zeros.tistory.com/182

 

[VBNET] [WMI] USB Detect 예제

* VBNET WMI 를 이용한 USB 연결 및 연결해제 예제... - WMI 를 사용하기 위해 참조 -> System.Management dll 을 추가 -> 소스 코드 Imports System.Management - 사용한 컨트롤 : ListView 1개, Button 2개 전..

kdsoft-zeros.tistory.com

 

반응형
반응형

* C# WMI 를 이용한 CPU 클럭 속도 가져오기 예제...

 

- WMI 를 사용하기 위해 참조 -> System.Management dll 을 추가 -> 소스 코드 using System.Management

 

Main

- 사용 컨트롤 : Label 1개, Button 1개

 

전체 소스 코드

Form1.cs

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Management;

namespace CSharp_WMICpuSpeed
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        private void button1_Click(object sender, EventArgs e)
        {

            using (ManagementObject managementObject = new ManagementObject("Win32_Processor.DeviceID='CPU0'"))
            {
                uint ispeed = (uint)(managementObject["CurrentClockSpeed"]);
                lbl0 .Text = ispeed.ToString();
            }

        }
    }

}

 

*예제 결과

 

 

단위는 메가 헤르츠 이며 내컴퓨터 속성에서 보듯이 값이 똑같다는 걸 볼 수 있습니다.

 

*참조 문서 (마이크로소프트)

https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-processor

 

Win32_Processor class - Win32 apps

Win32_Processor class In this article --> The Win32_Processor WMI class represents a device that can interpret a sequence of instructions on a computer running on a Windows operating system. The following syntax is simplified from Managed Object Format (MO

docs.microsoft.com

 

https://kdsoft-zeros.tistory.com/180

 

[VBNET] [WMI] CPU 클럭 속도 (CurrentClockSpeed)

* VBNET WMI 를 이용한 CPU 클럭 속도 가져오기 예제... - WMI 를 사용하기 위해 참조 -> System.Management dll 을 추가 -> 소스 코드 imports System.Management - 사용 컨트롤 : Label 1개, Button 1개 전체..

kdsoft-zeros.tistory.com

 

반응형
반응형

* C# 파일 비교  (File Compare) 예제...

 

Main

- 사용한 컨트롤 : Label 5개 , Button 3개 , GroupBox 1개

 

전체 소스 코드

Form1.cs

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CSharp_FileCompare
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //원본 파일 선택...
            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                lblSource.Text = ofd.FileName;
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            //대상 파일 선택...
            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                lblDesc.Text = ofd.FileName;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //File Compare
            int iFile1byte;
            int iFile2byte;
            System.IO.FileStream fs1;
            System.IO.FileStream fs2;

            //파일 위치 및 이름이 같으면...
            if (lblSource.Text == lblDesc.Text)
            {
                lblCompare.Text = "같은 파일 입니다.";
                return;
            }

            // Open the two files.
            fs1 = new System.IO.FileStream(lblSource.Text, System.IO.FileMode.Open);
            fs2 = new System.IO.FileStream(lblDesc.Text, System.IO.FileMode.Open);

            //파일 길이 비교...
            if (fs1.Length != fs2.Length)
            {
                // Close the file
                fs1.Close();
                fs2.Close();

                // Return false to indicate files are different
                lblCompare.Text = "다른 파일 입니다.";
                return ;
            }

            do
            {
                // Read one byte from each file.
                iFile1byte = fs1.ReadByte();
                iFile2byte = fs2.ReadByte();
            }
            while ((iFile1byte == iFile2byte) && (iFile1byte != -1));

            // Close the files.
            fs1.Close();
            fs2.Close();

            if ((iFile1byte - iFile2byte) == 0)
            {
                lblCompare.Text = "같은 파일 입니다.";
            }

        }
    }
}

 

 

*예제 결과

 

- 길이 및 읽은 바이트 수가 같으면...

 

 

- 파일 위치 및 이름이 같으면...

 

 

- 파일 길이 및 이름, 읽은 바이트 수가 다르면...

 

 

https://kdsoft-zeros.tistory.com/178

 

[VBNET] 파일 비교 (File Compare)

* VBNET 파일 비교 (File Compare) 예제... - 사용한 컨트롤 : Label 5개 , Button 3개 , GroupBox 1개 전체 소스 코드 Form1.vb Public Class Form1 Private Sub button1_Click(ByVal sender As System.Object,..

kdsoft-zeros.tistory.com

 

반응형
반응형

* C# DateTime Format yyyy-MM-dd HH:mm:ss - 전역 설정 예제...

 

Main

 

전체 소스 코드

Form1.cs

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Globalization;
using System.Threading;

namespace CSharp_GlobalDateTimeFormat
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //전역 설정...
            CultureInfo cti = CultureInfo.CurrentCulture.Clone() as CultureInfo ;
            cti.DateTimeFormat.LongDatePattern = "yyyy-MM-dd";
            cti.DateTimeFormat.LongTimePattern = "HH:mm:ss";
            cti.DateTimeFormat.ShortDatePattern = "yyyy-MM-dd";
            cti.DateTimeFormat.ShortTimePattern = "HH:mm:ss";
            System.Threading.Thread.CurrentThread.CurrentCulture = cti;
            System.Threading.Thread.CurrentThread.CurrentUICulture = cti;

        }

        private void button1_Click(object sender, EventArgs e)
        {
            //전역 설정 했을 경우 2020-03-19 21:47:54 로 나타남.
            //하지 않았을 경우 2020-03-19 오후 9:47:54.
            label1.Text = DateTime.Now.ToString();
            //label1.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }
    }
}

 

 

*예제 결과

 

반응형
반응형

*C# 레지스트리를 이용한 설치된 닷넷프레임워크 버전 리스트 조회 예제...

 

Main

 

전체 소스 코드

Form1.cs

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Microsoft.Win32;

namespace CSharp_InstallFrameworkList
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            listView1.Items.Clear();

            using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
            {
                int iCount=0;
                string strNET="";

                //하위 레지스트리 검색
                foreach(string strRegName in rk.GetSubKeyNames())
                {
                    ListViewItem lvi = new ListViewItem();

                    //문자열이 v로 시작 하면...
                    if(strRegName .StartsWith("v"))
                    {
                        //하위 레지스트리 열기...
                        using (RegistryKey versionKey = rk.OpenSubKey(strRegName))
                        {
                            // Get the .NET Framework version value.
                            string strVersion = (string)versionKey.GetValue("Version", "");

                            //strVersion 이 null 이거나 빈값이면...
                            if (string.IsNullOrEmpty(strVersion))
                            {
                                //하위 레지스트리 검색...
                                foreach (string strSubKey in versionKey.GetSubKeyNames())
                                {
                                    //하위 레지스트리 열기...
                                    using (RegistryKey rkSub = versionKey.OpenSubKey(strSubKey))
                                    {
                                        //하위 레지스트리에 Version 값 얻어오기...
                                        string strVer = (string)rkSub.GetValue("Version", "");
                                        strNET = strVer;
                                    }
                                }
                            }
                            else
                            {
                                strNET = strVersion;
                            }
                        }

                        //Listview Display
                        lvi.Text = (iCount +1) .ToString();
                        lvi.SubItems.Add(strNET);
                        listView1.Items.Add(lvi);
                       iCount +=1;

                    }//if

                }//foreach
            }//using

        }//button1_Click

    }
}

 

 

설치된 닷넷 프레임워크 버전들 위치는 아래와 같습니다.

 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP

레지스트리 에디터 열기

윈도우 시작 -> 실행 -> regiedit 입력

 

아래의 그림은 레지스트리 에디터를 열고 위치를 직접 찾아가 본 모습입니다. 

NDP 안에 여러개의 v 로 시작 되면서 닷넷프레임워크 버전들이 존재 하고 있는 모습을 볼 수 있습니다.

 

 

*예제 결과

 

 

* 참조 문서 : https://docs.microsoft.com/ko-kr/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed

 

설치된 .NET Framework 버전 확인

코드, regedit.exe 또는 PowerShell을 사용하여 Windows 레지스트리를 쿼리하는 방법으로 컴퓨터에 설치된 .NET Framework 버전을 검색합니다.

docs.microsoft.com

 

https://kdsoft-zeros.tistory.com/173

 

[VBNET] 설치된 닷넷프레임워크 버전 리스트 조회

* VBNET 설치된 닷넷프레임워크(NET Framework) 리스트 조회 예제... 전체 소스 코드 Form1.vb Imports Microsoft.Win32 Public Class Form1 Private Sub button1_Click(ByVal sender As System.Object, ByVal e..

kdsoft-zeros.tistory.com

 

반응형
반응형

* C# API 를 이용한 제어판 기본 프린터(Default Printer) 변경 예제...

 

Main

 

전체 소스 코드

Form1.cs

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Drawing.Printing;
using System.Runtime.InteropServices;

namespace CSharp_PrinterList
{
    public partial class Form1 : Form
    {
        [DllImport("winspool.drv")]
        static extern bool SetDefaultPrinter(string name);


        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //프린터 목록 콜렉션 배열에 담기...
            System.Collections.ArrayList alList = new System.Collections.ArrayList(
                PrinterSettings.InstalledPrinters);

            //정렬
            alList.Sort();
            //리스트뷰 아이템 초기화
            listView1.Items.Clear();

            for (int iCount = 0; iCount < alList.Count; iCount++)
            {
                //프린터 목록 리스트 보여주기...
                ListViewItem lvi = new ListViewItem();
                lvi.Text = (iCount + 1).ToString();
                lvi.SubItems.Add(alList[iCount].ToString());

                //리스트뷰 아이템에 추가...
                listView1.Items.Add(lvi);
            }

        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            //Select Printer
            lblSelectPrinter.Text = listView1.FocusedItem.SubItems[1].Text;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //Default Printer Set
            if (lblSelectPrinter.Text == "") return;

            if (SetDefaultPrinter(lblSelectPrinter.Text))
            {
                MessageBox.Show("Default Printer Set Success...", "확 인", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
            }
            else
            {
                MessageBox.Show("Default Printer Set Failed...", "확 인", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
    }
}

 

* 예제 결과

 

 

위 그림은 기본 프린터 변경 전 모습으로 윈도우 시작 -> 제어판 -> 장치 및 프린터 로 가보게 되면 기본 프린터가 NesPDF 로 되어 있습니다. 

 

해당 리스트뷰에서 기본 프린터로 지정될 항목을 클릭 한 뒤 Default Printer Set 버튼을 클릭 하여 아래의 그림과 같이

변경 

 

https://kdsoft-zeros.tistory.com/166

 

[C#] 제어판 프린터(Printer) 목록 불러오기

* C# 제어판 프린터 (Printer) 목록 불러오기 예제... 전체 소스 코드 Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; usin..

kdsoft-zeros.tistory.com

 

https://kdsoft-zeros.tistory.com/171

 

[VBNET] [API] 제어판 기본 프린터(Default Printer) 변경

* VBNET API 이용한 제어판 기본 프린터 (Default Printer) 변경 하기 예제... 전체 소스 코드 Form1.vb Imports System.Collections Imports System.Drawing.Printing Public Class Form1 'API Declare Function..

kdsoft-zeros.tistory.com

 

반응형
반응형

*C# WMI 를 이용한 실시간 메모리 사용량 체크 (Memory Check) 예제...

- WMI 를 사용하기 위해 참조 -> System.Management dll 을 추가 -> 소스 코드 using System.Management

 

Main

 

전체 소스 코드

Form1.cs

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Management; 

namespace CSharp_WMIMemory
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Start
            timer1.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //Stop
            timer1.Stop();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            int itotalMem = 0;		// 총 메모리 KB 단위
            int itotalMemMB = 0;	    // 총 메모리 MB 단위
            int ifreeMem = 0;		// 사용 가능 메모리 KB 단위
            int ifreeMemMB = 0;	    // 사용 가능 메모리 MB 단위

            ManagementClass cls = new ManagementClass("Win32_OperatingSystem");
            ManagementObjectCollection moc = cls.GetInstances();

            foreach (ManagementObject mo in moc)
            {
                itotalMem = int.Parse(mo["TotalVisibleMemorySize"].ToString());
                ifreeMem = int.Parse(mo["FreePhysicalMemory"].ToString());
            }

            itotalMemMB = itotalMem / 1024;	// 총 메모리 MB 단위 변경	
            ifreeMemMB = ifreeMem / 1024;	// 사용 가능 메모리 MB 단위 변경

            //Progressbar Max Setting...
            pbTotal.Maximum = itotalMemMB;
            pbFree.Maximum = itotalMemMB;
            pbUse.Maximum = itotalMemMB;

            //Label Display
            lblTotal.Text = itotalMemMB.ToString();
            lblFree.Text = ifreeMemMB.ToString();
            lblUse.Text = (itotalMemMB - ifreeMemMB).ToString();

            //Progressbar Display
            pbTotal.Value = itotalMemMB;
            pbFree.Value = ifreeMemMB;
            pbUse.Value = (itotalMemMB - ifreeMemMB);

        }

    }
}

 

 

*예제 결과

 

아래의 그림과 같이 NoxPlayer 를 켜고 난 뒤 게임을 실행 하면서 메모리 사용량이 변화 하는 것을 WMI 를 이용한

프로그램과 작업관리자 화면 을 동시에 비교 해 봤을 때 변화 하는 것을 볼 수 있습니다. 물론 단위가 작업관리자는 GB 로 나오고 WMI 를 이용해 만든 프로그램은 MB 이지만 1024를 한번 더 나누게 되면 단위는 GB 가 됩니다.

 

또한 소스 코드는 int 형 변수로 구현 했지만  Double 형 변수를 써서 구현 하게 되시면 작업 관리자 화면 처럼 소수점 2번째 자리 까지 표현 하면서 나타낼 수 있습니다.

 

 

 

 

https://kdsoft-zeros.tistory.com/169

 

[VBNET] [WMI] 실시간 메모리 사용량 체크 (Memory Check) - Progressbar

*VBNET WMI 를 이용한 실시간 메모리 사용량 체크 (Memory Check) 예제... - WMI 를 사용하기 위해 참조 -> System.Management dll 을 추가 -> 소스 코드 Imports System.Management 전체 소스 코드 Form1.vb Imp..

kdsoft-zeros.tistory.com

 

반응형
반응형

* C# 제어판 프린터 (Printer) 목록 불러오기 예제...

 

Main

 

전체 소스 코드

Form1.cs

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Drawing.Printing;

namespace CSharp_PrinterList
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //프린터 목록 콜렉션 배열에 담기...
            System.Collections.ArrayList alList = new System.Collections.ArrayList(
                PrinterSettings.InstalledPrinters);

            //정렬
            alList.Sort();
            //리스트뷰 아이템 초기화
            listView1.Items.Clear();

            for (int iCount = 0; iCount < alList.Count; iCount++)
            {
                //프린터 목록 리스트 보여주기...
                ListViewItem lvi = new ListViewItem();
                lvi.Text = (iCount + 1).ToString();
                lvi.SubItems.Add(alList[iCount].ToString());

                //리스트뷰 아이템에 추가...
                listView1.Items.Add(lvi);
            }

        }
    }
}

 

*예제 결과

 

결과 화면

 

https://kdsoft-zeros.tistory.com/167

 

[VBNET] 제어판 프린터(Printer) 목록 불러오기

* VBNET 제어판 프린터 목록 불러 오기 예제... 전체 소스 코드 Form1.vb Imports System.Collections Imports System.Drawing.Printing Public Class Form1 Private Sub button1_Click(ByVal sender As System.O..

kdsoft-zeros.tistory.com

 

반응형

+ Recent posts