返回 DeepSeek-Reasonix
env_create_options.go
根目录 / desktop / third_party / go-webview2 / webviewloader / env_create_options.go
1 //go:build windows && !native_webview2loader
2
3 package webviewloader
4
5 import (
6 "unicode/utf16"
7 "unsafe"
8
9 "github.com/wailsapp/go-webview2/pkg/combridge"
10 "golang.org/x/sys/windows"
11 )
12
13 // WithBrowserExecutableFolder to specify whether WebView2 controls use a fixed or installed version
14 // of the WebView2 Runtime that exists on a user machine.
15 //
16 // To use a fixed version of the WebView2 Runtime,
17 // pass the folder path that contains the fixed version of the WebView2 Runtime.
18 // BrowserExecutableFolder supports both relative (to the application's executable) and absolute files paths.
19 // To create WebView2 controls that use the installed version of the WebView2 Runtime that exists on user
20 // machines, pass a empty string to WithBrowserExecutableFolder. In this scenario, the API tries to find a
21 // compatible version of the WebView2 Runtime that is installed on the user machine (first at the machine level,
22 // and then per user) using the selected channel preference. The path of fixed version of the WebView2 Runtime
23 // should not contain \Edge\Application\. When such a path is used, the API fails with HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED).
24 func WithBrowserExecutableFolder(folder string) option {
25 return func(wvep *environmentOptions) {
26 wvep.browserExecutableFolder = folder
27 }
28 }
29
30 // WithUserDataFolder specifies to user data folder location for WebView2
31 //
32 // You may specify the userDataFolder to change the default user data folder location for WebView2.
33 // The path is either an absolute file path or a relative file path that is interpreted as relative
34 // to the compiled code for the current process.
35 // Dhe default user data ({Executable File Name}.WebView2) folder is created in the same directory
36 // next to the compiled code for the app. WebView2 creation fails if the compiled code is running
37 // in a directory in which the process does not have permission to create a new directory.
38 // The app is responsible to clean up the associated user data folder when it is done.
39 func WithUserDataFolder(folder string) option {
40 return func(wvep *environmentOptions) {
41 wvep.userDataFolder = folder
42 }
43 }
44
45 // WithAdditionalBrowserArguments changes the behavior of the WebView.
46 //
47 // The arguments are passed to the
48 // browser process as part of the command. For more information about
49 // using command-line switches with Chromium browser processes, navigate to
50 // [Run Chromium with Flags][ChromiumDevelopersHowTosRunWithFlags].
51 // The value appended to a switch is appended to the browser process, for
52 // example, in `--edge-webview-switches=xxx` the value is `xxx`. If you
53 // specify a switch that is important to WebView functionality, it is
54 // ignored, for example, `--user-data-dir`. Specific features are disabled
55 // internally and blocked from being enabled. If a switch is specified
56 // multiple times, only the last instance is used.
57 //
58 // \> [!NOTE]\n\> A merge of the different values of the same switch is not attempted,
59 // except for disabled and enabled features. The features specified by
60 // `--enable-features` and `--disable-features` are merged with simple
61 // logic.\n\> * The features is the union of the specified features
62 // and built-in features. If a feature is disabled, it is removed from the
63 // enabled features list.
64 //
65 // If you specify command-line switches and use the
66 // `additionalBrowserArguments` parameter, the `--edge-webview-switches`
67 // value takes precedence and is processed last. If a switch fails to
68 // parse, the switch is ignored. The default state for the operation is
69 // to run the browser process with no extra flags.
70 //
71 // [ChromiumDevelopersHowTosRunWithFlags]: https://www.chromium.org/developers/how-tos/run-chromium-with-flags "Run Chromium with flags | The Chromium Projects"
72 func WithAdditionalBrowserArguments(args string) option {
73 return func(wvep *environmentOptions) {
74 wvep.additionalBrowserArguments = args
75 }
76 }
77
78 // WithLanguage sets the default display language for WebView.
79 //
80 // It applies to browser UI such as
81 // context menu and dialogs. It also applies to the `accept-languages` HTTP
82 // header that WebView sends to websites. It is in the format of
83 //
84 // `language[-country]` where `language` is the 2-letter code from
85 // [ISO 639][ISO639LanguageCodesHtml]
86 // and `country` is the
87 // 2-letter code from
88 // [ISO 3166][ISOStandard72482Html].
89 //
90 // [ISO639LanguageCodesHtml]: https://www.iso.org/iso-639-language-codes.html "ISO 639 | ISO"
91 // [ISOStandard72482Html]: https://www.iso.org/standard/72482.html "ISO 3166-1:2020 | ISO"
92 func WithLanguage(lang string) option {
93 return func(wvep *environmentOptions) {
94 wvep.language = lang
95 }
96 }
97
98 // WithTargetCompatibleBrowserVersion secifies the version of the WebView2 Runtime binaries required to be
99 // compatible with your app.
100 //
101 // This defaults to the WebView2 Runtime version
102 // that corresponds with the version of the SDK the app is using. The
103 // format of this value is the same as the format of the
104 // `BrowserVersionString` property and other `BrowserVersion` values. Only
105 // the version part of the `BrowserVersion` value is respected. The channel
106 // suffix, if it exists, is ignored. The version of the WebView2 Runtime
107 // binaries actually used may be different from the specified
108 // `TargetCompatibleBrowserVersion`. The binaries are only guaranteed to be
109 // compatible. Verify the actual version on the `BrowserVersionString`
110 // property on the `ICoreWebView2Environment`.
111 func WithTargetCompatibleBrowserVersion(version string) option {
112 return func(wvep *environmentOptions) {
113 wvep.targetCompatibleBrowserVersion = version
114 }
115 }
116
117 // WithAllowSingleSignOnUsingOSPrimaryAccount is used to enable
118 // single sign on with Azure Active Directory (AAD) and personal Microsoft
119 // Account (MSA) resources inside WebView. All AAD accounts, connected to
120 // Windows and shared for all apps, are supported. For MSA, SSO is only enabled
121 // for the account associated for Windows account login, if any.
122 // Default is disabled. Universal Windows Platform apps must also declare
123 // `enterpriseCloudSSO`
124 // [Restricted capabilities][WindowsUwpPackagingAppCapabilityDeclarationsRestrictedCapabilities]
125 // for the single sign on (SSO) to work.
126 //
127 // [WindowsUwpPackagingAppCapabilityDeclarationsRestrictedCapabilities]: /windows/uwp/packaging/app-capability-declarations\#restricted-capabilities "Restricted capabilities - App capability declarations | Microsoft Docs"
128 func WithAllowSingleSignOnUsingOSPrimaryAccount(allow bool) option {
129 return func(wvep *environmentOptions) {
130 wvep.allowSingleSignOnUsingOSPrimaryAccount = allow
131 }
132 }
133
134 // WithExclusiveUserDataFolderAccess specifies that the WebView environment
135 // obtains exclusive access to the user data folder.
136 //
137 // If the user data folder is already being used by another WebView environment with a
138 // different value for `ExclusiveUserDataFolderAccess` property, the creation of a WebView2Controller
139 // using the environment object will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`.
140 // When set as TRUE, no other WebView can be created from other processes using WebView2Environment
141 // objects with the same UserDataFolder. This prevents other processes from creating WebViews
142 // which share the same browser process instance, since sharing is performed among
143 // WebViews that have the same UserDataFolder. When another process tries to create a
144 // WebView2Controller from an WebView2Environment object created with the same user data folder,
145 // it will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`.
146 func WithExclusiveUserDataFolderAccess(exclusive bool) option {
147 return func(wvep *environmentOptions) {
148 wvep.exclusiveUserDataFolderAccess = exclusive
149 }
150 }
151
152 type option func(*environmentOptions)
153
154 var _ iCoreWebView2EnvironmentOptions = &environmentOptions{}
155 var _ iCoreWebView2EnvironmentOptions2 = &environmentOptions{}
156
157 type environmentOptions struct {
158 browserExecutableFolder string
159 userDataFolder string
160 preferCanary bool
161
162 additionalBrowserArguments string
163 language string
164 targetCompatibleBrowserVersion string
165 allowSingleSignOnUsingOSPrimaryAccount bool
166 exclusiveUserDataFolderAccess bool
167 }
168
169 func (o *environmentOptions) AdditionalBrowserArguments() string {
170 return o.additionalBrowserArguments
171 }
172
173 func (o *environmentOptions) Language() string {
174 return o.language
175 }
176
177 func (o *environmentOptions) TargetCompatibleBrowserVersion() string {
178 v := o.targetCompatibleBrowserVersion
179 if v == "" {
180 v = kMinimumCompatibleVersion
181 }
182 return v
183 }
184
185 func (o *environmentOptions) AllowSingleSignOnUsingOSPrimaryAccount() bool {
186 return o.allowSingleSignOnUsingOSPrimaryAccount
187 }
188
189 func (o *environmentOptions) ExclusiveUserDataFolderAccess() bool {
190 return o.exclusiveUserDataFolderAccess
191 }
192
193 type iCoreWebView2EnvironmentOptions interface {
194 combridge.IUnknown
195
196 AdditionalBrowserArguments() string
197 Language() string
198 TargetCompatibleBrowserVersion() string
199 AllowSingleSignOnUsingOSPrimaryAccount() bool
200 }
201
202 type iCoreWebView2EnvironmentOptions2 interface {
203 combridge.IUnknown
204
205 ExclusiveUserDataFolderAccess() bool
206 }
207
208 func init() {
209 combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2EnvironmentOptions](
210 "{2fde08a8-1e9a-4766-8c05-95a9ceb9d1c5}",
211 _iCoreWebView2EnvironmentOptionsAdditionalBrowserArguments,
212 _iCoreWebView2EnvironmentOptionsNOP,
213 _iCoreWebView2EnvironmentOptionsLanguage,
214 _iCoreWebView2EnvironmentOptionsNOP,
215 _iCoreWebView2EnvironmentTargetCompatibleBrowserVersion,
216 _iCoreWebView2EnvironmentOptionsNOP,
217 _iCoreWebView2EnvironmentOptionsAllowSingleSignOnUsingOSPrimaryAccount,
218 _iCoreWebView2EnvironmentOptionsNOP,
219 )
220
221 combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2EnvironmentOptions2](
222 "{ff85c98a-1ba7-4a6b-90c8-2b752c89e9e2}",
223 _iCoreWebView2EnvironmentOptions2ExclusiveUserDataFolderAccess,
224 _iCoreWebView2EnvironmentOptionsNOP,
225 )
226 }
227 func _iCoreWebView2EnvironmentOptionsNOP(this uintptr) uintptr {
228 return uintptr(windows.S_FALSE)
229 }
230
231 func _iCoreWebView2EnvironmentOptionsAdditionalBrowserArguments(this uintptr, value **uint16) uintptr {
232 v := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).AdditionalBrowserArguments()
233 *value = stringToOleString(v)
234 return uintptr(windows.S_OK)
235 }
236
237 func _iCoreWebView2EnvironmentOptionsLanguage(this uintptr, value **uint16) uintptr {
238 args := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).Language()
239 *value = stringToOleString(args)
240 return uintptr(windows.S_OK)
241 }
242
243 func _iCoreWebView2EnvironmentTargetCompatibleBrowserVersion(this uintptr, value **uint16) uintptr {
244 args := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).TargetCompatibleBrowserVersion()
245 *value = stringToOleString(args)
246 return uintptr(windows.S_OK)
247 }
248
249 func _iCoreWebView2EnvironmentOptionsAllowSingleSignOnUsingOSPrimaryAccount(this uintptr, value *int32) uintptr {
250 v := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).AllowSingleSignOnUsingOSPrimaryAccount()
251 *value = boolToInt(v)
252 return uintptr(windows.S_OK)
253 }
254
255 func _iCoreWebView2EnvironmentOptions2ExclusiveUserDataFolderAccess(this uintptr, value *int32) uintptr {
256 v := combridge.Resolve[iCoreWebView2EnvironmentOptions2](this).ExclusiveUserDataFolderAccess()
257 *value = boolToInt(v)
258 return uintptr(windows.S_OK)
259 }
260
261 func stringToOleString(v string) *uint16 {
262 wstr := utf16.Encode([]rune(v + "\x00"))
263 lwstr := len(wstr)
264 ptr := (*uint16)(coTaskMemAlloc(2 * lwstr))
265
266 copy(unsafe.Slice(ptr, lwstr), wstr)
267
268 return ptr
269 }
270
271 func boolToInt(v bool) int32 {
272 if v {
273 return 1
274 }
275 return 0
276 }
277
277 lines GO