Visual Studio 2010 hdd veya cpu numaralarını öğrenmek ??

Başlatan EMG81, 27 Aralık 2010, 23:56:29

EMG81

Yanıtınız için teşekkür ederim Kudret bey. Sanırım elinizde bahsettiğiniz kitap mevcut. Şayet böyle ise sizden ricam kitap index inden HDD veya CPU nosu öğrenme ile ilgili bir başlık olup olmadığına bakarmısınız ?

iyildirim

http://www.codeproject.com/KB/system/GetHardwareInformation.aspx
Ekteki örnek oldukça detaylı bilgi veriyor. c#,  ama bir translator ile vb ye çevrilebilir.


lojikmemo1

API değil de WMI diye bişi var bunun içinde isteğnizden fazlası olacaktı..
İnsanlara Akılları Ölçüsünde Söz Söyleyiniz.

EMG81

Visual Studio da çok yeniyim... O nedenle WMI yı biraz açabilirmisiniz ?

lojikmemo1

Bu makalede...

WMI (Windows Management Instrumentation) Microsoft Windows işletim sistemlerinde var olan en önemli yapılardan biridir. WMI, en temel kullanımı ile, sistemin sorgulanmasına ve sistem temel operasyonların programatik olarak yönetilmesine yardımcı olabilecek ama yetenekleri de sadece bunlarla sınırlı olmayan bir yapı sunmaktadır. Bu makale ve ekte sunacağım örneklerde basit bir konu seçerek, local makine ve bağlı bulunduğu network (Active Directory yapısı) üzerinden aynı ağdaki farklı bir makinede çalışan process'lerin listesine nasıl ulaşılacağı ve hatta yetkili kullanıcı olunması halinde bu process'lerin nasıl öldürüleceğini anlatmaya çalıştım, tabii bütün bunları .NET Framework 2.0 üzerinde C# ve WMI kullanarak yapmaya çalıştım.


çok güçlü bir namespace; System.Management

Genelde programcılar ve yazılım mimarları tarafından çoğu projede gözardı edilebilen bu güçlü namespace adından da anlaşılacağı gibi sistemin durumu, logları, başarımı ve yönetilmesi ile ilgili temel sınıfları içeren bir kütüphane olarak düşünülebilir. Ama dikkat edilecek husus bu namespace'in yetkinliklerinin System.Diagnostics namespace' i içerisindeki sınıflarla karıştırılmamasıdır. O, apayrı bir konudur ve burada biz Diagnostics namespace' i ile ilgilenmiyor olacağız.

System.Management namespace' i içerisindeki en önemli sınıflardan biri kuşkusuz ManagementObject sınıfıdır. (Tam adı ile System.Management.ManagementObject). Bu nesnenin detaylı bir incelenmesi çabasına girmeden once bu sınıfın, ICloneable interface' ini implement ettiğine dikkatinizi çekmek isterim. ICloneable interface' ini daha önce kullanmış olanlar bilirler, bu interface' i implement eden sınıflar sanki birer value type' mış gibi kopyalanabilirler ki bu bir nesnenin referansının değil ama değerlerinin farklı fonksiyonlar, sınıflar ve yeri geldiğinde Application Domain' ler arasında transfer edilebilmesine imkan tanır. Bu işlemler ise dağıtık uygulamalar konusu ile ilgili olup bu makalenin ilgi alanı dışındadır. Fakat son olarak, ilgilenenler için, söz konusu sınıfın ISerializable interface' ini implement ettiğini de belirtelim, yani bu nesne Serialize edilebilen bir nesnedir ve serialize ederek anlık state' ini bir stream üzerinde saklmak mümkündür.

Dikkat edilecek yegane husus ise, ManagementObject sınıfı yönetim için bir taban sınıfı deklare ettiğinden (esasında bunu taban sınıfı da ManagementObjectBase sınıfıdır), tüm yönetimsel işlemlerin kalbi denilebilecek kadar önem taşımasıdır. Başka bir değişle ManagementObject sınıfı kullanılarak işlemler yürütülmektedir.

Bunun yanı sıra WMI sistemi bir ağaç yapısına sahiptir. Bunun anlamı sistemin neresine erişilmek isteniyorsa orayı gösteren bir path vasıtası ile gerekli işlemler ve sorgular çalıştırılmalıdır. Nasıl Windows dizinindeki sample.txt adlı bir dosyayı silmek için c:\Windows\ dizini kullanılacaksa, WMI path' leri de ulaşılmak istenilen yönetimsel aracın yolunu belirtecek şekilde düzenlenmelidir. Aşağıdaki satırda local makine üzerindeki process bilgileri için kullanacağımız path örnek olarak verilmiştir. Buradaki path kavramını namespace kavramı gibi de düşünmek mümkündür ve esasında hiçbir farkı yoktur.

\\localhost\root\cimv2

Bir diğer temel öğe ise WMI işlemlerinin, daha doğrusu sorgularının alışılagelmiş SQL sorguları ile yapısal olarak aynı sözdizimi ve anahtar kelimleri kullandığıdır. Tabii ki, bir yazılım sisteminin öğeleri tablolar olmadığından tabloların yerlerini özel nesnelerin isimleri almaktadır. Örneğin sistemdeki tüm process' lerin tüm özelliklerini sorgulamak için aşağıda verilen sorgu cümleciği kullanılabilir:

SELECT * FROM Win32_Process

Bu sorgunun klasik bir SQL sorgusuna ne kadar benzediği kuşkusuz kullanıcının dikkatini çekecetir. Dolayısı ile, şu ana kadar, WMI path ile ulaşcağımız bilginin yerini, SQL benzeri sorgu ile de bu yerden istediğimiz bilgiyi alabileceğimiz gösterilmiştir.


En Temel bilgiler...

Yukarıda anlatılanların ışığında bize bazı temel bilgiler gerekeceği gözükmektedir:

1. Process' leri hangi path (namespace) üzerinden arayacağız (ulaşacağız)
2. Bütün bunları uzak bir makine üzerinde nasıl yapacağız.

İlk sorunun cevabı oldukça kolay. Konu ile ilgili daha detaylı bilgiye MSDN üzerinden ulaşabilirsiniz. Bizim örnek uygulamamızda kullanacağımız CIMV2 adlı namespace, local Windows sistemi üzerinde sorgu ve işlemleri yapabileceğimiz bir sınıflar kümesi barındırmaktadır. Dolayısı ile erişmek istediğimiz alan "\\<Makine_Adı>\root\cimv2" olarak kullanılacaktır. Bir diğer soru sisteme bunu nasıl anlatabiliriz?

İşte bu noktada System.Management.MangementScope adlı bir sınıf imdadımıza yetişmektedir. Yapılacak işlemlerin hangi sınıf kümesi (namespace ya da path olarak da düşünebilirsiniz) üzerinde yapılacağını bu sınıfı kullanarak belirtebiliriz. Örneğin:

ManagementScope scope = new ManagementScope(@"\\localhost\root\cimv2");

Yukarıdaki tanımlama "scope" olarak localhost adlı makine üzerinde root\cimv2 kümesinin elamanlarının kullanılacağını belirtmektedir.

Bir diğer soru işareti ise olası bir durumda, mesela uzaktaki bir makineye bağlanılması, kullanıcı bilgilerinin diğer makineye nasıl aktarılacağı olabilir. Varsayılan değer olarak aktif olarak sistemde bulunan kullanıcı bilgilerinin ve kısıtlarının ışığında karşı tarafa bu bilgilerin gittiğini yani logon olmuş kullanıcının kimlik bilgileri (credentials) ile uzak makinede oturum açmaya çalıştığını çoğumuz zaten biliyoruz. Örneğin ben çalıştığım domain üzerinde Administrator yetkilerim olmasına karşılık Domain Admin yetkisi olmayan farklı bir kullanıcı ile sisteme logon olmayı terchi ediyorum. Dolayısı ile uzak makinede bir işlem yapmak istediğimde Domain Admin şapkamı takmalı ve o şapka altında işlerimi yürütmeliyim. İşte böyle bir durumda da System.Management.ConnectionOptions sınıfı oldukça kullanışlı olmaktadır. İsminden de anlaşılacağı üzere herhangi bir bağlantı esnasında kullanmak istediğiniz ayarları bu sınıf ile sisteme bildirebilirsiniz. Örneğin:

ConnectionOptions options = new ConnectionOptions();
options.Impersonation = ImpersonationLevel.Impersonate;
options.Username = "<domain_name>\\<user_name>";
options.Password = "<password>";

Burada en önemli property muhtemelen Impersonation olacaktır. Impersonation işlemi kullanıcı bilgilerinin varolan application domain sınırlarından başka application domainlere ulaştırılarak farklı uygulamalar arasında kimlik paylaştırılması olarak düşünülebilir. Impersonation.Impersonate enumeration değeri ise söz konusu olan bağlantı ayarlarının impersonate edileceğini, yani uzaktaki sisteme bağlanılırken verilen kullanıcı adı ve şifresinin kullanılarak bağlanılacağını bildirmektedir.

Şimdi yukarıdaki ManagementScope ile ConnectionScope sınıflarını birleştirmek istersek:


ConnectionOptions options = new ConnectionOptions();
options.Impersonation = ImpersonationLevel.
options.Impersonation = ImpersonationLevel.Impersonate;
options.Username = "domain\\user";
options.Password = "SomePassword";

ManagementScope scope = null;
scope = new ManagementScope("\\ComputerName\root\cimv2", options);

Bu kod parçacığı ComputerName adlı sisteme, verilen kimlik bilgileri ile bağlanarak, o sistemdeki \root\cimv2 WMI namespace' ine ulaşmak amacı ile kullanılacak olan scope adlı bir değişken tanıtmaktadır.

Tüm örnek koda göz atmadan önce son olarak iki sınıftan daha bahsetmek yerinde olur. Bunlar da sırası ile ObjectQuery ve ManagementObjectSearcher sınıflarıdır. Yüzeysel olarak bu sınıfların işlevlerine de değinmek gerekirse; ObjectQuery sınıfı ManagementObject'leri içerisinden arama yapmak yani bir sorgu çalıştırmak için gerekli olan komutu içeren bir yapı tanımlar. Bunu sınıfı ADO.net kütüphaneleri içerisinde bulunan Command sınıflarına benzetebiliriz.

ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Process");

Yukarıdaki bu tanımlama verilen sorgu cümlesini içeren bir sorgu nesnesi yaratmamızı sağlamaktadır. Bu sorgular klasik SQL cümleleri gibi WHERE koşulu da içerebilir. Bir başka örnek;

ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Process WHERE ProcessID = '1263'");

şeklinde olabilir. Bu sayede sistem 1263 numaralı ID'ye sahip process'i arayıp bulmaya çalışacaktır.

ManagementObjectSearcher nesnesi ise verilen path (namespace) üzerinde verilen sorgu nesnesini çalıştırmakla yükümlüdür. Bununla beraber sonuçlarını , tabii ki, ADO.net'den alışıldığı üzere DataTable veya DataSet gibi nesnelerle değil yine ManagementObject olarak döndürür. Her sorgu muhakkak ki sıfır ila sonsuz tane cevap döndürecektir, dolayısı ile sonuçlar tek bir nesne değil nesneler topluluğu yani Collection olarak döndürülür. ManagementObject sınıflarından oluşan bu topluluğa ManagementObjectCollection adı verilmektedir. İsminden de anlaşılacağı gibi, zaten bu nesne (ManagementObjectSearcher) ManagementObject' lerini aramakla yükümlüdür, yani verilen sorgudaki kriterlere uyan nesneleri döndürecektir. Aşağıdaki örnekte konu ile ilgili örnek kod bloğu verilmiştir.

ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection result = searcher.Get();

Bu temel bilgilerin ardından örnek kodu incelemek yerinde olacaktır sanırım.

Örnek Uygulama

Öncelikle uygulamamızda kullanacağımız sınıflarımıza bir bakalım. Form1 adlı sınıf uygulamanın kullanıcı arabirimini oluşturan standart bir Form sınıfıdır. Yapılan işleleri arka tarafta çalışacak olan ProcWMI sınıfına iletmekten başka bir işlevi yoktur.

Bunun yanı sıra ProcessInfo sınıfı, her bir process hakkinda bizim uygulamamızda kullanılacak olan bilgileri içeren (esasında enkapsüle eden) bir sınıf olarak tasarlanmıştır. ID olarak sistemdeki process' in ID'si, Memory olarak process' in kullandığı bellek miktarı, Name olarak da process' I tanımlayan isim değerleri kullanılacaktır. ProcessInfoCollection ise ProcessInfo sınıflarını eleman olarak kabul eden bir Collection sınıfından ibarettir. Kodlara bakacak olursanız bu sınıfın CollectionBase sınıfından türediğini göreceksiniz.


Şekil 1 – Sınıf Tanımlamaları

Şimdi gelelim esas yükü sırtlanan ProcWMI sınıfına; bu sınıf iki temel property sunar, bunlar sırası ile Credentials ve ComputerName adlı property' lerdir. Credentials property' si kullanıcı uzak makinelere eğer farklı bir kimlik kullanarak bağlanmak istiyorsa kullanacağımız değerleri verir. Bu değerler, Domain adı, Kullanıcı Adı ve Şifresidir. ComputerName ise IP veya isim olarak bağlanılacak sistemi tanıtmaya yarar. Bu property' nin varsayılan değeri "localhost" olarak ayarlanmıştır.

IsLocal methodu verilen bilgisayar adı ve / veya IP' sinin lokal makine olup olmadığını sorgular. Eğer verilen yol lokal ise true aksi taktirde false döndürür ve private bir method' dur.

private bool IsLocal()
{
return (this.m_ComputerName == "localhost" || this.m_ComputerName == "." ||
this.m_ComputerName == "127.0.0.1" || this.m_ComputerName ==
System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList[0].ToString()
||
this.m_ComputerName.ToLower() == Dns.GetHostName().ToLower());
}

GetScope methodu ise verilen Credentials ve ComputerName property' leri vasıtasıyla ve verilen adresin lokal makine olup olmadığını kontrol ederek ilgili makinenin ilgili WMI namespace' ini kullanan bir path'i kullanarak bir ManagementScope nesnesi yaratır ve bu nesneyi geri gönderir. Dikkat edilirse verilen credentials sadece uzak makine bağlantılarında kullanılmak üzere ayarlanmıştır.

private ManagementScope GetScope(){
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = ImpersonationLevel.Impersonate;
options.Username = this.m_Credentials.Domain + "\\" + this.m_Credentials.UserName;
options.Password = this.m_Credentials.Password;

ManagementScope scope = null;

if (IsLocal())
scope = new ManagementScope("\\\\" + this.m_ComputerName + "\\root\\cimv2");
else
scope = new ManagementScope("\\\\" + this.m_ComputerName + "\\root\\cimv2", options);

return scope;
}

Bir diğer önemli method ise ExecuteQuery methodudur. Bu method parametre olarak string tipinde bir değişken (sorgu cümlesi) alır ve GetScope methodunu çağırarak elde ettiği scope üzerinde bu sorguyu çalıştırır ve elde ettiği ManagementObjectCollection tipindeki cevapları geri döndürür.

private ManagementObjectCollection ExecuteQuery(string queryText){
ManagementScope scope = this.GetScope();
ObjectQuery query = new ObjectQuery(queryText);
ManagementObjectSearcher searcher = new
ManagementObjectSearcher(scope, query);
ManagementObjectCollection result = searcher.Get();

return result;
}

Son olarak verilen process' leri öldürecek olan KillProcess adlı metodumuza bir göz atalım. Bu method parameter olarak process' in ID' sini almaktadır. Bilindiği üzere işletim sistemi üzerinde koşan her process' e tekil bir ID otomatik olarak verilmektedir. Aşağıda bu metodun kodları verilmiştir:
public void KillProcess(int procID){
ManagementObjectCollection results = this.ExecuteQuery("SELECT * FROM
Win32_Process WHERE ProcessID = '" + procID.ToString() + "'");

foreach (ManagementObject process in results){
ManagementBaseObject param =
process.GetMethodParameters("Terminate");
param["Reason"] = 1;
process.InvokeMethod("Terminate", param, null);
}
}

Burada dikkat edilirse metod önce ExecuteQuery fonksiyonunu çağırarak gerekli process' in varolup olmadığına bakmaktadır. Ardından bulunan sonuçlar arasından, ki ya hiç bulunmayacak ya da 1 tane bulunacaktır, tüm process' lere "Terminate" sinyali gönderilecektir. ManagementBaseObject sınıfının GetMethodParameters fonksiyonu istenilen bir WMI methodunun parametrelerini bize dödürmektedir. Bu örnekte Terminate fonksiyonunun parametreleri istenilmektedir. Bu parametrelerden bir tanesi çok önem kazanmaktadır, Reason. Çünkü system bizden bir process' I hangi sebeple öldürmek istediğimizi soracaktır. Bunun yanı sıra param adlı değişken, yani fonksiyonun parametrelerini refere eden deişkenimizin sanki bir HashTable yapısı gösterdiğine dikkatinizi çekmek isterim. Bu sayede param nesnesinin Reason indexer' ı ile refere edilen değeri 1 olarak set edilebilmektedir.

Geriye kalan tek nokta ise öldürülecek olan process' i refere eden WMI nesnesi üzerinden istenilen metodu, yani Terminate metodunu çağırmaktır. Görüldüğü üzere bu da InvokeMethod fonksiyonu sayesinde, ilgili metodun dinamik olarak çağırılması ile yapılabilir. InvokeMethod fonksiyonunun ikinci paramatresi olarak, dinamik olarak tanımlanan parametrelerinin, bir başka deyiş ile method üzerinden aldığımız param adlı nesnenin geçirildiğine dikkatinizi çekmek isterim.


Uygulama Yapısına Son Bir Bakış

Bu bölümde uygulamamızın yaptığı temel iki işlem olan, process' leri listelemek ve öldürmek için izlediği yolları basit birer flowchart ile göstereceğiz.


Şekil 2 – Kullanıcı Arabirimi


Şekil 3 – "Connect" butonu nasıl çalışıyor



Şekil 4 – "Kill" butonu nasıl çalışıyor

Örnek uygulama kodları için http://www.kozsu.com sitesini ziyaret edebilirsiniz. Uygulamanın kodları:

http://www.kozsu.com/admin/Portal/LinkClick.aspx?tabid=22&table=Documents&field=ItemID&id=39&link=ProcessManager.zip adresinden indirilebilir.

Yukarıdaki makale alıntıdır.


Çeşitli sitelerden bu konu ile alakalı örnek uygulama indirilebilir MSDN de de bir sürü yardım metini vardır.

Kolay gelsin
İnsanlara Akılları Ölçüsünde Söz Söyleyiniz.

EMG81

Makale için çok teşekkür ederim fakat C ile olduğu için yine basic e dökememekteyim. Bir kod buldum. Akşam denemeler yapacağım. İnş bu sefer başarırım. Ayrıca aklıma takıldımadı değil.. ben bu cpu nosunu yaptığım basit bir programı korumak için öğrenmek istiyorum fakat! daha profesyönel yollarda vardır diye tahmin ediyorum.programları korumanın daha profesyönel yolları hakkında bilgisi olan varmı ?

Burak B

"... a healthy dose of paranoia leads to better systems." Jack Ganssle

EMG81

Hemen inceliyorum. Haaa bu arada visual net te form un start anında nerede başlıyacağını nerden ayarlıyoruz. Mesela VB6 da sağ en altta monitör resmi ve form resmi vardı. Ordan ayarını yapıyordukk ?

Digimensch

#23
Alıntı yapılan: EMG81 - 01 Ocak 2011, 20:54:16
Hemen inceliyorum. Haaa bu arada visual net te form un start anında nerede başlıyacağını nerden ayarlıyoruz. Mesela VB6 da sağ en altta monitör resmi ve form resmi vardı. Ordan ayarını yapıyordukk ?
C#'da Formun ismini , cismini yani özelliklerini dagistirdigin kisim varya sag tarafda adi properies kismi.
orda StartPosition u bul ve karsiindaki cumbobox icindeki secenekleri degistirerek istedigin sekilde ayarlayabilirsin.
Örnegin Formun ekranin tam ortasinda acilmasini istersen CenterScreen secenegini secersin.

Kodlarla yapmak istiyorum dersen
Formun Load olayina
this.StartPosition = FormStartPosition.CenterScreen;


yazman yeterli olacaktir.

EMG81

Değerli yanıtlarınız için çok teşekkür ederim..@Digimensch Dediğini programda uyguladım ve oldu... Hdd serial number içinde ilk sayfada verdiğim kodu programa ekledim. Yarın hocaya teslim edeceğim inş. Konuyu sonuçlanmış olarak işaretliyorum yalnız son bir sorum daha olacak. Vb net te bi label ın yada text in içerisinin hep 4 haneli olmasını istiyorum ve bunu nasıl yapabilirim ?

Örneğin;

label1.text="0001"

label1.text =label1.text + 1  desemde içerisinin "0002" olmasını istiyorum. veya + 1000 dersem, bu seferde label1.text="1002" gibi...

Digimensch

labelin icine zaten kullanici yazi yazamaz.
ama textbox dersen
textBox1.MaxLength = 4;  seklinde sinirlayabilirsin.

Yada önceki mesajimda belirttigim gibi textboxun properties kismindan MaxLength icerigine 4 yazarsan artik kullanici TectBox icine 4 basamakli sayidan fazla giremez....

EMG81


iyildirim

stringval = right("0000" + trim(numericval) ,2)
label1.text = right("0000" + trim(val(label1.text)) ,2)
yada kullandığınız komponentin formatlama seçenekleri varsa o şekilde. label için yukarıdaki gibi.

EMG81

Verdiğiniz kod hata veriyor...

Hata veren kısımları ;

Stringval
numericval
Right

iyildirim

ilk satır  sadece örnek olması içindi.
sadece bu yeterli.
label1.text = right("0000" + trim(val(label1.text)) ,2)