How do I find out the browser's proxy settings? - windows

I am writing a command-line tool for Windows that uses libcurl to download files from the internet.
Obviously, the downloading doesn't work when the user is behind a proxy server, because the proxy needs to be configured. I want to keep my tool as simple as possible however, and not have to burden the user with having to configure the proxy. My tool doesn't even have a config file, so the user would otherwise have to pass in the proxy settings on every command, or set an environment variable or somesuch -- way too much hassle.
So I thought, everyone's browser will usually already be set up properly, proxy configured and everything. This will be true for even the most basic user because otherwise "their internet wouldn't work".
So I figure that I can find out whether to use a proxy by looking at IE's proxy settings.
How do I go about this? More specifically:
Is there one set of "proxy settings" in Windows, used by all browsers (probably IE's), or would I have to write different routines for IE, Firefox, Opera, etc?
I know that I can probably read the values directly out of the appropriate registry locations if they are configured manually, but does this also work with "automatically detect proxy server?" Do I even have to bother with that option, or is it (almost) never used?
Before people start suggesting alternatives: I'm using C, so I'm limited to the Win32 API, and I really really want to keep using C and libcurl.

The function you're looking for is WinHttpGetIEProxyConfigForCurrentUser(), which is documented at http://msdn.microsoft.com/en-us/library/aa384096(VS.85).aspx. This function is used by Firefox and Opera to get their proxy settings by default, although you can override them per-browser. Don't do that, though. The right thing to do (which is what everybody else does) is to just get the IE settings and assume that they're correct, since they almost always are.
Here's a sample of the relevant logic, which you should adapt for your needs:
if( WinHttpGetIEProxyConfigForCurrentUser( &ieProxyConfig ) )
{
if( ieProxyConfig.fAutoDetect )
{
fAutoProxy = TRUE;
}
if( ieProxyConfig.lpszAutoConfigUrl != NULL )
{
fAutoProxy = TRUE;
autoProxyOptions.lpszAutoConfigUrl = ieProxyConfig.lpszAutoConfigUrl;
}
}
else
{
// use autoproxy
fAutoProxy = TRUE;
}
if( fAutoProxy )
{
if ( autoProxyOptions.lpszAutoConfigUrl != NULL )
{
autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
}
else
{
autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
}
// basic flags you almost always want
autoProxyOptions.fAutoLogonIfChallenged = TRUE;
// here we reset fAutoProxy in case an auto-proxy isn't actually
// configured for this url
fAutoProxy = WinHttpGetProxyForUrl( hiOpen, pwszUrl, &autoProxyOptions, &autoProxyInfo );
}
if ( fAutoProxy )
{
// set proxy options for libcurl based on autoProxyInfo
}
else
{
if( ieProxyConfig.lpszProxy != NULL )
{
// IE has an explicit proxy. set proxy options for libcurl here
// based on ieProxyConfig
//
// note that sometimes IE gives just a single or double colon
// for proxy or bypass list, which means "no proxy"
}
else
{
// there is no auto proxy and no manually configured proxy
}
}

Here is a complete code sample how to call WinHttpGetIEProxyConfigForCurrentUser method from winhttp.dll library in C#
[TestClass]
public class UnitTest1
{
[StructLayout(LayoutKind.Sequential)]
public struct WinhttpCurrentUserIeProxyConfig
{
[MarshalAs(UnmanagedType.Bool)]
public bool AutoDetect;
[MarshalAs(UnmanagedType.LPWStr)]
public string AutoConfigUrl;
[MarshalAs(UnmanagedType.LPWStr)]
public string Proxy;
[MarshalAs(UnmanagedType.LPWStr)]
public string ProxyBypass;
}
[DllImport("winhttp.dll", SetLastError = true)]
static extern bool WinHttpGetIEProxyConfigForCurrentUser(ref WinhttpCurrentUserIeProxyConfig pProxyConfig);
[TestMethod]
public void TestMethod1()
{
var config = new WinhttpCurrentUserIeProxyConfig();
WinHttpGetIEProxyConfigForCurrentUser(ref config);
Console.WriteLine(config.Proxy);
Console.WriteLine(config.AutoConfigUrl);
Console.WriteLine(config.AutoDetect);
Console.WriteLine(config.ProxyBypass);
}
}

There are registry keys for these values that you could get to directly of course. You could also do this in .NET without much hassle at all. I believe the WebClient object negotiates the proxy settings for you based on the current settings. This would look like this in C#:
using System.Net;
string url = "http://www.example.com";
WebClient client = new WebClient();
byte[] fileBuffer = client.DownloadFile(url);
Or something close to that.

For Firefox/Seamonkey, the problem is a bit more tricky because of the existence of many profiles.
If you want to assume there is only one profile then you just need to find prefs.js. You parse the network.proxy.type, and then use it to decide, which related values to read.
I'm working on some documents for mozilla, so put your followup questions in here (checked wiki box), and I'll try to give you the info you need.

Related

Persistent Storage using Application.Current.Properties not working

I'm trying to achieve a persistent storage in Xamarin.Forms. After researching in Xamarin.Forms, I decided to use Application.Current.Properties property.
It looks like it is working just only if the app still remains alive. If I close the app and start it again the Application.Current.Properties is empty.
Does anyone know if I'm doing something wrong? Can I achieve this feature in another way?
As usual, thanks guys.
I have had a ton of problems with Application.Current.Properties on Android. I highly suggest using Xamarin Settings plugin instead which I have never had any issues with. It is persistent even when the app is closed.
That being said Application.Current.Properties is supposed to work even when you close the app. Not sure why it wouldn't but it does not surprise me either.
*Edit: To use once it is installed, basically CrossSettings.Current is the plugin class that will do the work but the example just creates a separate property to access it. So create a new file, lets call it SettingsImplementation:
public static class SettingsImplementation {
#region Instance
private static Lazy<ISettings> _appSettings;
public static ISettings AppSettings {
get {
if(_appSettings == null) {
_appSettings = new Lazy<ISettings>(() => CrossSettings.Current, LazyThreadSafetyMode.PublicationOnly);
}
return _appSettings.Value;
}
set {
_appSettings = new Lazy<ISettings>(() => value, LazyThreadSafetyMode.PublicationOnly);
}
}
#endregion
private const string UserNameKey = "username_key"; //Key used to get your property
private static readonly string UserNameDefault = string.Empty; //Default value for your property if the key-value pair has not been created yet
public static string UserName {
get { return AppSettings.GetValueOrDefault<string>(UserNameKey, UserNameDefault); }
set { AppSettings.AddOrUpdateValue<string>(UserNameKey, value); }
}
}
Then to use that you would do this anywhere in your app:
SettingsImplementation.UserName = "something";
OR
string username = SettingsImplementation.UserName;
My own problem regarding this issue was due to me not explicitly saving the properties with the following line of code:
Application.Current.SavePropertiesAsync();
you can use Xamarin essentials "Preferences" instead:
Preferences.Set("Key", "Value");
Preferences.Get("Key", "Default");
I ran into the same issue.
The problem:
I was trying to throw complex objects into the Application Properties.
It turns out that the Properties can only take primitive data typs.
This Blog was very helpfull.
https://codemilltech.com/persist-whatever-you-want-with-xamarin-forms/

Visual Basic - Check To See If Program Can Edit Registry [duplicate]

Does anybody know how I can programmatically check (using C#) whether my program will be able to read / write a particular registry key (specifically: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run")?
I am asking because my program has the option to enable or disable the 'run at startup' behaviour. I want to disable this option if the current user is not allowed to make changes to the registry. Is this key always allowed to be written by the current user, or is there the possibility that it has been locked down? If the latter, how do I check this?
I have seen several conflicting ways of checking registry permissions - but basically I can't find a way to check a specific key before I try to read it. I would rather perform the check before accessing the key than trying to access it and receive an exception.
Any help is much appreciated.
Tom
The RegistryPermission class governs the security permissions around reg keys. To check if you may have write access to a permission you use it in the following manner:
RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, #"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
You would then use the "Demand" method in a try/catch and return on failure (the raising of a security exception). On success you'd carry on and perform your update. Although this isn't quite what you want, a check on permissions before access, it is the accepted way of ensuring you have the permissions you need before you operate on the keys. In a fully structured manner this would equate to:
try
{
RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.Write, #"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
perm1.Demand();
}
catch (System.Security.SecurityException ex)
{
return;
}
//Do your reg updates here
EDIT: Thinking on what I mentioned in the comment, here are extension methods to the RegistryPermission class for permission checks:
using System.Security.Permissions;
using System.Security;
public static class RegistryExtensions
{
public static bool HavePermissionsOnKey(this RegistryPermission reg, RegistryPermissionAccess accessLevel, string key)
{
try
{
RegistryPermission r = new RegistryPermission(accessLevel, key);
r.Demand();
return true;
}
catch (SecurityException)
{
return false;
}
}
public static bool CanWriteKey(this RegistryPermission reg, string key)
{
try
{
RegistryPermission r = new RegistryPermission(RegistryPermissionAccess.Write, key);
r.Demand();
return true;
}
catch (SecurityException)
{
return false;
}
}
public static bool CanReadKey(this RegistryPermission reg, string key)
{
try
{
RegistryPermission r = new RegistryPermission(RegistryPermissionAccess.Read, key);
r.Demand();
return true;
}
catch (SecurityException)
{
return false;
}
}
}
One thing you should know about permissions is that they are volatile. That means you could do your security check on the registry key, attempt to add your value only if the check passes, and then still fail with an insufficient access exception because the permissions changed in between when you made the check and when you acted on the results. This is possible even if they are consecutive statements in your program.
Granted security permissions tend to be relatively stable, but the chance still exists. This means that you must have code to handle the security exception, and if you have to do that anyway there's not really any point in making the check in the first place. Instead, put your time into making your exception handler a little bit better.
That said, "boo" to any app that wants to run something at start-up. YAGNI.
I think you best bet is to just try to add your value to the key, and handle failure gracefully by informing the user they didn't have enough permissions to do that.
If you're writing some sort of administrative tool that is designed to always be run by an administrator, you should indicate that in the manifest. That way your app will elevate at startup (via UAC prompt).
Simplest option is to try and open the key with write access and see if you get it. Remember to close the key afterwards.
bool fWriteAccess;
try {
Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True).Close();
fWriteAccess = True;
} catch (SecurityException) {
fWriteAccess = False;
}
I'm not sure how to it with C#, but with Win32, you would use RegGetKeySecurity(). Maybe there's a C# wrapper? Otherwise, use P/Invoke.
Just try to open the registry key with WRITE permissions.
That said, what others have said is right: There is no way to tell if an operation is going to succeed unless you try it. Maybe someon deleted the Run key. Maybe the registry will exceed allocated memory. Maybe the disk failed.

Fetch windows setting value

How do I fetch the Measurement System setting value in javascript?
I'm guessing that it would be throw some WinJS call.
The logical place would be Windows.Globalization, but not seeing if offered there. One pretty simple workaround - faster to write than to research the setting :) is to create a Windows Runtime Component in C# that calls in to System.Globalization:
namespace WindowsRuntimeComponent
{
public sealed class RegionalSettings
{
public bool isMetric()
{
return System.Globalization.RegionInfo.CurrentRegion.IsMetric;
}
}
}
Then add as a reference to your JavaScript app and invoke there:
var r = new WindowsRuntimeComponent.RegionalSettings;
var isMetric = r.isMetric();

Cache Shows Old Values on IIS7, not Debug Server

I have a pretty standard MVC3 application. I'm trying to store some data that's application-wide (not user wide) in a the cache (in this case, a Theme object/name). When debugging (on the development server that integrates with Visual Studio), if I call SwitchTheme, I see the new theme right away. On IIS7, whatever theme was cached, stays cached; it doesn't update to the new theme.
Edit: Some code:
public static Theme CurrentTheme { get {
Theme currentTheme = HttpContext.Current.Cache[CURRENT_THEME] as Theme;
if (currentTheme == null)
{
string themeName = DEFAULT_THEME;
try
{
WebsiteSetting ws = WebsiteSetting.First(w => w.Key == WebsiteSetting.CURRENT_THEME);
if (ws != null && !string.IsNullOrEmpty(ws.Value))
{
themeName = ws.Value;
}
}
catch (Exception e)
{
// DB not inited, or we're installing, or something broke.
// Don't panic, just use the default.
}
// Sets HttpContext.Current.Cache[CURRENT_THEME] = new themeName)
Theme.SwitchTo(themeName);
currentTheme = HttpContext.Current.Cache[CURRENT_THEME] as Theme;
}
return currentTheme;
} }
public static void SwitchTo(string name)
{
HttpContext.Current.Cache.Insert(CURRENT_THEME, new Theme(name), null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(30));
// Persist change to the DB.
// But don't do this if we didn't install the application yet.
try
{
WebsiteSetting themeSetting = WebsiteSetting.First(w => w.Key == WebsiteSetting.CURRENT_THEME);
if (themeSetting != null)
{
themeSetting.Value = name;
themeSetting.Save();
}
// No "else"; if it's not there, we're installing, or Health Check will take care of it.
}
catch (Exception e)
{
// DB not inited or install not complete. No worries, mate.
}
}
I'm not sure where the problem is. I am calling the same method and updating the cache; but IIS7 just shows me the old version.
I can disable output caching in IIS, but that's not what I want to do. That seems like a hacky work-around at best.
Without a code sample it's difficult to know what your problem is. In an attempt to provide some assistance, here is how I frequently set the cache in my applications:
public static void SetCache(string key, object value) {
if (value != null) {
HttpRuntime.Cache.Insert(key, value, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(30));
}
}
The HTTP cache is reset only if you do so manually or the app domain (or app pool) resets for whatever reason. Are you sure that's not happening in this case? And generally speaking, any global static variables would also be maintained in memory under the same circumstances.
There are many reasons why an app pool might be reset at any given point, such as a change to a web.config file, etc. I suggest checking that's not happening in your case.
By the way, output caching is a different thing, although it is maintained in memory largely the same way.
Given that this only happens on IIS7 when Output Caching is not disabled, this seems very likely to be an IIS7 bug. Seriously.
Whether it is or not, is irrelevant to the solution. What you need to do is find some manual process of invalidating the cache, such as touching the web.config file.
But beware: doing this will wipe out the cache (as you expect), but also all static variables (as a side-effect). Whether this is another bug or not, I don't know; but in my case, this was sufficient to solve the problem.

Mvc-Mini-Profiler: Why so many X-MiniProfiler-Ids?

I'm using Mvc-Mini-Profiler (what a great product!). Using my ordinary web browser everything seems to work fine but as soon as I use my own http client (basic http 1.1 without cookie support) the amount of X-MiniProfiler-Ids in the http header increases. This happens quite rapidly and becomes quite many in a short amount of time (11kB and above of data).
Can the lack of cookies make Mvc-Mini-Profiler work this way or could anything be wrong with my implementation?
This is by design I think. Though we could improve the implementation a bit.
The X-MiniProfiler-Ids need to be "consumed", they only show up when profiling is enabled. The reason it works this way is so you can profile POST and redirects.
We probably should set some clear upper limit there (like 20 or so) - please post a bug for that.
However, since you never really plan to consume any profiling blocks for you HTTP client, I would recommend abandoning profiling if the useragent is your HTTP client.
You can do this by adding a conditional before:
// don't run if UserAgent is "my http client"
if(notMyUserAgent)
MvcMiniProfiler.MiniProfiler.Start();
Another option is to override the SqlServerStorage class and default the UserHasViewed field to true. This will keep the X-MiniProfiler-Id string down to a minimum.
public class MvcMiniProfilerStorage : SqlServerStorage
{
public MvcMiniProfilerStorage(string connectionString) : base(connectionString)
{
}
/// <summary>
/// Stores to dbo.MiniProfilers under its ;
/// stores all child Timings and SqlTimings to their respective tables.
/// </summary>
public override void Save(MiniProfiler profiler)
{
const string sql =
#"insert into MiniProfilers
(Id,
Name,
Started,
MachineName,
[User],
Level,
RootTimingId,
DurationMilliseconds,
DurationMillisecondsInSql,
HasSqlTimings,
HasDuplicateSqlTimings,
HasTrivialTimings,
HasAllTrivialTimings,
TrivialDurationThresholdMilliseconds,
HasUserViewed)
select #Id,
#Name,
#Started,
#MachineName,
#User,
#Level,
#RootTimingId,
#DurationMilliseconds,
#DurationMillisecondsInSql,
#HasSqlTimings,
#HasDuplicateSqlTimings,
#HasTrivialTimings,
#HasAllTrivialTimings,
#TrivialDurationThresholdMilliseconds,
#HasUserViewed
where not exists (select 1 from MiniProfilers where Id = #Id)";
// this syntax works on both mssql and sqlite
using (DbConnection conn = GetOpenConnection())
{
int insertCount = conn.Execute(sql,
new
{
profiler.Id,
Name = Truncate(profiler.Name, 200),
profiler.Started,
MachineName = Truncate(profiler.MachineName, 100),
User = Truncate(profiler.User, 100),
profiler.Level,
RootTimingId = profiler.Root.Id,
profiler.DurationMilliseconds,
profiler.DurationMillisecondsInSql,
profiler.HasSqlTimings,
profiler.HasDuplicateSqlTimings,
profiler.HasTrivialTimings,
profiler.HasAllTrivialTimings,
profiler.TrivialDurationThresholdMilliseconds,
// BUG: Too many X-MiniProfiler-Id headers cause
// Firefox to stop all requests
//
// This hack marks all entries as read so that
// they do not end up part of that header.
HasUserViewed = true
});
if (insertCount > 0)
{
SaveTiming(conn, profiler, profiler.Root);
}
}
}
private static string Truncate(string s, int maxLength)
{
return s != null && s.Length >
maxLength ? s.Substring(0, maxLength) : s;
}
}

Resources