Why can I change the Registry only the first time? - c#

I am attempting to write an application that automatically changes the proxy server based upon what network connection is active. In this application, the user can also manually click a server in the notifyIcon context menu and call the function to switch the server.
My problem is the following: The application changes the proxy server the first time the function is called, but will not work after that. I have put debug statements in to make sure the correct proxy server is being passed to that function (and it is indeed correct), but the registry entries never get changed after the first time. What am I doing wrong?
Here is my Proxy Class:
class Proxy
{
[DllImport("wininet.dll")]
public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
public const int INTERNET_OPTION_SETTINGS_CHANGED = 39;
public const int INTERNET_OPTION_REFRESH = 37;
static bool settingsReturn, refreshReturn;
public void SetProxy(ProxyList proxy)
{
RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
registry.SetValue("ProxyEnable", 1);
registry.SetValue("ProxyServer", proxy.server + ":" + proxy.port);
registry.Close();
// These lines implement the Interface in the beginning of program
// They cause the OS to refresh the settings, causing IP to realy update
settingsReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
}
}
And here is how I call the function from the context menu:
void Form1_Click(object sender, EventArgs e)
{
Proxy proxyServer = new Proxy();
ToolStripMenuItem item = (ToolStripMenuItem)sender;
proxyServer.SetProxy(XML.proxy[(int)item.Tag]);
proxyServer = null;
notifyIcon1.BalloonTipText = XML.proxy[(int)item.Tag].name + " is now your Active Proxy";
notifyIcon1.ShowBalloonTip(1);
}

From Microsoft's Knowledge Base: How to programmatically query and set proxy settings under Internet Explorer
Note INTERNET_OPTION_PER_CONNECTION_OPTION causes the settings to be changed on a system-wide basis when a NULL handle is used. To correctly reflect global proxy settings, you must call the InternetSetOption function with the INTERNET_OPTION_REFRESH option flag.
This is from MSDN
INTERNET_OPTION_PER_CONNECTION_OPTION
75
Sets or retrieves an INTERNET_PER_CONN_OPTION_LIST structure that specifies a list of options for a particular connection. This is used by InternetQueryOption and InternetSetOption. This option is only valid in Internet Explorer 5 and later.
Read about the INTERNET_PER_CONN_OPTION_LIST structure.
Note: the value for the INTERNET_PER_CONN_PROXY_SERVER flag is 2.

RegistryKey class is disposable. Maybe it is being cached or something, try disposing it in addition of closing it.

i think you'd better do a plug-in for your browser instead of changing the registry directly.

Related

WPF app log out from Azure ACS [duplicate]

I am working with the Webbrowser control on a windows.form application written in C#. I would like to write a method for deleting the cookies from the Webbrowers control after it visits a certain site. Unfortunately, I don't know how to do that exactly and haven't found a lot of help on the internet.
If anyone has experience actually doing this, not just hypothetical because it might be trickier than it seems, I don't know.
int count = webBrowser2.Document.Cookie.Length;
webBrowser2.Document.Cookie.Remove(0,count);
I would just assume something like the above code would work but I guess it won't. Can anyone shed some light on this whole cookie thing?
If you have JavaScript enabled you can just use this code snippet to clear to clear the cookies for the site the webbrowser is currently on.
webBrowser.Navigate("javascript:void((function(){var a,b,c,e,f;f=0;a=document.cookie.split('; ');for(e=0;e<a.length&&a[e];e++){f++;for(b='.'+location.host;b;b=b.replace(/^(?:%5C.|[^%5C.]+)/,'')){for(c=location.pathname;c;c=c.replace(/.$/,'')){document.cookie=(a[e]+'; domain='+b+'; path='+c+'; expires='+new Date((new Date()).getTime()-1e11).toGMTString());}}}})())")
It's derived from this bookmarklet for clearing cookies.
I modified the solution from here:
http://mdb-blog.blogspot.ru/2013/02/c-winforms-webbrowser-clear-all-cookies.html
Actually, you don't need an unsafe code. Here is the helper class that works for me:
public static class WinInetHelper
{
public static bool SupressCookiePersist()
{
// 3 = INTERNET_SUPPRESS_COOKIE_PERSIST
// 81 = INTERNET_OPTION_SUPPRESS_BEHAVIOR
return SetOption(81, 3);
}
public static bool EndBrowserSession()
{
// 42 = INTERNET_OPTION_END_BROWSER_SESSION
return SetOption(42, null);
}
static bool SetOption(int settingCode, int? option)
{
IntPtr optionPtr = IntPtr.Zero;
int size = 0;
if (option.HasValue)
{
size = sizeof (int);
optionPtr = Marshal.AllocCoTaskMem(size);
Marshal.WriteInt32(optionPtr, option.Value);
}
bool success = InternetSetOption(0, settingCode, optionPtr, size);
if (optionPtr != IntPtr.Zero) Marshal.Release(optionPtr);
return success;
}
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool InternetSetOption(
int hInternet,
int dwOption,
IntPtr lpBuffer,
int dwBufferLength
);
}
You call SupressCookiePersist somewhere at the start of the process and
EndBrowserSession to clear cookies when browser is closed as described here:
Facebook multi account
I found a solution, for deleting all cookies.
the example found on the url, deletes the cookies on application (process) startup.
http://mdb-blog.blogspot.com/2013/02/c-winforms-webbrowser-clear-all-cookies.html
The solution is using InternetSetOption
Function to announce the WEBBROWSER to clear all its content.
int option = (int)3/* INTERNET_SUPPRESS_COOKIE_PERSIST*/;
int* optionPtr = &option;
bool success = InternetSetOption(0, 81/*INTERNET_OPTION_SUPPRESS_BEHAVIOR*/, new IntPtr(optionPtr), sizeof(int));
if (!success)
{
MessageBox.Show("Something went wrong !>?");
}
Note, that clears the cookies for the specific PROCESS only as written on MSDN INTERNET_OPTION_SUPPRESS_BEHAVIOR:
A general purpose option that is used to suppress behaviors on a
process-wide basis.
A variant of other proposed answers, which doesn't require unsafe code or manual marshalling:
private static void SuppressCookiePersistence()
{
int flag = INTERNET_SUPPRESS_COOKIE_PERSIST;
if (!InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SUPPRESS_BEHAVIOR, ref flag, sizeof(int)))
{
var ex = Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
throw ex;
}
}
const int INTERNET_OPTION_SUPPRESS_BEHAVIOR = 81;
const int INTERNET_SUPPRESS_COOKIE_PERSIST = 3;
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, ref int flag, int dwBufferLength);
web browser control based on Internet Explorer , so when we delete IE cookies,web browser cookies deleted too. so by this answer you can try this:
System.Diagnostics.Process.Start("CMD.exe","/C RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 2");
Try using this:
System.IO.File.Delete(Environment.SpecialFolder.Cookies.ToString() + "cookiename");
I'm using this code and it works without JavaScript. It's doing the same things as the JavaScript, but in VB.NET. Also, no navigation needed.
For Each cookie As String In Document.Cookie.Split(";"c)
Dim domain As String = "." + url.Host
While domain.Length > 0
Dim path As String = url.LocalPath
While path.Length > 0
Document.Cookie = cookie.Split("="c)(0).Trim & "= ;expires=Thu, 30-Oct-1980 16:00:00 GMT;path=" & path & ";domain=" & domain
path = path.Substring(0, path.Length - 1)
End While
Select Case domain.IndexOf(".")
Case 0
domain = domain.Substring(1)
Case -1
domain = ""
Case Else
domain = domain.Substring(domain.IndexOf("."))
End Select
End While
Next
The only real difference from the JavaScript is where, instead of just expiring cookie=value, I specifically search for the = and expire cookie=. This is important for expiring cookies that have no value.
Pitfalls:
You can only delete the cookies of the website to which you have navigated.
If the page is redirected to a different domain, the cookies you remove might be from the redirected domain. Or not, it's a race between the redirect and your code.
Don't access Document until ReadyState = WebBrowserReadyState.Complete, otherwise Document will be Nothing and the dereference will throw an exception.
Probably lots of others, but this code works great for me.
Firefox with the View Cookies Add-On helped a lot in debugging specific web pages.
Does the webbrowser control show pages form mutliple sites that you, as a developer, are not in control of, or are you just using the web browser control to view custom HTML pages created within your application?
If it is the former, cookies are directly tied to the domain that sets them, and as such to delete these cookies you would need to monitor the users's cookie directory and delete any new cookies created, a track changes to existing cookies.
If it is the later, you can always send the webbrowser control to a custom page that deletes the cookies with either server-side scripting (if available in your application) or JavaScript.
webBrowser.Navigate("javascript:void((function(){var a,b,c,e,f;f=0;a=document.cookie.split('; ');for(e=0;e<a.length&&a[e];e++){f++;for(b='.'+location.host;b;b=b.replace(/^(?:%5C.|[^%5C.]+)/,'')){for(c=location.pathname;c;c=c.replace(/.$/,'')){document.cookie=(a[e]+'; domain='+b+'; path='+c+'; expires='+new Date((new Date()).getTime()-1e11).toGMTString());}}}})())")
After a great time finding how destroy sessions in webbrowser C# I'm have sucessfull using a code:
webBrowser.Navigate("javascript:void((function(){var a,b,c,e,f;f=0;a=document.cookie.split('; ');for(e=0;e<a.length&&a[e];e++){f++;for(b='.'+location.host;b;b=b.replace(/^(?:%5C.|[^%5C.]+)/,'')){for(c=location.pathname;c;c=c.replace(/.$/,'')){document.cookie=(a[e]+'; domain='+b+'; path='+c+'; expires='+new Date((new Date()).getTime()-1e11).toGMTString());}}}})())")
how says for Jordan Milne in this topic above.
In my application I need use webbrowser1.navigate("xxx");
here don't work if you use the C# properties.
i hope you find it useful this information.

Delete all WebBrowser cookies and session data also set referer [duplicate]

I am working with the Webbrowser control on a windows.form application written in C#. I would like to write a method for deleting the cookies from the Webbrowers control after it visits a certain site. Unfortunately, I don't know how to do that exactly and haven't found a lot of help on the internet.
If anyone has experience actually doing this, not just hypothetical because it might be trickier than it seems, I don't know.
int count = webBrowser2.Document.Cookie.Length;
webBrowser2.Document.Cookie.Remove(0,count);
I would just assume something like the above code would work but I guess it won't. Can anyone shed some light on this whole cookie thing?
If you have JavaScript enabled you can just use this code snippet to clear to clear the cookies for the site the webbrowser is currently on.
webBrowser.Navigate("javascript:void((function(){var a,b,c,e,f;f=0;a=document.cookie.split('; ');for(e=0;e<a.length&&a[e];e++){f++;for(b='.'+location.host;b;b=b.replace(/^(?:%5C.|[^%5C.]+)/,'')){for(c=location.pathname;c;c=c.replace(/.$/,'')){document.cookie=(a[e]+'; domain='+b+'; path='+c+'; expires='+new Date((new Date()).getTime()-1e11).toGMTString());}}}})())")
It's derived from this bookmarklet for clearing cookies.
I modified the solution from here:
http://mdb-blog.blogspot.ru/2013/02/c-winforms-webbrowser-clear-all-cookies.html
Actually, you don't need an unsafe code. Here is the helper class that works for me:
public static class WinInetHelper
{
public static bool SupressCookiePersist()
{
// 3 = INTERNET_SUPPRESS_COOKIE_PERSIST
// 81 = INTERNET_OPTION_SUPPRESS_BEHAVIOR
return SetOption(81, 3);
}
public static bool EndBrowserSession()
{
// 42 = INTERNET_OPTION_END_BROWSER_SESSION
return SetOption(42, null);
}
static bool SetOption(int settingCode, int? option)
{
IntPtr optionPtr = IntPtr.Zero;
int size = 0;
if (option.HasValue)
{
size = sizeof (int);
optionPtr = Marshal.AllocCoTaskMem(size);
Marshal.WriteInt32(optionPtr, option.Value);
}
bool success = InternetSetOption(0, settingCode, optionPtr, size);
if (optionPtr != IntPtr.Zero) Marshal.Release(optionPtr);
return success;
}
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool InternetSetOption(
int hInternet,
int dwOption,
IntPtr lpBuffer,
int dwBufferLength
);
}
You call SupressCookiePersist somewhere at the start of the process and
EndBrowserSession to clear cookies when browser is closed as described here:
Facebook multi account
I found a solution, for deleting all cookies.
the example found on the url, deletes the cookies on application (process) startup.
http://mdb-blog.blogspot.com/2013/02/c-winforms-webbrowser-clear-all-cookies.html
The solution is using InternetSetOption
Function to announce the WEBBROWSER to clear all its content.
int option = (int)3/* INTERNET_SUPPRESS_COOKIE_PERSIST*/;
int* optionPtr = &option;
bool success = InternetSetOption(0, 81/*INTERNET_OPTION_SUPPRESS_BEHAVIOR*/, new IntPtr(optionPtr), sizeof(int));
if (!success)
{
MessageBox.Show("Something went wrong !>?");
}
Note, that clears the cookies for the specific PROCESS only as written on MSDN INTERNET_OPTION_SUPPRESS_BEHAVIOR:
A general purpose option that is used to suppress behaviors on a
process-wide basis.
A variant of other proposed answers, which doesn't require unsafe code or manual marshalling:
private static void SuppressCookiePersistence()
{
int flag = INTERNET_SUPPRESS_COOKIE_PERSIST;
if (!InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SUPPRESS_BEHAVIOR, ref flag, sizeof(int)))
{
var ex = Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
throw ex;
}
}
const int INTERNET_OPTION_SUPPRESS_BEHAVIOR = 81;
const int INTERNET_SUPPRESS_COOKIE_PERSIST = 3;
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, ref int flag, int dwBufferLength);
web browser control based on Internet Explorer , so when we delete IE cookies,web browser cookies deleted too. so by this answer you can try this:
System.Diagnostics.Process.Start("CMD.exe","/C RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 2");
Try using this:
System.IO.File.Delete(Environment.SpecialFolder.Cookies.ToString() + "cookiename");
I'm using this code and it works without JavaScript. It's doing the same things as the JavaScript, but in VB.NET. Also, no navigation needed.
For Each cookie As String In Document.Cookie.Split(";"c)
Dim domain As String = "." + url.Host
While domain.Length > 0
Dim path As String = url.LocalPath
While path.Length > 0
Document.Cookie = cookie.Split("="c)(0).Trim & "= ;expires=Thu, 30-Oct-1980 16:00:00 GMT;path=" & path & ";domain=" & domain
path = path.Substring(0, path.Length - 1)
End While
Select Case domain.IndexOf(".")
Case 0
domain = domain.Substring(1)
Case -1
domain = ""
Case Else
domain = domain.Substring(domain.IndexOf("."))
End Select
End While
Next
The only real difference from the JavaScript is where, instead of just expiring cookie=value, I specifically search for the = and expire cookie=. This is important for expiring cookies that have no value.
Pitfalls:
You can only delete the cookies of the website to which you have navigated.
If the page is redirected to a different domain, the cookies you remove might be from the redirected domain. Or not, it's a race between the redirect and your code.
Don't access Document until ReadyState = WebBrowserReadyState.Complete, otherwise Document will be Nothing and the dereference will throw an exception.
Probably lots of others, but this code works great for me.
Firefox with the View Cookies Add-On helped a lot in debugging specific web pages.
Does the webbrowser control show pages form mutliple sites that you, as a developer, are not in control of, or are you just using the web browser control to view custom HTML pages created within your application?
If it is the former, cookies are directly tied to the domain that sets them, and as such to delete these cookies you would need to monitor the users's cookie directory and delete any new cookies created, a track changes to existing cookies.
If it is the later, you can always send the webbrowser control to a custom page that deletes the cookies with either server-side scripting (if available in your application) or JavaScript.
webBrowser.Navigate("javascript:void((function(){var a,b,c,e,f;f=0;a=document.cookie.split('; ');for(e=0;e<a.length&&a[e];e++){f++;for(b='.'+location.host;b;b=b.replace(/^(?:%5C.|[^%5C.]+)/,'')){for(c=location.pathname;c;c=c.replace(/.$/,'')){document.cookie=(a[e]+'; domain='+b+'; path='+c+'; expires='+new Date((new Date()).getTime()-1e11).toGMTString());}}}})())")
After a great time finding how destroy sessions in webbrowser C# I'm have sucessfull using a code:
webBrowser.Navigate("javascript:void((function(){var a,b,c,e,f;f=0;a=document.cookie.split('; ');for(e=0;e<a.length&&a[e];e++){f++;for(b='.'+location.host;b;b=b.replace(/^(?:%5C.|[^%5C.]+)/,'')){for(c=location.pathname;c;c=c.replace(/.$/,'')){document.cookie=(a[e]+'; domain='+b+'; path='+c+'; expires='+new Date((new Date()).getTime()-1e11).toGMTString());}}}})())")
how says for Jordan Milne in this topic above.
In my application I need use webbrowser1.navigate("xxx");
here don't work if you use the C# properties.
i hope you find it useful this information.

Modifying Proxy Settings within C#

I have the following snippet of code here that im trying to build to automatically change the proxy settings:
public class ProxyManager
{
public static bool UnsetProxy()
{
return SetProxy(null);
}
public static bool SetProxy(string Ip,int Port)
{
return SetProxy(Ip + ":" + Port.ToString());
}
public static bool SetProxy(string ProxyAddress)
{
RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
if (ProxyAddress == null)
{
registry.SetValue("ProxyEnable", 0);
}
else
{
registry.SetValue("ProxyEnable", 1);
registry.SetValue("ProxyServer", ProxyAddress.ToString());
}
//Force the update!
registry.Clase();
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
return true;
}
[DllImport("wininet.dll")]
public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
public const int INTERNET_OPTION_SETTINGS_CHANGED = 39;
public const int INTERNET_OPTION_REFRESH = 37;
}
But for some reason the proxy settings are not being set, I know the method is being executed correctly as I insert an event into the Event Manger after the method is called and that is visible.
For some reason though the proxy settings are not, I'me calling the function like so:
EventManager.WriteEntry("Proxy Settings Enabled");
ProxyManager.SetProxy("10.222.62.65:8080");
My application is a windows service and is running under the authority of the Local System Account which has full privileges.
I suspect that it might be a combination of the fact that you're using the code Registry.CurrentUser and that it's running under the Local System Account.
The combination of those two snippets of your question makes me think that you might be changing the settings for the wrong user account? I'd suggest trying to run the service under your account and see if that makes any difference (assuming that this is possible due to UAC etc).
i wrote a similar program for disabling network adapters and changing proxy. It is at tognet.codeplex.com. I have experienced that // Force the update code somehow does not wan to refresh proxy settings on a windows 7 box. If i restart IE and look at the proxy settings again only then it shows the correct state of the proxy.
The reason is that you are changing the registry branch of CURRENT_USER, so there are actually two different branches - for your own user, and for Local System. And when you are running as Windows Service, you are changing the other branch. So actually you set the values, bot for a totally defferent user.
So what you need - is to get SID of your user, and then save it somewhere, so your service could use it, and access the correct branch (the one that is owned by your user). The code below tested on Windows 10.
public static RegistryKey? GetCurrentUserKey()
{
var sidString = GetSidFromLocalMachine();
if (string.IsNullOrWhiteSpace(sidString))
{
sidString = WindowsIdentity.GetCurrent().User?.ToString();
}
if (string.IsNullOrWhiteSpace(sidString))
return null;
RegistryKey resultKey = Registry.Users.OpenSubKey(sidString + "\\", true);
return resultKey;
}
public static string GetSidFromLocalMachine()
{
var settingsKey = Registry.LocalMachine.OpenSubKey(regKeyInternetSettings, true);
if (settingsKey != null)
return settingsKey.GetValue(regSid).ToString();
return string.Empty;
}
public static bool SaveSidToLocalMachine(string sid)
{
if (string.IsNullOrWhiteSpace(sid))
return false;
var settingsKey = Registry.LocalMachine.OpenSubKey(regKeyInternetSettings, true);
if (settingsKey == null)
return false;
settingsKey.SetValue("SID", sid);
settingsKey.Close();
return true;
}
You need to call SaveSidToLocalMachine before running the service, or set it manually. Then any time you need to load any registry key from your service, just call
var key = GetCurrentUserKey()?.OpenSubKey(regKeyInternetSettings, true);
key.SetValue("ProxyEnable", 1);
key.Close();
And don't forget to refresh:
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);

.NET Setup Project - Changing Registry Settings

I have a class that modifies the ProxyEnable and ProxyServer registry keys of Internet Settings.
If I use this class in a Console App and run it the value are changed and I can see the changes using regedit.
Now the part that doesn't work is I am trying to use this class in an Installer class so that the registry keys are changed during installation of my application.
Here is the code for the class:
public class ProxySettings {
[DllImport("wininet.dll")]
public static extern bool InternetSetOption(IntPtr hInternet, int dwOption,
IntPtr lpBuffer, int dwBufferLength);
public const int INTERNET_OPTION_SETTINGS_CHANGED = 39;
public const int INTERNET_OPTION_REFRESH = 37;
static bool settingsReturn, refreshReturn;
public void EnableProxy(string proxy) {
RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
registry.SetValue("ProxyEnable", 1);
registry.SetValue("ProxyServer", proxy);
settingsReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED,
IntPtr.Zero, 0);
refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
}
public void DisableProxy() {
RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
registry.SetValue("ProxyEnable", 0);
registry.DeleteValue("ProxyServer", false);
settingsReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED,
IntPtr.Zero, 0);
refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
}
}
Here is my Installer class:
[RunInstaller(true)]
public class WindowsServiceInstaller : Installer {
public WindowsServiceInstaller() {
ServiceProcessInstaller serviceProcessInstaller =
new ServiceProcessInstaller();
ServiceInstaller serviceInstaller = new ServiceInstaller();
//# Service Account Information
serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
serviceProcessInstaller.Username = null;
serviceProcessInstaller.Password = null;
//# Service Information
serviceInstaller.DisplayName = "Client Service";
serviceInstaller.StartType = ServiceStartMode.Automatic;
//# This must be identical to the WindowsService.ServiceBase name
//# set in the constructor of WindowsService.cs
serviceInstaller.ServiceName = "Client Service";
this.Installers.Add(serviceProcessInstaller);
this.Installers.Add(serviceInstaller);
}
public override void Commit(System.Collections.IDictionary savedState) {
base.Commit(savedState);
ServiceController controller = new ServiceController("Client Service");
if(controller.Status != ServiceControllerStatus.Running) {
controller.Start();
}
ProxySettings proxy = new ProxySettings();
proxy.EnableProxy("127.0.0.1:8889");
}
public override void Uninstall(System.Collections.IDictionary savedState) {
base.Uninstall(savedState);
ProxySettings proxy = new ProxySettings();
proxy.DisableProxy();
}
}
In the override of Commit I am starting the service which works fine but for some reason I don't see the changes to the registry.
Just too make sure the class was initializing and firing I added
System.Diagnostics.Process.Start("http://www.microsoft.com");
to both the EnableProxy and DisableProxy methods. During the install the website opened and also during uninstall but the registry remained unchanged.
What am I doing wrong? Why will it work running as a Console App but not in an Installer?
I can't say for sure why it works in the Console app and not the installer, but I notice that you're neither disposing nor directly flushing the registry key.
Try replacing the code in your EnableProxy with this (and similarly with DisableProxy) and see what happens:
using (RegistryKey registry = Registry.CurrentUser.OpenSubKey(
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true))
{
registry.SetValue("ProxyEnable", 1);
registry.SetValue("ProxyServer", proxy);
}
(This is one of many reasons why you should always dispose an IDisposable)
Okay, I have figured out what was going on.
I had the installer set to install for Everyone. I tried installing and selecting Just Me and it worked.
I guess that makes sense since I was setting a registry key for the current user but was installing for everyone. Does this sound right?
Anyway, I now have some more testing to do to see if the software will function correctly if installed for Just Me. The application is a Windows Service.

How to clear System.Windows.Forms.WebBrowser session data?

How can I clear current session data (cookies, cached data, auth sessions, etc) without restarting the application?
Update: I'm talking about WebBrowser control in Windows.Forms, not the ASP.Net session.
To clear session (such as HttpOnly cookies), you can use InternetSetOption() from wininet.dll.
private const int INTERNET_OPTION_END_BROWSER_SESSION = 42;
[DllImport("wininet.dll", SetLastError = true)]
private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength);
and use this method whenever need to clear session.
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_END_BROWSER_SESSION, IntPtr.Zero, 0);
webBrowser1.Document.Window.Navigate(url);
I tried everything to clear the form data so the next user would not see the previous email address, etc. I ended up doing this to clear the cookies...
string[] theCookies = System.IO.Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.Cookies));
foreach (string currentFile in theCookies)
{
try
{
System.IO.File.Delete(currentFile);
}
catch (Exception ex)
{
}
}
If you have javascript enabled you can just use this code snippet to clear to clear the cookies for the site the webbrowser is currently on (I haven't yet found a way to clear session cookies other than this).
webBrowser.Navigate("javascript:void((function(){var a,b,c,e,f;f=0;a=document.cookie.split('; ');for(e=0;e<a.length&&a[e];e++){f++;for(b='.'+location.host;b;b=b.replace(/^(?:%5C.|[^%5C.]+)/,'')){for(c=location.pathname;c;c=c.replace(/.$/,'')){document.cookie=(a[e]+'; domain='+b+'; path='+c+'; expires='+new Date((new Date()).getTime()-1e11).toGMTString());}}}})())")
It's derived from this bookmarklet for clearing cookies.
In addition to this, you can delete the contents of the "C:\Documents and Settings\username\Cookies" folder (minus the index.dat, which is usually locked).
As for the cached data, it should be sufficient to just delete all of the files in "C:\Documents and Settings\username\Local Settings\Temporary Internet Files".
If you really need to be able to clear the cookies for all sites, you're probably better off using something like the axWebBrowser control in the long run.
Private Const INTERNET_OPTION_END_BROWSER_SESSION As Integer = 42
<DllImport("wininet.dll", SetLastError:=True)>
Public Shared Function InternetSetOption(hInternet As IntPtr, dwOption As Integer, lpBuffer As IntPtr, lpdwBufferLength As Integer) As Boolean
End Function
Private Sub WebBrowserFormName_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Closed
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_END_BROWSER_SESSION, IntPtr.Zero, 0)
End Sub
Just posting for someone looking for this answer in VB.
Happy coding!!!
webBrowser1.Document.Cookies = "" won't work. This call will not clear the cookie. webBrowser1.Document.Cookies = just works as document.cookie in javascript.
You should find the cookie you want to clear, sa 'Session', use
webBrowser1.Document.Cookies = "Session = ''";
It will just set the cookie to '', as you want.
Following solution worked for me -
webBrowser1.Document.ExecCommand("ClearAuthenticationCache", false, null);
This was suggested in following post for deleting cookies - https://stackoverflow.com/a/21512662/6291511
You can find more info regarding this here - https://msdn.microsoft.com/en-us/library/system.windows.forms.htmldocument.execcommand(v=vs.110).aspx
Hope it helps!!!
You have to realise that the way "session state" is tracked, from the point of view of a web server, is by giving the client browser a cookie with a session-id in it. When the browser posts back to the server, that cookie allows the server to associate the request with a stored session state.
So the solution is to clear the cookies of the webBrowser control. Eg webBrowser1.Document.Cookies = "", that should work I think.
ASP.NET also has what it calls "cookieless sessions", which work by adding the session id to the url. So if that's the mechanism used by the server, you could try to filter that out of the url. But you won't see that much, it's mostly the cookie based session state.
Windows 7 uses index.dat files to store cookies and history so that Bill and his freinds at CIA central can snoop on you and have done all they can to ensure you can not delete these files and that after taking copies because 'Special Folders' are used and the .Dat files remain locked whilst windows is running.
This is not a perfect solution but it works to some degree with the full file names being in a List.
int DeletedCount = 0;
int CouldNotDelete = 0;
KillExplorer();
foreach (string DatFile in DatFiles)
{//Do not put break point or step into the code else explorer will start and the file will become locked again
DirectoryInfo DInfo=new DirectoryInfo(DatFile.Replace("index.dat",""));
FileAttributes OldDirAttrib = DInfo.Attributes;
DInfo.Attributes = FileAttributes.Normal;//Set to normal else can not delete
FileInfo FInfo = new FileInfo(DatFile);
FileAttributes OldFileAttrib = FInfo.Attributes;
SetAttr(FInfo, FileAttributes.Normal);
TryDelete(FInfo);
SetAttr(FInfo, OldFileAttrib);//Sets back to Hidden,system,directory,notcontentindexed
if (File.Exists(DatFile))
CouldNotDelete++;
else
DeletedCount++;
}
if (DatFiles.Count>0)//Lets get explorer running again
System.Diagnostics.Process.Start(DatFiles[DatFiles.Count - 1].Replace("index.dat", ""));
else
System.Diagnostics.Process.Start("explorer");
System.Windows.Forms.MessageBox.Show("Deleted " + DeletedCount + " Index.dat files with " + CouldNotDelete + " Errors");
return "Deleted " + DeleteFileCount + " Files ";
}
private void KillExplorer()
{
foreach (Process P in Process.GetProcesses())
{//Kill both these process because these are the ones locking the files
if (P.ProcessName.ToLower() == "explorer")
P.Kill();
if (P.ProcessName.ToLower() == "iexplore")
P.Kill();
}
}
private bool TryDelete(FileInfo Info)
{
try
{
Info.Delete();
return true;
}
catch
{return false;}
}
private void SetAttr(FileInfo Info,FileAttributes Attr)
{
try
{
Info.Attributes = Attr;
}
catch { }
}

Categories

Resources