Autor Beitrag
Marabunta
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Mi 08.01.14 13:03 
Hallo,

ich möchte vom Adobe Reader die Version feststellen.
Problem bei der ersten Variante (Registry->GUID) war, dass nicht jede Version den Wert verändert hat. Folglich würde bspw. immer eine alte Version festgestellt und ein kleiner Patch installiert werden, da meldet es sich mit bereits installiert oder sonstigen Fehlern.
Wie genau der es sonst feststellt weiß ich nicht, laut
blogs.adobe.com/dmcm...stration.pdf#page=25
gibt es noch folgende Möglichkeit:

1.7.3 MSI API
For 10.x product versions, you can use the MSI API to determine the product version. To use the MSI API,
use the MsiEnumRelatedProducts() and MsiGetProductInfo() as shown in Example 1.5.
For more information about these APIs, see msdn.microsoft.com/e...aa370130(VS.85).aspx
Example 1.5: Product version via MSI API
ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
//UpgradeCode is a family of ProductCodes
//ProductCode property is what you need to get installed Product Info
void GetProductInfo()
{
  /*
  Reader 7.0.5 {AC76BA86-7AD7-1033-7B44-A70500000002}
  Acrobat 7.0.1 and Reader 7.0.1 Update {AC76BA86-0000-7EC8-7489-000000000702}
  Acrobat 7.0.2 and Reader 7.0.2 Update {AC76BA86-0000-7EC8-7489-000000000703}
  Acrobat 7.0.3 and Reader 7.0.3 Update {AC76BA86-0000-7EC8-7489-000000000704}
  Acrobat 7.0.5 and Reader 7.0.5 Update Use the product ID 7.0 listed above
  Adobe Acrobat 7.0.7 and Reader 7.0.7 update {AC76BA86-1033-F400-7760-100000000002}
  Adobe Acrobat 7.0.8 and Reader 7.0.8 update {AC76BA86-1033-0000-7760-100000000002}
  Table 8 Example GUIDs
  Product GUID
  Trial Acrobat installations
  2/8/12: Enterprise Administration for the Acrobat Family of Products 30
  */
  CString sUpgrdCode = _T("{A6EADE66-0000-0000-484E-7E8A45000000}");//All
  Reader installers (any version) have the same UpgradeCode
  //UpgradeCodes for Acrobat - these values do not change
  //APEX {AC76BA86-0000-0000-7761-7E8A45000000};
  //Pro {AC76BA86-0000-0000-7760-7E8A45000000};
  //Std {AC76BA86-0000-0000-BA7E-7E8A45000000};
  CString sProdCode;
  DWORD dw = ERROR_SUCCESS;
  for(int index = 0; dw == ERROR_SUCCESS; index++)
  {
    dw = MsiEnumRelatedProducts(sUpgrdCode, 0, index,
    sProdCode.GetBuffer(MAX_PATH));
    sProdCode.ReleaseBuffer();
    if(dw == ERROR_SUCCESS)
    {
      UINT ret;
      TCHAR sVersionString[MAX_PATH] = {0}, sVerMajor[MAX_PATH] = {0};
      DWORD dwSize = 10;
      ret = MsiGetProductInfo(sProdCode, INSTALLPROPERTY_VERSIONMAJOR, sVerMajor, &dwSize);
      //ret = MsiGetProductInfo(sProdCode, INSTALLPROPERTY_VERSIONSTRING, sVersionString, &dwSize);
    }
  }
}

wie ich diesen Code bzw. mit welchem Programm verwende weiß ich nicht.
Was genau passiert hier und wie komme ich damit ans Ziel?
Danke.

Moderiert von user profile iconTh69: Code-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 08.01.14 14:24 
Hallo und :welcome:

bei dem Beispiel-Code handelt es sich um C++ (und dem MFC-Framework).
Um von C# aus native C-Schnittstellen anzusprechen, verwendet man P/Invoke.
Als gute Anlaufstelle dafür gibt es die Seite pinvoke.net
Für deine beiden Funktionen dann konkret
pinvoke.net/default....iEnumRelatedProducts
pinvoke.net/default....si.MsiGetProductInfo

Du müsstest dich also ersteinmal generell in P/Invoke einarbeiten.
Marabunta Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Do 09.01.14 12:25 
danke ich komme mit dem was dort steht leider gar nicht klar.
ich habe vergebens versucht das generell zum laufen zu bekommen:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
1>Der Buildvorgang wurde am 09.01.2014 11:06:41 gestartet.
1>InitializeBuildStatus:
1>  Aktualisieren des Timestamps von "Debug\Reader_Version_Identify.unsuccessfulbuild".
1>ClCompile:
1>  Alle Ausgaben sind aktuell.
1>  Alle Ausgaben sind aktuell.
1>ResourceCompile:
1>  Alle Ausgaben sind aktuell.
1>ManifestResourceCompile:
1>  Alle Ausgaben sind aktuell.
1>Reader_Version_Identify.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_MsiGetProductInfoW@16" in Funktion ""void __cdecl GetProductInfo(void)" (?GetProductInfo@@YAXXZ)".
1>Reader_Version_Identify.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_MsiEnumRelatedProductsW@16" in Funktion ""void __cdecl GetProductInfo(void)" (?GetProductInfo@@YAXXZ)".
1>D:\Test\Reader_Version_VisualStudio\Reader_Version_Identify\Debug\Reader_Version_Identify.exe : fatal error LNK1120: 2 nicht aufgelöste externe Verweise.
1>
1>Fehler beim Erstellen


mein Code sieht aktuell so aus

ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
// Reader_Version_Identify.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

#include "stdafx.h"
#include "Reader_Version_Identify.h"
#include "msi.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// Das einzige Anwendungsobjekt

CWinApp theApp;

using namespace std;

//UpgradeCode is a family of ProductCodes
//ProductCode property is what you need to get installed Product Info
void GetProductInfo()
{
CString sUpgrdCode = _T("{A6EADE66-0000-0000-484E-7E8A45000000}");
//AllReader installers (any version) have the same UpgradeCode
//UpgradeCodes for Acrobat - these values do not change
//APEX {AC76BA86-0000-0000-7761-7E8A45000000};
//Pro {AC76BA86-0000-0000-7760-7E8A45000000};
//Std {AC76BA86-0000-0000-BA7E-7E8A45000000};
CString sProdCode;
DWORD dw = ERROR_SUCCESS;
for(int index = 0; dw == ERROR_SUCCESS; index++)
{
dw = MsiEnumRelatedProducts(sUpgrdCode, 0, index, sProdCode.GetBuffer(MAX_PATH));
sProdCode.ReleaseBuffer();
if(dw == ERROR_SUCCESS)
{
UINT ret;
TCHAR sVersionString[MAX_PATH] = {0}, sVerMajor[MAX_PATH] = {0};
DWORD dwSize = 10;
ret = MsiGetProductInfo(sProdCode, INSTALLPROPERTY_VERSIONMAJOR, sVerMajor, &dwSize);
//ret = MsiGetProductInfo(sProdCode, INSTALLPROPERTY_VERSIONSTRING, sVersionString, &dwSize);
}
}
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
  int nRetCode = 0;

  HMODULE hModule = ::GetModuleHandle(NULL);

  if (hModule != NULL)
  {
    // MFC initialisieren und drucken. Bei Fehlschlag Fehlermeldung aufrufen.
    if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
    {
      // TODO: Den Fehlercode an Ihre Anforderungen anpassen.
      _tprintf(_T("Schwerwiegender Fehler bei der MFC-Initialisierung\n"));
      nRetCode = 1;
    }
    else
    {
      // TODO: Hier den Code für das Verhalten der Anwendung schreiben.
      _tprintf(_T("Funktioniert bis hier.\n"));

    }
  }
  else
  {
    // TODO: Den Fehlercode an Ihre Anforderungen anpassen.
    _tprintf(_T("Schwerwiegender Fehler: Fehler bei GetModuleHandle.\n"));
    nRetCode = 1;
  }

  return nRetCode;
}


ich behaupte mit der msi.h die ich einbinden könnte löse ich das problem, habe nur leider keine?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 09.01.14 13:01 
Hallo,

ich bin davon ausgegangen, daß du in C# programmierst (denn dies hier ist ja ein C#-Forum).

Aber zu deinem Problem mit dem C++ Code:
dir fehlt noch die "msi.lib" als Verweis für den Linker (in den Projekteinstellungen unter Linker Input).
Marabunta Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Do 09.01.14 14:13 
danke es klappt jetzt soweit.
was c++ usw. betrifft habe ich vor jahren hello world hinbekommen aber dann wegen anderer dinge auch wieder aufhören müssen...trotzdem soll das hier laufen.

jetzt muss bloß noch die version ausgegeben werden(und später woanders übernommen)

hiermit ging es leider nicht:
ausblenden Quelltext
1:
UINT _tprintf(ret);					


wie bekomme ich das hin?