OLD | NEW |
1 /** | 1 /** |
2 * \file property.h Installer property, whether from a live installation session
or directly from a package or installed product. | 2 * \file property.h Installer property, whether from a live installation session
or directly from a package or installed product. |
3 */ | 3 */ |
4 | 4 |
5 #ifndef PROPERTY_H | 5 #ifndef PROPERTY_H |
6 #define PROPERTY_H | 6 #define PROPERTY_H |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 #include "windows.h" | 9 #include "windows.h" |
10 #include "msi.h" | 10 #include "msi.h" |
11 | 11 |
12 /* | 12 /* |
13 * Forward declaration of Session class required to break what's otherwise a cyc
lic definition. | 13 * Forward declaration of Session class required to break what's otherwise a cycl
ic definition. |
14 */ | 14 */ |
15 class Session ; | 15 class Session ; |
16 | 16 |
17 /** | 17 /** |
18 * Class representing an MSI property. | 18 * Class representing an MSI property. |
19 * | 19 * |
20 * MSI properties arise from three places: | 20 * MSI properties arise from three places: |
21 * - Live installations (seen in custom actions) | 21 * - Live installations (seen in custom actions) |
22 * - Packages (MSI files) | 22 * - Packages (MSI files) |
23 * - Products (as installed on a machine) | 23 * - Products (as installed on a machine) |
24 * All of these access an underlying MSI database at some remove, though the det
ails vary. | 24 * All of these access an underlying MSI database at some remove, though the deta
ils vary. |
25 * The underlying API calls, MsiGetProperty and MsiSetProperty, are overloaded, | 25 * The underlying API calls, MsiGetProperty and MsiSetProperty, are overloaded, |
26 * in the sense that they take a single handle regardless of what it represent
s. | 26 * in the sense that they take a single handle regardless of what it represents
. |
27 * Constructors for this class, therefore, require both a name and one of these
places. | 27 * Constructors for this class, therefore, require both a name and one of these p
laces. |
28 * | 28 * |
29 * Handles are not user-visible in this library by policy. | 29 * Handles are not user-visible in this library by policy. |
30 * Therefore this class has no public constructors. | 30 * Therefore this class has no public constructors. |
31 * Constructors are private and made available to the classes surrounding a hand
le with a 'friend' declaration. | 31 * Constructors are private and made available to the classes surrounding a handl
e with a 'friend' declaration. |
32 * These class provide factory access to property objects. | 32 * These class provide factory access to property objects. |
33 * We use the default copy constructor and assignment operator (both implicitly
declared) to make the factory function work. | 33 * We use the default copy constructor and assignment operator (both implicitly d
eclared) to make the factory function work. |
34 * | 34 * |
35 * The semantics of properties is that they always appear as defined. | 35 * The semantics of properties is that they always appear as defined. |
36 * Properties not explicitly defined are considered to have the empty string (ze
ro-length) as their value. | 36 * Properties not explicitly defined are considered to have the empty string (zer
o-length) as their value. |
37 * The return values of the API functions, for example, do not have an error cod
e of "property not found". | 37 * The return values of the API functions, for example, do not have an error code
of "property not found". |
38 * | 38 * |
39 * Rather than getter/setter functions, this class allows Property instances to
appear exactly as strings. | 39 * Rather than getter/setter functions, this class allows Property instances to a
ppear exactly as strings. |
40 * Instead of a getter, we provide a string conversion operator. | 40 * Instead of a getter, we provide a string conversion operator. |
41 * Instead of a setter, we provide an overloaded assignment operator. | 41 * Instead of a setter, we provide an overloaded assignment operator. |
42 * | 42 * |
43 * \remark | 43 * \remark |
44 * This class is specialized to std::wstring for property names and values. | 44 * This class is specialized to std::wstring for property names and values. |
45 * A more general library class would have these as template arguments, whether
on the class or on functions. | 45 * A more general library class would have these as template arguments, whether o
n the class or on functions. |
46 * | 46 * |
47 * \remark | 47 * \remark |
48 * The class makes a copy of the handle of the underlying object rather than kee
ping a reference to that object. | 48 * The class makes a copy of the handle of the underlying object rather than keep
ing a reference to that object. |
49 * This approach has the drawback that the user must ensure that the underlying
object remains open for the lifetime of one of its derived Property instances. | 49 * This approach has the drawback that the user must ensure that the underlying o
bject remains open for the lifetime of one of its derived Property instances. |
50 * For single-threaded custom actions (the ordinary case), this is never a probl
em, | 50 * For single-threaded custom actions (the ordinary case), this is never a proble
m, |
51 * because the entry point constructs a Session that lasts the entire duration
of the CA. | 51 * because the entry point constructs a Session that lasts the entire duration
of the CA. |
52 * For other tools using the library, this may not be the case. | 52 * For other tools using the library, this may not be the case. |
53 * Nevertheless, for a typical case where the scope of a Property is a single fu
nction, there's no problem. | 53 * Nevertheless, for a typical case where the scope of a Property is a single fun
ction, there's no problem. |
54 * | 54 * |
55 * \sa MSDN on <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/
aa370889%28v=vs.85%29.aspx">Windows Installer Properties</a>. | 55 * \sa MSDN on <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/a
a370889%28v=vs.85%29.aspx">Windows Installer Properties</a>. |
56 */ | 56 */ |
57 class Property | 57 class Property |
58 { | 58 { |
59 public: | 59 public: |
60 /** | 60 /** |
61 * Conversion operator to std::wstring provides rvalue access to the property. | 61 * Conversion operator to std::wstring provides rvalue access to the property. |
62 */ | 62 */ |
63 operator std::wstring() const ; | 63 operator std::wstring() const ; |
64 | 64 |
65 /** | 65 /** |
66 * Assignment operator from std::wstring provides lvalue access to the propert
y. | 66 * Assignment operator from std::wstring provides lvalue access to the property
. |
67 * | 67 * |
68 * \par[in] value | 68 * \par[in] value |
69 * Value to be assigned to the property | 69 * Value to be assigned to the property |
70 */ | 70 */ |
71 void operator=( const std::wstring & value ) ; | 71 void operator=( const std::wstring & value ) ; |
72 | 72 |
73 /** | 73 /** |
74 * Constructor from a session. | 74 * Constructor from a session. |
75 * | 75 * |
76 * The Windows Installer API uses a single handle type for all kinds of sessio
ns. | 76 * The Windows Installer API uses a single handle type for all kinds of session
s. |
77 * Deferred sessions, though, have access only to a limited set of property va
lues. | 77 * Deferred sessions, though, have access only to a limited set of property val
ues. |
78 * It's the responsibility of the user to ensure that property names refer to
properties that contain meaningful data. | 78 * It's the responsibility of the user to ensure that property names refer to p
roperties that contain meaningful data. |
79 * As a result, this constructor has base Session class as an argument, and we
use this argument for both immediate and deferred sessions. | 79 * As a result, this constructor has base Session class as an argument, and we
use this argument for both immediate and deferred sessions. |
80 * | 80 * |
81 * \sa MSDN "Obtaining Context Information for Deferred Execution Custom Actio
ns" | 81 * \sa MSDN "Obtaining Context Information for Deferred Execution Custom Action
s" |
82 * http://msdn.microsoft.com/en-us/library/windows/desktop/aa370543%28v=vs
.85%29.aspx | 82 * http://msdn.microsoft.com/en-us/library/windows/desktop/aa370543%28v=vs.
85%29.aspx |
83 * for a list of properties that are available to deferred custom actions. | 83 * for a list of properties that are available to deferred custom actions. |
84 */ | 84 */ |
85 Property( Session & session, std::wstring name ) ; | 85 Property( Session & session, std::wstring name ) ; |
86 | 86 |
87 private: | 87 private: |
88 /** | 88 /** |
89 * Handle to the installation, product, or package. | 89 * Handle to the installation, product, or package. |
90 * Any of these is permissible; the API does not distinguish these as types. | 90 * Any of these is permissible; the API does not distinguish these as types. |
91 */ | 91 */ |
92 MSIHANDLE handle ; | 92 MSIHANDLE handle ; |
93 | 93 |
94 /** | 94 /** |
95 * Name of the property. | 95 * Name of the property. |
96 * | 96 * |
97 * \sa http://msdn.microsoft.com/en-us/library/windows/desktop/aa371245%28v=vs
.85%29.aspx for more on property names, | 97 * \sa http://msdn.microsoft.com/en-us/library/windows/desktop/aa371245%28v=vs.
85%29.aspx for more on property names, |
98 * including valid syntax and the internal scoping that the installer uses. | 98 * including valid syntax and the internal scoping that the installer uses. |
99 */ | 99 */ |
100 std::wstring name ; | 100 std::wstring name ; |
101 } ; | 101 } ; |
102 | 102 |
103 /* | 103 /* |
104 * We need a couple of ancillary addition operators to concatenate properties an
d constants strings. | 104 * We need a couple of ancillary addition operators to concatenate properties and
constants strings. |
105 * While not strictly necessary, they eliminate the need for an explicit convers
ion operator. | 105 * While not strictly necessary, they eliminate the need for an explicit conversi
on operator. |
106 * The compiler needs a means to infer that "+" refers to string operations dire
ctly; | 106 * The compiler needs a means to infer that "+" refers to string operations direc
tly; |
107 * it doesn't search all possible chains of conversions to locate an operator. | 107 * it doesn't search all possible chains of conversions to locate an operator. |
108 * Support isn't complete, as we're not declaring concatenation for characters n
or for rvalue references (the other meaning of &&). | 108 * Support isn't complete, as we're not declaring concatenation for characters no
r for rvalue references (the other meaning of &&). |
109 */ | 109 */ |
110 /** | 110 /** |
111 * Concatenation operator for a constant-string plus a property | 111 * Concatenation operator for a constant-string plus a property |
112 */ | 112 */ |
113 inline std::wstring operator+( const wchar_t * left, const Property & right ) | 113 inline std::wstring operator+( const wchar_t * left, const Property & right ) |
114 { | 114 { |
115 return left + std::wstring( right ) ; | 115 return left + std::wstring( right ) ; |
116 } | 116 } |
117 | 117 |
118 /** | 118 /** |
119 * Concatenation operator for a property and a constant-string | 119 * Concatenation operator for a property and a constant-string |
120 */ | 120 */ |
121 inline std::wstring operator+( const Property & left, const wchar_t * right ) | 121 inline std::wstring operator+( const Property & left, const wchar_t * right ) |
122 { | 122 { |
123 return std::wstring( left ) + right ; | 123 return std::wstring( left ) + right ; |
124 } | 124 } |
125 | 125 |
126 #endif | 126 #endif |
OLD | NEW |