草庐IT

c++ - IWebbrowser2 IE=edge 和用户代理字符串

coder 2024-02-10 原文

我正在开发一个使用 IWebBrowser2 嵌入式控件的 winapi c++ 程序。

我运行的是 Windows 7 + IExplore 11,所以当我打开 IE11 并调用我的服务器时,我得到了这个用户代理字符串:

Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko

当从 IWebBrowser2 发出请求时,我得到这个 UA 字符串:

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; Tablet PC 2.0; InfoPath.3; .NET4.0E)

我已经设法将此元标记附加到 IWebBrowser2 中加载的每个 html 页面(编辑 试图避免执行浏览器功能控制 - 请参阅评论 -):

<meta http-equiv="X-UA-Compatible" content="IE=edge"/>


第一个问题:通过这样做,我是否启用了最新安装的 IExplore 版本的功能?

第二个问题:我在Changing the user agent of the WebBrowser control看到过如何更改 IWebBrowser2 中的 UA 字符串。

有没有办法在安全用户权限下获取最新的IE版本UA字符串? (所以即使对于我可以实现的大多数权限受限的用户帐户)。 我试过 ObtainUserAgentString()运气不好,总是得到 "Mozilla/4.0 ... MSIE 7.0 ..."

最佳答案

最后,感谢 Noseratio 评论 (+1),我实现了浏览器功能控制,因为这不需要管理员权限。我还在注册表中打开了易变的 key ,以便在可能的卸载后不会弄脏注册表。

由于 Noseratio 链接的响应引用了 C#,如果有人需要 C++ 翻译并解释每个功能的作用,我将其留在此处:

static bool SetBrowserFeatureControlKey(wstring feature, wchar_t *appName, DWORD value) {
  HKEY key;
  bool success = true;
  wstring featuresPath(L"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\");
  wstring path(featuresPath + feature);

  LONG nError = RegCreateKeyEx(HKEY_CURRENT_USER, path.c_str(), 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &key, NULL);
  if (nError != ERROR_SUCCESS) {
    success = false;

  } else {
    nError = RegSetValueExW(key, appName, 0, REG_DWORD, (const BYTE*) &value, sizeof(value));
    if (nError != ERROR_SUCCESS) {
      success = false;
    }

    nError = RegCloseKey(key);
    if (nError != ERROR_SUCCESS) {
      success = false;
    }
  } 

  return success;
}

static void SetBrowserFeatureControl() {
  // http://msdn.microsoft.com/en-us/library/ee330720(v=vs.85).aspx
  DWORD emulationMode = GetBrowserEmulationMode();

  if (emulationMode > 0) {
    // FeatureControl settings are per-process
    wchar_t fileName[MAX_PATH + 1];
    ZeroMemory(fileName, (MAX_PATH + 1) * sizeof(wchar_t));
    GetModuleFileNameW(NULL, fileName, 256);
    vector<string> splittedFileName = split(WString2string(fileName), '\\');
    ZeroMemory(fileName, (MAX_PATH + 1) * sizeof(wchar_t));
    wstring exeName = String2wstring(splittedFileName.at(splittedFileName.size() - 1));
    memcpy(fileName, exeName.c_str(), sizeof(wchar_t) * exeName.length());

    // make the control is not running inside Visual Studio Designer
    //if (String.Compare(fileName, "devenv.exe", true) == 0 || String.Compare(fileName, "XDesProc.exe", true) == 0) {
    //  return;
    //}

    // Windows Internet Explorer 8 and later. The FEATURE_BROWSER_EMULATION feature defines the default emulation mode for Internet
    // Explorer and supports the following values.
    // Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
    SetBrowserFeatureControlKey(L"FEATURE_BROWSER_EMULATION", fileName, emulationMode);

    // Internet Explorer 8 or later. The FEATURE_AJAX_CONNECTIONEVENTS feature enables events that occur when the value of the online
    // property of the navigator object changes, such as when the user chooses to work offline. For more information, see the ononline
    // and onoffline events.
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_AJAX_CONNECTIONEVENTS", fileName, 1);

    // Internet Explorer 9. Internet Explorer 9 optimized the performance of window-drawing routines that involve clipping regions associated
    // with child windows. This helped improve the performance of certain window drawing operations. However, certain applications hosting the
    // WebBrowser Control rely on the previous behavior and do not function correctly when these optimizations are enabled. The
    // FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION feature can disable these optimizations.
    // Default: ENABLED
    // SetBrowserFeatureControlKey(L"FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION", fileName, 1);

    // Internet Explorer 8 and later. By default, Internet Explorer reduces memory leaks caused by circular references between Internet Explorer
    // and the Microsoft JScript engine, especially in scenarios where a webpage defines an expando and the page is refreshed. If a legacy
    // application no longer functions with these changes, the FEATURE_MANAGE_SCRIPT_CIRCULAR_REFS feature can disable these improvements.
    // Default: ENABLED
    // SetBrowserFeatureControlKey(L"FEATURE_MANAGE_SCRIPT_CIRCULAR_REFS", fileName, 1);

    // Windows Internet Explorer 8. When enabled, the FEATURE_DOMSTORAGE feature allows Internet Explorer and applications hosting the WebBrowser
    // Control to use the Web Storage API. For more information, see Introduction to Web Storage.
    // Default: ENABLED
    // SetBrowserFeatureControlKey(L"FEATURE_DOMSTORAGE ", fileName, 1);

    // Internet Explorer 9. The FEATURE_GPU_RENDERING feature enables Internet Explorer to use a graphics processing unit (GPU) to render content.
    // This dramatically improves performance for webpages that are rich in graphics.
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_GPU_RENDERING ", fileName, 1);

    // Internet Explorer 9. By default, the WebBrowser Control uses Microsoft DirectX to render webpages, which might cause problems for
    // applications that use the Draw method to create bitmaps from certain webpages. In Internet Explorer 9, this method returns a bitmap
    // (in a Windows Graphics Device Interface (GDI) wrapper) instead of a GDI metafile representation of the webpage. When the
    // FEATURE_IVIEWOBJECTDRAW_DMLT9_WITH_GDI feature is enabled, the following conditions cause the Draw method to use GDI instead of DirectX
    // to create the resulting representation. The GDI representation will contain text records and vector data, but is not guaranteed to be
    // similar to the same represenation returned in earlier versions of the browser:
    //    The device context passed to the Draw method points to an enhanced metafile.
    //    The webpage is not displayed in IE9 Standards mode.
    // By default, this feature is ENABLED for applications hosting the WebBrowser Control. This feature is ignored by Internet Explorer and
    // Windows Explorer. To enable this feature by using the registry, add the name of your executable file to the following setting.
    SetBrowserFeatureControlKey(L"FEATURE_IVIEWOBJECTDRAW_DMLT9_WITH_GDI  ", fileName, 0);

    // Windows 8 introduces a new input model that is different from the Windows 7 input model. In order to provide the broadest compatibility
    // for legacy applications, the WebBrowser Control for Windows 8 emulates the Windows 7 mouse, touch, and pen input model (also known as the
    // legacy input model). When the legacy input model is in effect, the following conditions are true:
    //    Windows pointer messages are not processed by the Trident rendering engine (mshtml.dll).
    //    Document Object Model (DOM) pointer and gesture events do not fire.
    //    Mouse and touch messages are dispatched according to the Windows 7 input model.
    //    Touch selection follows the Windows 7 model ("drag to select") instead of the Windows 8 model ("tap to select").
    //    Hardware accelerated panning and zooming is disabled.
    //    The Zoom and Pan Cascading Style Sheets (CSS) properties are ignored.
    // The FEATURE_NINPUT_LEGACYMODE feature control determines whether the legacy input model is enabled
    // Default: ENABLED
    SetBrowserFeatureControlKey(L"FEATURE_NINPUT_LEGACYMODE", fileName, 0);

    // Internet Explorer 7 consolidated HTTP compression and data manipulation into a centralized component in order to improve performance and
    // to provide greater consistency between transfer encodings (such as HTTP no-cache headers). For compatibility reasons, the original
    // implementation was left in place. When the FEATURE_DISABLE_LEGACY_COMPRESSION feature is disabled, the original compression implementation
    // is used.
    // Default: ENABLED
    // SetBrowserFeatureControlKey(L"FEATURE_DISABLE_LEGACY_COMPRESSION", fileName, 1);

    // When the FEATURE_LOCALMACHINE_LOCKDOWN feature is enabled, Internet Explorer applies security restrictions on content loaded from the
    // user's local machine, which helps prevent malicious behavior involving local files:
    //    Scripts, Microsoft ActiveX controls, and binary behaviors are not allowed to run.
    //    Object safety settings cannot be overridden.
    //    Cross-domain data actions require confirmation from the user.
    // Default: DISABLED
    // SetBrowserFeatureControlKey(L"FEATURE_LOCALMACHINE_LOCKDOWN", fileName, 0);

    // Internet Explorer 7 and later. When enabled, the FEATURE_BLOCK_LMZ_??? feature allows ??? stored in the Local Machine zone to be
    // loaded only by webpages loaded from the Local Machine zone or by webpages hosted by sites in the Trusted Sites list. For more information,
    // see Security and Compatibility in Internet Explorer 7.
    // Default: DISABLED
    //    FEATURE_BLOCK_LMZ_IMG can block images that try to load from the user's local file system. To opt in, add your process name and set 
    //                          the value to 0x00000001.
    //    FEATURE_BLOCK_LMZ_OBJECT can block objects that try to load from the user's local file system. To opt in, add your process name and
    //                          set the value to 0x00000001.
    //    FEATURE_BLOCK_LMZ_SCRIPT can block script access from the user's local file system. To opt in, add your process name and set the value
    //                          to 0x00000001.
    // SetBrowserFeatureControlKey(L"FEATURE_BLOCK_LMZ_OBJECT", fileName, 0);
    // SetBrowserFeatureControlKey(L"FEATURE_BLOCK_LMZ_OBJECT", fileName, 0);
    // SetBrowserFeatureControlKey(L"FEATURE_BLOCK_LMZ_SCRIPT", fileName, 0);

    // Internet Explorer 8 and later. When enabled, the FEATURE_DISABLE_NAVIGATION_SOUNDS feature disables the sounds played when you open a
    // link in a webpage.
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_DISABLE_NAVIGATION_SOUNDS", fileName, 1);

    // Windows Internet Explorer 7 and later. Prior to Internet Explorer 7, href attributes of a objects supported the javascript prototcol;
    // this allowed webpages to execute script when the user clicked a link. For security reasons, this support was disabled in Internet
    // Explorer 7. For more information, see Event 1034 - Cross-Domain Barrier and Script URL Mitigation.
    // When enabled, the FEATURE_SCRIPTURL_MITIGATION feature allows the href attribute of a objects to support the javascript prototcol. 
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_SCRIPTURL_MITIGATION", fileName, 1);

    // For Windows 8 and later, the FEATURE_SPELLCHECKING feature controls this behavior for Internet Explorer and for applications hosting
    // the web browser control (WebOC). When fully enabled, this feature automatically corrects grammar issues and identifies misspelled words
    // for the conditions described earlier.
    //    (DWORD) 00000000 - Features are disabled.
    //    (DWORD) 00000001 - Features are enabled for the conditions described earlier. (This is the default value.)
    //    (DWORD) 00000002 - Features are enabled, but only for elements that specifically set the spellcheck attribute to true.
    SetBrowserFeatureControlKey(L"FEATURE_SPELLCHECKING", fileName, 0);

    // When enabled, the FEATURE_STATUS_BAR_THROTTLING feature limits the frequency of status bar updates to one update every 200 milliseconds.
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_STATUS_BAR_THROTTLING", fileName, 1);

    // Internet Explorer 7 or later. When enabled, the FEATURE_TABBED_BROWSING feature enables tabbed browsing navigation shortcuts and
    // notifications. For more information, see Tabbed Browsing for Developers.
    // Default: DISABLED
    // SetBrowserFeatureControlKey(L"FEATURE_TABBED_BROWSING", fileName, 1);

    // When enabled, the FEATURE_VALIDATE_NAVIGATE_URL feature control prevents Windows Internet Explorer from navigating to a badly formed URL.
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_VALIDATE_NAVIGATE_URL", fileName, 1);

    // When enabled,the FEATURE_WEBOC_DOCUMENT_ZOOM feature allows HTML dialog boxes to inherit the zoom state of the parent window.
    // Default: DISABLED
    SetBrowserFeatureControlKey(L"FEATURE_WEBOC_DOCUMENT_ZOOM", fileName, 1);

    // The FEATURE_WEBOC_POPUPMANAGEMENT feature allows applications hosting the WebBrowser Control to receive the default Internet Explorer
    // pop-up window management behavior.
    // Default: ENABLED
    SetBrowserFeatureControlKey(L"FEATURE_WEBOC_POPUPMANAGEMENT", fileName, 0);

    // Applications hosting the WebBrowser Control should ensure that window resizing and movement events are handled appropriately for the
    // needs of the application. By default, these events are ignored if the WebBrowser Control is not hosted in a proper container. When enabled,
    // the FEATURE_WEBOC_MOVESIZECHILD feature allows these events to affect the parent window of the application hosting the WebBrowser Control.
    // Because this can lead to unpredictable results, it is not considered desirable behavior.
    // Default: DISABLED
    // SetBrowserFeatureControlKey(L"FEATURE_WEBOC_MOVESIZECHILD", fileName, 0);

    // The FEATURE_ADDON_MANAGEMENT feature enables applications hosting the WebBrowser Control
    // to respect add-on management selections made using the Add-on Manager feature of Internet Explorer.
    // Add-ons disabled by the user or by administrative group policy will also be disabled in applications that enable this feature.
    SetBrowserFeatureControlKey(L"FEATURE_ADDON_MANAGEMENT", fileName, 0); 

    // Internet Explorer 10. When enabled, the FEATURE_WEBSOCKET feature allows script to create and use WebSocket objects.
    // The WebSocketobject allows websites to request data across domains from your browser by using the WebSocket protocol.
    // Default: ENABLED
    SetBrowserFeatureControlKey(L"FEATURE_WEBSOCKET", fileName, 1);

    // When enabled, the FEATURE_WINDOW_RESTRICTIONS feature adds several restrictions to the size and behavior of popup windows:
    //    Popup windows must appear in the visible display area.
    //    Popup windows are forced to have status and address bars.
    //    Popup windows must have minimum sizes.
    //    Popup windows cannot cover important areas of the parent window.
    // When enabled, this feature can be configured differently for each security zone by using the URLACTION_FEATURE_WINDOW_RESTRICTIONS URL
    // action flag. 
    // Default: ENABLED
    SetBrowserFeatureControlKey(L"FEATURE_WINDOW_RESTRICTIONS", fileName, 0);

    // Internet Explorer 7 and later. The FEATURE_XMLHTTP feature enables or disables the native XMLHttpRequest object.
    // Default: ENABLED
    // SetBrowserFeatureControlKey(L"FEATURE_XMLHTTP", fileName, 1);
  }
}

static LONG GetDWORDRegKey(HKEY hKey, const std::wstring &strValueName, DWORD &nValue, DWORD nDefaultValue) {
  nValue = nDefaultValue;
  DWORD dwBufferSize(sizeof(DWORD));
  DWORD nResult(0);
  LONG nError = ::RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, reinterpret_cast<LPBYTE>(&nResult), &dwBufferSize);
  if (ERROR_SUCCESS == nError) {
    nValue = nResult;
  }

  return nError;
}

static LONG GetStringRegKey(HKEY hKey, const std::wstring &strValueName, std::wstring &strValue, const std::wstring &strDefaultValue) {
  strValue = strDefaultValue;
  WCHAR szBuffer[512];
  DWORD dwBufferSize = sizeof(szBuffer);
  ULONG nError;
  nError = RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize);
  if (ERROR_SUCCESS == nError) {
    strValue = szBuffer;
  }
  return nError;
}

static DWORD GetBrowserEmulationMode() {
  int browserVersion = 7;
  wstring sBrowserVersion;
  HKEY key;
  bool success = true;
  BYTE data[256];
  wstring path(L"SOFTWARE\\Microsoft\\Internet Explorer");
  LONG nError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_QUERY_VALUE, &key);
  DWORD mode = 10000; // Internet Explorer 10. Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode. Default value for Internet Explorer 10.

  if (nError != ERROR_SUCCESS) {
    success = false;
  } else {
    nError = GetStringRegKey(key, L"svcVersion", sBrowserVersion, L"7");
    if (nError != ERROR_SUCCESS) {
      nError = GetStringRegKey(key, L"version", sBrowserVersion, L"7");
      if (nError != ERROR_SUCCESS) {
        success = false;
      }
    }

   if (RegCloseKey(key) != ERROR_SUCCESS) {
      success = false;
    }
  }

  if (success) {
    browserVersion = std::atoi(split(WString2string(sBrowserVersion), '.').at(0).c_str()); // convert base 16 number in s to int

    switch (browserVersion) {
    case 7:
      mode = 7000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode. Default value for applications hosting the WebBrowser Control.
      break;
    case 8:
      mode = 8000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode. Default value for Internet Explorer 8
      break;
    case 9:
      mode = 9000; // Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode. Default value for Internet Explorer 9.
      break;
    default:
      // use IE10 mode by default
      break;
    }

  } else {
    mode = -1;
  }

  return mode;
}

关于c++ - IWebbrowser2 IE=edge 和用户代理字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21339074/

有关c++ - IWebbrowser2 IE=edge 和用户代理字符串的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  3. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  4. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  5. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  6. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  7. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  8. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  9. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

  10. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

随机推荐