ofis versiyonu

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
master_20
Üye
Mesajlar: 85
Kayıt: 27 Eki 2010 09:42

ofis versiyonu

Mesaj gönderen master_20 »

Merhaba arkadaslar regedette ilgili kayitlari okuyarak ofis versiyonunu ogrenebiliyorum ancak standart versiyon mu pro versiyonu mu gibi ayrintiyi alamadim. Bu konuda yonlendirme yapabilecek var mi acaba ?
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: ofis versiyonu

Mesaj gönderen mrmarman »

Güzel soru, google'da baktım herhangi bir çözüm bulamadım. Ben de kendi çözümümü üreteyim istedim.
Umarım faydası dokunur. Başlığı okuyanlar deneyip sonucu bildirirlerse sevinirim. Ben de emin değilim çünkü. Office kurulumları farklılık göstereceğinden düzgün çalışmaya da bilir.

Ben şimdi uyguladığım metodu anlatayım, aklınıza yatarsa kullanırsınız.
Yürüdüğüm yol, Registry içerisinde ürün adı nerede yer alıyor onu elle buldum. Gerisi mantık kurmakla ilgili.

Test edilip geçerli olup olmadığı doğrulanması gereken bir kod, kendi makinemde denediğim şeklin başka makinelerde de test edilmesi şart.

Açıklamaları kod içerisine yerleştirdim.
(1) Önce sistemin 32Bit veya 64Bit olma durumuna göre Registry erişimi otomatik yapılıyor.
(2) Her MSOffice için vazgeçilmez olan EXCEL programını ele alarak, varsayılan olarak kurulu olan EXCEL'in registry kaydından kurulu olduğu office klasörünü tespit ediyoruz.
(3) Kurulu olduğu klasörün adın Office15 olsun, sonundaki 15 rakamına ihtiyacımız var, sonuna ".0" ekleyip 15.0 yapınca registry içindekki MSOffice klasörüne direkt zıplayabileceğiz anlamına geliyor.
(4) MSOffice'in örneğimizde 15.0'lı olan gerçek olanı altında Registration alt başlığını açmayı deniyoruz. Açabilirsek bir adım daha hedefe yaklaşmış oluyoruz.
(5) Artık bir sürü anahtar içerisinden sırayla dolaşarak (uzun değil 3-5 anahtar sonra hedefe erişiyoruz) anahtar altında ProductCode değeri okuyabiliyorsak, aynı yerde Office'in ürün tam adının da yer aldığı sonucuna varıyoruz.

Kod: Tümünü seç

USES Registry;

function OfficeVersion: String;
  // 32 veya 64 Bit sistemlerde Registry kaydına farklı erişim şekli var.
  function RegistryViewAccessFlag: LongWord;
    type
      TRegistryView = (rvDefault, rvRegistry64, rvRegistry32);

    function IsWOW64: Boolean;
    type
      TIsWow64Process = function( Handle: THandle; var Res: BOOL ): BOOL; stdcall;
    var
      IsWow64Result  : BOOL;
      IsWow64Process : TIsWow64Process;
    begin
      IsWow64Process := GetProcAddress( GetModuleHandle('kernel32'), 'IsWow64Process' );
      if Assigned(IsWow64Process) then
      begin
        if not IsWow64Process(GetCurrentProcess, IsWow64Result)
          then raise Exception.Create('Sıkıntı var, anlayamadım...');
        Result := IsWow64Result;
      end else Result := False;
    end;
  begin
    if IsWOW64 then Result := KEY_WOW64_64KEY
               else Result := KEY_WOW64_32KEY;
  end;
var
  Reg          : TRegistry;
  strExcelPath : String;
  slListe      : TStringList;
  iSayac       : Integer;
  boolBulundu  : Boolean;
begin
  Result := 'Office Version malesef bulunamadı...';
  Reg := TRegistry.Create(KEY_READ or RegistryViewAccessFlag );
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;

    // Aktif Excel programının klasöründen Office setinin
    // 8.0, 9.0, 10.0 gibi sürüm numarasını elde etmeyi deniyoruz...
    if Reg.OpenKey('\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\excel.exe', False) then
    begin
      strExcelPath := ExcludeTrailingPathDelimiter( Reg.ReadString( 'Path' ) );
      System.Delete( strExcelPath, 1, Pos('\OFFICE', UpperCase( strExcelPath ) )+ Length('\OFFICE')-1 );

      if Reg.OpenKey('\SOFTWARE\Microsoft\Office\'+strExcelPath + '.0\Registration', False) then
      begin // Office kayıtlarına ulaştık.
        // Şimdi Office bileşen anahtar listesini elde edicez...
        slListe     := TStringList.Create;
        Reg.GetKeyNames( slListe );

        boolBulundu := False;
        iSayac      := 0;
        // Şimdi bu anahtar listesini tek tek açarak, içinde  'ProductCode' varsa
        // Office setine ait ana kayda ulaştık diyecek ve ProductNameBrand veya ProductName de olur
        // okuyup çıktı vericez...
        while (iSayac < slListe.Count) AND (not boolBulundu) do
        begin
          if Reg.OpenKey('\SOFTWARE\Microsoft\Office\'+strExcelPath + '.0\Registration\'+slListe[iSayac], False) then
          begin
            if Reg.ReadString('ProductCode') <> '' then
            begin
              Result := Reg.ReadString('ProductNameBrand');
              boolBulundu  := True;
            end;
          end;
          inc(iSayac);
        end; // While
        slListe.Free;
      end;
    end;
  finally
    Reg.Free;
  end;
end;
Kullanımı

Kod: Tümünü seç

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  ShowMessage(  OfficeVersion );
end;
Resim
Resim ....Resim
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: ofis versiyonu

Mesaj gönderen SimaWB »

WMI kullanarak Registry ile uğraşmadan alınabiliyormuş. Değerlendirmek lazım:
https://theroadtodelphi.wordpress.com/2 ... -software/

Not: Hangi işletim sistemlerini desteklediği kontrol edilmeli.
There's no place like 127.0.0.1
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: ofis versiyonu

Mesaj gönderen mrmarman »

:lol: Teşekkürler Veli hocam, sağ kulağımı soldan göstermişim. :lol:

Sonuç olumlu, kötü yanı çok yavaş olması...10 saniyeden uzun sürdü, sizde kaç saniye veriyor ? :roll:
Bir de bu listeden hangisinin M$Office'in kendisi olduğu bilgisini seçmekte zorlanıyorum. Acaba daima en sondaki vs. gibi bir çıkarım olabilir mi ama bu düşünce de bana sağlam gelmedi. Önümüzdeki maçlara bakacağız artık. :idea:

Sistem : Windows 7 Enterprise Ed. x64 bit
Resim

Kod: Tümünü seç

USES Activex, ComObj;

procedure TForm1.BitBtn5Click(Sender: TObject);
const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
  aBas : Cardinal;
begin;
  aBas := GetTickCount;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\cimv2', '', '');
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT Name,Version FROM  Win32_Product Where Name LIKE "Microsoft Office%"','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  With TStringList.Create do
  begin
    while oEnum.Next(1, FWbemObject, iValue) = 0 do
    begin
      Add( Format('Name    %s - Version %s',[String(FWbemObject.Name), String(FWbemObject.Version)]) );
      FWbemObject:=Unassigned;
    end;
    Add( '' );
    Add( 'Süre : ' + FloatToStr( (GetTickCount - aBas) / 1000 ) + ' saniye');
    Showmessage( Text );
    Free;
  end;// With
end;
Resim
Resim ....Resim
master_20
Üye
Mesajlar: 85
Kayıt: 27 Eki 2010 09:42

Re: ofis versiyonu

Mesaj gönderen master_20 »

bilgiler için teşekkürler arkadaşlar, her iki durumuda kontrol edip döneceğim :)
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: ofis versiyonu

Mesaj gönderen SimaWB »

mrmarman yazdı: Sonuç olumlu, kötü yanı çok yavaş olması...10 saniyeden uzun sürdü, sizde kaç saniye veriyor ? :roll:
Bir de bu listeden hangisinin M$Office'in kendisi olduğu bilgisini seçmekte zorlanıyorum. Acaba daima en sondaki vs. gibi bir çıkarım olabilir mi ama
Evet bende de çok yavaş: 12,843 sn.
Zaten Rodrigo web sitesinde bu konuda uyarıda bulunmuş. Bilgisayarda kurulu olan Windows programlarının sayısıyla orantılıymış sanırm.
İşin kötüsü, "Microsoft Office Professional Plus 2013" bende ilk sırada çıkıyor ama sizde son sırada gözüküyor.

Ben de pek tutmadım bunu :)
There's no place like 127.0.0.1
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: ofis versiyonu

Mesaj gönderen sabanakman »

Sırf merakımdan denedim, 80 sn sürdü :D
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: ofis versiyonu

Mesaj gönderen mrmarman »

Registry yöntemi cevap verdi mi sizlerde de? Farklı office versiyon ve window versionu ile sonuç hakkında fikir verir misiniz?
Resim
Resim ....Resim
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: ofis versiyonu

Mesaj gönderen thelvaci »

Bir kaç yöntem geliyor aklıma, arzu ederseniz deneyebilirsiniz. Birincisi; "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths" altında excel.exe anahtarını bulup, oradan yol tanımını elde edip; GetFileVersionInfo & VerQueryFile apileri ile dosyanın versiyonunu sorgulayabilirsiniz. İkinci olarak; madem sistemde Office yüklü; bu durumda, uygulamamız içinde Excel'e ulaşıp versiyon bilgisini kendisine sorabiliriz.

Örneğin;

Kod: Tümünü seç

var
  Excel : OleVariant;
begin
  Excel := CreateOleObject('Excel.Application');
  Excel.Visible := false;
  ShowMessage(Excel.Version);
  Excel.Quit;
end;
gibi.

Ayrıca; aşağıdaki API fonksiyonları ile sistem üzerinde yüklü olan uygulamaları ve bu uygulamaların versiyon bilgilerini de alabiliyormuşuz.

MsiEnumProducts function
MsiGetProductInfo function
Required Properties
En son thelvaci tarafından 20 Nis 2015 11:53 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: ofis versiyonu

Mesaj gönderen mrmarman »

şimdi dışarıdayım deneyemiyorum da excel versiyonu verirken ooffice paketinin hangi ürün olduğunu veriyor mu? Buradaki hedefimiz Microsoft Office Professional Plus 2013 ifadesine ulaşmak çünkü.
Resim
Resim ....Resim
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: ofis versiyonu

Mesaj gönderen thelvaci »

Yazdığım basit metod bende 14.0 ve 7145 döndürüyor.

Kod: Tümünü seç

procedure TForm2.Button1Click(Sender: TObject);
var
  Excel : Variant;
begin
  Excel := CreateOleObject('Excel.Application');
  Excel.Visible := false;
  ShowMessage(Excel.Version);
  ShowMessage(Excel.Build);
  Excel.Quit;
end;
master_20
Üye
Mesajlar: 85
Kayıt: 27 Eki 2010 09:42

Re: ofis versiyonu

Mesaj gönderen master_20 »

Ben yaklaşık olarak 120 Pc de denedim :) xp ve üzeri tüm işletim sistemleri ve tüm ofis versiyonlarında sağlıklı bir şekilde çalıştı 5 ile 15 sn arasında ofis versiyonlarını topladım sonucta istediğimi elde etmiş oldum :) teşekkürler.

Ancak exe olarak çalışan uygulamayı servis uygulaması olarak kodladığımda wmi sorgularında hata veriyor, wmi servis uygulamalarında çalıştırmak için extra birşey yapmak gerekir mi acaba ?
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: ofis versiyonu

Mesaj gönderen mrmarman »

Registry ile de denedin mi ? Yoksa sadece wmi ile mi denedin ?
Resim
Resim ....Resim
master_20
Üye
Mesajlar: 85
Kayıt: 27 Eki 2010 09:42

Re: ofis versiyonu

Mesaj gönderen master_20 »

registry ile denemedim, hem oradaki işlemler uzun geldi hemde benim amacım bilgisayarın envanterini çıkarmaktı onuda wmi ile alıyordum ikisi bir arada oldu
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: ofis versiyonu

Mesaj gönderen SimaWB »

master_20 yazdı:wmi servis uygulamalarında çalıştırmak için extra birşey yapmak gerekir mi acaba ?
Evet yapman gerekiyor.
:ara CoInitialize CoUninitialize
There's no place like 127.0.0.1
Cevapla