1 / 1 / 0
Регистрация: 30.09.2020
Сообщений: 33
1

CefSharp проксификация. Как можно повторно поменять прокси после инициализации настроек?

06.02.2022, 11:58. Показов 1544. Ответов 3

Author24 — интернет-сервис помощи студентам
Собственно, задача простая: мне нужно загружать веб страницы на конкретном сайте, но делать это под разными прокси. По какой то причине, CefSharp позволяет инициализировать настройки только единожды. Так или иначе, я реализовал код(наскреб его то тут то там, - с миру по нитке), который задает нужный прокси, и дальше он работает с ним. "Смена" прокси в моем случае происходит путем "перезапуска", - на каждую страницу приходится запускать это приложение заново. Это создает некоторые проблемы - добавляет время на загрузку ресурсов, а также создает некоторые непонятные проблемы то ли с утечкой памяти, то ли еще с чем-то, но рабочий стол после нескольких сотен страниц "умирает", поэтому, ищу другое решение. Вот сам код:

C#
1
2
3
4
5
6
7
8
using System;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
using CefSharp.OffScreen;
using CefSharp;
using System.Runtime.InteropServices;
C#
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
class Program
    {
 
        static async Task Main(string[] args)
        {
            string path = Directory.GetCurrentDirectory();
 
            string id;
 
            string url;
 
            string pathreturn;
 
            string myipaddress;
 
            string myport;
 
            string myusername;
 
            string mypassword;
 
            id = Ini.Read(@path + @"\запрос.ini", "steam", "Id", "NotFound");
 
            url = Ini.Read(@path + @"\запрос.ini", "steam", "Adress", "NotFound");
 
            pathreturn = Ini.Read(@path + @"\запрос.ini", "steam", "Path", "NotFound");
 
            myipaddress = Ini.Read(@path + @"\запрос.ini", "steam", "myipaddress", "NotFound");
 
            myport = Ini.Read(@path + @"\запрос.ini", "steam", "myport", "NotFound");
 
            myusername = Ini.Read(@path + @"\запрос.ini", "steam", "myusername", "NotFound");
 
            mypassword = Ini.Read(@path + @"\запрос.ini", "steam", "mypassword", "NotFound");
 
 
            string LocalesDirPath = @path + @"\locales";
            string Locale = "ru";
 
            CefSharpSettings.Proxy = new ProxyOptions(ip: myipaddress, port: myport, username: myusername, password: mypassword);
 
            Browser _browser = new Browser(LocalesDirPath, Locale);
              
            _browser.OpenUrl(url);
            
            string source = "";
     
            source = await _browser.Page.GetSourceAsync();
            
 
            File.Delete(pathreturn + id + ".html");
            File.AppendAllText(pathreturn + id + ".html", source);
 
        }
    }

C#
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
public class Browser
    {
       
        /// <summary>
        /// The browser page
        /// </summary>
        public ChromiumWebBrowser Page { get; private set; }
        /// <summary>
        /// The request context
        /// </summary>
        public RequestContext RequestContext { get; private set; }
 
        // chromium does not manage timeouts, so we'll implement one
        private ManualResetEvent manualResetEvent = new ManualResetEvent(false);
 
        public Browser(string LocalesDirPath, string Locale)
        {
            var settings = new CefSettings()
            {
                //By default CefSharp will use an in-memory cache, you need to     specify a Cache Folder to persist data
                CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache"),
 
            };
            settings.LocalesDirPath = LocalesDirPath;
            settings.Locale = Locale;
            
 
            //Autoshutdown when closing
            CefSharpSettings.ShutdownOnExit = true;
 
            //Perform dependency check to make sure all relevant resources are in our     output directory.
            Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
 
            RequestContext = new RequestContext();
            Page = new ChromiumWebBrowser("", null, RequestContext);
            PageInitialize();
        }
 
        /// <summary>
        /// Open the given url
        /// </summary>
        /// <param name="url">the url</param>
        /// <returns></returns>
        public void OpenUrl(string url)
        {
            try
            {
                Page.LoadingStateChanged += PageLoadingStateChanged;
                if (Page.IsBrowserInitialized)
                {
                    Page.Load(url);
 
                    //create a 60 sec timeout 
                    bool isSignalled = manualResetEvent.WaitOne(TimeSpan.FromSeconds(60));
                    manualResetEvent.Reset();
 
                    //As the request may actually get an answer, we'll force stop when the timeout is passed
                    if (!isSignalled)
                    {
                        Page.Stop();
                    }
                }
            }
            catch (ObjectDisposedException)
            {
                //happens on the manualResetEvent.Reset(); when a cancelation token has disposed the context
            }
            Page.LoadingStateChanged -= PageLoadingStateChanged;
        }
 
        /// <summary>
        /// Manage the IsLoading parameter
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PageLoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
        {
            // Check to see if loading is complete - this event is called twice, one when loading starts
            // second time when it's finished
            if (!e.IsLoading)
            {
                manualResetEvent.Set();
            }
        }
 
        /// <summary>
        /// Wait until page initialization
        /// </summary>
        private void PageInitialize()
        {
            SpinWait.SpinUntil(() => Page.IsBrowserInitialized);
        }
    }



Собственно, хотелось бы иметь возможность задавать прокси больше 1 раза. Может кто-нибудь подскажет, как это сделать? При повторном задании прокси:
C#
1
2
3
4
5
CefSharpSettings.Proxy = new ProxyOptions(ip: myipaddress, port: myport, username: myusername, password: mypassword);
 Browser _browser = new Browser(LocalesDirPath, Locale);
 _browser.OpenUrl(url);
CefSharpSettings.Proxy = new ProxyOptions(ip: myipaddress2, port: myport2, username: myusername2, password: mypassword2);
 _browser.OpenUrl(url);
прокси не меняется, - страницы загружаются с первоначально заданным прокси. Нужна инициализация настроек.
При попытке инициализировать повторно

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Browser _browser = new Browser(LocalesDirPath, Locale);
 
 CefSharpSettings.Proxy = new ProxyOptions(ip: myipaddress, port: myport, username: myusername, password: mypassword);
 
var settings = new CefSettings()
            {
                //By default CefSharp will use an in-memory cache, you need to     specify a Cache Folder to persist data
                CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache"),
 
            };
            settings.LocalesDirPath = LocalesDirPath;
            settings.Locale = Locale;
 
            Cef.Initialize(settings);
выдает ошибку:

Код
Необработанное исключение: System.Exception: CEF can only be initialized once pe
r process. This is a limitation of the underlying CEF/Chromium framework. You ca
n change many (not all) settings at runtime through RequestContext.SetPreference
. See [url]https://github.com/cefsharp/CefSharp/wiki/General-Usage#request-context-br[/url]
owser-isolation Use Cef.IsInitialized to guard against this exception. If you ar
e seeing this unexpectedly then you are likely calling Cef.Initialize after you'
ve created an instance of ChromiumWebBrowser, it must be before the first instan
ce is created.
   в CefSharp.Core.Cef.Initialize(CefSettingsBase cefSettings, Boolean performDe
pendencyCheck, IApp cefApp) в C:\projects\cefsharp\CefSharp.Core.Runtime\Cef.h:с
трока 260
   в CefSharp.Cef.Initialize(CefSettingsBase settings) в C:\projects\cefsharp\Ce
fSharp.Core\Cef.cs:строка 111
   в chrome.Program.<Main>d__0.MoveNext() в C:\DATA\visualstudio\source\repos\ch
rome\chrome\Program.cs:строка 142
--- Конец трассировка стека из предыдущего расположения, где возникло исключение
 ---
   в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNoti
fication(Task task)
   в chrome.Program.<Main>(String[] args)
Для продолжения нажмите любую клавишу . . .
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.02.2022, 11:58
Ответы с готовыми решениями:

Проверка рабочий ли прокси в CefSharp
Здравствуйте, подскажите как можно проверить прокси сервер рабочий или нет до его инициализации в...

Можно ли сделать так, чтобы после выполнения одного оператора if, цикл начинался повторно
Вопрос: Можно ли сделать так, чтобы после выполнения одного оператора if, цикл начинался повторно?...

Чтение настроек на этапе инициализации программы
Сабж. Если организовать что-то вроде private { Private declarations } ini: TIniFile; value:...

Можно ли вставить условие для настроек валидации настроек значений свойств?
Например ,есть поле ввода и радиобаттон. в зависимости от изменения переключателя (день/месяц) в...

3
3458 / 2470 / 695
Регистрация: 02.08.2011
Сообщений: 6,692
06.02.2022, 13:13 2
В исключении есть вся необходимая информация, в том числе по Proxy Resolution:
C#
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
//Create a new RequestContext that users a specific proxy server
//By default an in memory cache is used
var requestContext = RequestContext
    .Configure()
    .WithProxyServer("127.0.0.1", 8080)
    .Create();
 
//Create a RequestContext with a proxy and cache path
//Making sure that CachePath is equal to or a child of CefSettings.RootCachePath
//See https://github.com/cefsharp/CefSharp/issues/3111#issuecomment-629713608 for more info on cache path
var requestContext = RequestContext
    .Configure()
    .WithProxyServer("127.0.0.1", 8080)
    .WithCachePath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache"))
    .Create();
 
//Set the proxy at runtime, the RequestContext must be initialized
Cef.UIThreadTaskFactory.StartNew(delegate
{
    string errorMessage;
 
    if (!requestContext.CanSetPreference("proxy"))
    {
        //Unable to set proxy, if you set proxy via command line args it cannot be modified.
    }
 
    success = requestContext.SetProxy("127.0.0.1", 8080, out errorMessage);
});
1
1 / 1 / 0
Регистрация: 30.09.2020
Сообщений: 33
06.02.2022, 15:53  [ТС] 3
Цитата Сообщение от IamRain Посмотреть сообщение
В исключении есть вся необходимая информация, в том числе по Proxy Resolution:
Посмотрел ссылку. Покопался в теме. Все очень сложно. Вот я пытаюсь реализовать :
C#
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
public class ChromeTest
    {
        public static ChromiumWebBrowser Create(WebProxy proxy = null, Action<ChromiumWebBrowser> onInited = null)
        {
            var result = default(ChromiumWebBrowser);
            var settings = new CefSharp.OffScreen.CefSettings();
            result = new ChromiumWebBrowser("about:blank");
            if (proxy != null)
                result.RequestHandler = new _requestHandler(proxy?.Credentials as NetworkCredential);
 
            result.IsBrowserInitializedChanged += (s, e) =>
            {
                if (!e.IsBrowserInitialized)
                    return;
 
                var br = (ChromiumWebBrowser)s;
                if (proxy != null)
                {
                    var v = new Dictionary<string, object>
                    {
                        ["mode"] = "fixed_servers",
                        ["server"] = $"{proxy.Address.Scheme}://{proxy.Address.Host}:{proxy.Address.Port}"
                    };
                    if (!br.GetBrowser().GetHost().RequestContext.SetPreference("proxy", v, out string error))
                        MessageBox.Show(error);
                }
 
                onInited?.Invoke(br);
            };
 
            return result;
        }
 
        private class _requestHandler : DefaultRequestHandler
        {
            private NetworkCredential _credential;
 
            public _requestHandler(NetworkCredential credential = null) : base()
            {
                _credential = credential;
            }
 
            public override bool GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
            {
                if (isProxy == true)
                {
                    if (_credential == null)
                        throw new NullReferenceException("credential is null");
 
                    callback.Continue(_credential.UserName, _credential.Password);
                    return true;
                }
 
                return false;
            }
        }
    }
Перелазил по всем директориям using закинул что можно(что имело смысл) через nuget и все равно выдает ряд ошибок(без вариантов исправления):

Код
Серьезность	Код	Описание	Проект	Файл	Строка	Состояние подавления
Ошибка	CS0246	Не удалось найти тип или имя пространства имен "DefaultRequestHandler" (возможно, отсутствует директива using или ссылка на сборку).	netframework	C:\DATA\visualstudio\source\repos\netframework\netframework\Program.cs	536	Активный
Ошибка	CS0115	'"ChromeTest._requestHandler.GetAuthCredentials(IWebBrowser, IBrowser, IFrame, bool, string, int, string, string, IAuthCallback)": не найден метод, пригодный для переопределения.	netframework	C:\DATA\visualstudio\source\repos\netframework\netframework\Program.cs	545	Активный
Ошибка	CS0104	'CefSettings" является неоднозначной ссылкой между "CefSharp.OffScreen.CefSettings" и "CefSharp.WinForms.CefSettings".	netframework	C:\DATA\visualstudio\source\repos\netframework\netframework\Program.cs	245	Активный
Ошибка	CS0104	'CefSettings" является неоднозначной ссылкой между "CefSharp.OffScreen.CefSettings" и "CefSharp.WinForms.CefSettings".	netframework	C:\DATA\visualstudio\source\repos\netframework\netframework\Program.cs	419	Активный
Ошибка	CS0266	Не удается неявно преобразовать тип "netframework.ChromeTest._requestHandler" в "CefSharp.IRequestHandler". Существует явное преобразование (возможно, пропущено приведение типов).	netframework	C:\DATA\visualstudio\source\repos\netframework\netframework\Program.cs	511	Активный
Ошибка	CS1061	"ChromiumWebBrowser" не содержит определения "IsBrowserInitializedChanged", и не удалось найти доступный метод расширения "IsBrowserInitializedChanged", принимающий тип "ChromiumWebBrowser" в качестве первого аргумента (возможно, пропущена директива using или ссылка на сборку).	netframework	C:\DATA\visualstudio\source\repos\netframework\netframework\Program.cs	513	Активный
Ошибка	CS1729	'DefaultRequestHandler" не содержит конструктор, который принимает аргументы 0.	netframework	C:\DATA\visualstudio\source\repos\netframework\netframework\Program.cs	540	Активный

Не подскажете что можно сделать?
0
3458 / 2470 / 695
Регистрация: 02.08.2011
Сообщений: 6,692
06.02.2022, 16:06 4
Это уже элементарные ошибки, судя по всему, связанные с различными версиями API, который вы используете.
По причине того, что
Цитата Сообщение от Sergey1986 Посмотреть сообщение
(наскреб его то тут то там, - с миру по нитке),
А то, что ваш
Цитата Сообщение от Sergey1986 Посмотреть сообщение
рабочий стол после нескольких сотен страниц "умирает"
Видимо, надо освобождать вовремя все ресурсы, которые уже были использованы. (Dispose-ить все IDisposable объекты).

Первоначальный ваш вопрос про Proxy должен решаться этой строкой:
C#
1
 if (!br.GetBrowser().GetHost().RequestContext.SetPreference("proxy", v, out string error))
0
06.02.2022, 16:06
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.02.2022, 16:06
Помогаю со студенческими работами здесь

Как поменять в программе путь хранения настроек
Есть программа с открытым исходным кодом (LazyCure). Мне не нравится, что она сохраняет настройки в...

получение настроек прокси из IE
Всем привет. Вопрос в название темы. Как получить настройки прокси из Internet Explorer (или из...

Как поменять прокси!
Нужно короче написать прогу чтобы меняла прокси и заходила на сайт подскажите плиз как с помощью...

Сброс настроек прокси сервера
Здравствуйте. Пишу небольшой проксик. Нашел код, который позволяет настроить компьютер на...

Как повторно открыть форму после ее закрытия и одновременного сохранения данных в ячейку?
Private Sub НазваниеКнопки_Click() User_form.Hide End Sub При выполнении этого скрипта...

Цвет текста в консоли как поменять из своего класса настроек?
class Settings { public string FontColor = &quot;DarkGreen&quot;; // Цвет текста используемый...

Изменение настроек подключения к прокси-серверу
Здравствуйте! Уже второй день не могу решить проблему с подключение к прокси... Нашел в сети код, ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru