I need to build a console program to read and update the chrome browser setting.
Where should I start?
Check if you can modify the following file.
Location - c:\Users\\AppData\Local\Google\Chrome\User Data\Default\Preferences
This file contains a few settings. I have never done this so not sure if you can modify the file. But looks like a good start. Also, not sure if chrome rebuilds the file. (It was updated when I opened chrome while this file was open on my machine).
Chrome settings are stored in the registry, so here to read/write the registry and here for the list of available settings.
RegistryKey key = Registry.CurrentUser.CreateSubKey(#"SOFTWARE\OurSettings");
/// Reading value
var value = key.GetValue("Setting1");
/// Setting value
key.SetValue("Setting1", "This is our setting 1");
Be aware by Google's warning if you are not developing this for internal use :
These policies are strictly intended to be used to configure instances of Google Chrome internal to your organization. Use of these policies outside of your organization (for example, in a publicly distributed program) is considered malware and will likely be labeled as malware by Google and anti-virus vendors.
Related
I have an application that allows the user to upload a file (saving it to in a folder located in the wwwroot of the ASPNETCORE application). From here they can make edits to it and then they can choose to export the file as a csv/ xml/ xlsx which downloads the file to the user's 'downloads' folder.
While debugging in Visual Studio this all works fine however when I publish and deploy the application to IIS I am getting the exception
Error saving file C:\windows\system32\config\systemprofile\Downloads(FILE NAME)
Could not find part of the path C:\windows\system32\config\systemprofile\Downloads(FILE NAME)
This is the current way I am getting the downloads folder:
FileInfo file = new FileInfo(Path.Combine(Environment.ExpandEnvironmentVariables(#"%USERPROFILE%\Downloads"), data.Filename + "." + data.FileType));
However I have also tried the solution that Hans Passant has answered to a similar question here. Both solutions worjk fine while debugging locally however as soon as I publish them, this one produces the exception:
Value cannot be null. Parameter name: path1
Which I presume is thrown at this point here when I try and save the file to the user's download folder.
using (var package = new ExcelPackage(file))
{
var workSheet = package.Workbook.Worksheets.Add("ExportSheet");
workSheet.Cells.LoadFromCollection(exports, true);
package.Save();
}
I don't really know how I would be able to reproduce these exceptions seeing as locally using Visual Studio it all works fine.
Has anyone else came across this issue while trying to download a file?
UPDATE: When the application is running on IIS, it seems to be using that as the user profile instead of the actually user, so when it tries to navigate to the Downloads folder, it cannot find it. How can I force it to use the user's profile?
LoadUserProfile is already set to True.
Web applications have no knowledge of the end-user's computer's filesystem!
So using Environment.GetFolderPath or Environment.ExpandEnvironmentVariables in server side code will only reveal the server-side user (i.e. the Windows Service Identity)'s profile directories which is completely separate and distinct from your web-application's actual browser-based users OS user profile.
As a simple thought-experiment: consider a user running a weird alien web-browser on an even more alien operating system (say, iBrowse for the Amiga!) - the concept of a Windows-shell "Downloads" directory just doesn't exist, and yet here they are, browsing your website. What do you expect your code would do in this situation?
To "download" a file to a user, your server-side web-application should serve the raw bytes of the generated file (e.g. using HttpResponse.TransmitFile) with the Content-Disposition: header to provide a hint to the user's browser that they should save the file rather than try to open it in the browser.
Any idea how do I do the following using C#?
Going to Tools -> Internet Options -> Security
Select the Security tab
Click the Custom Level button
In the Miscellaneous section change Display mixed content to Enable
The "cheat" way to do this is to change the value
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\Zones\0\1609
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\Zones\1\1609
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\Zones\2\1609
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\Zones\3\1609
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\Zones\4\1609
Where 0-4 are Zone identifiers and the value is 0 to Allow, 1 to Prompt, and 3 to Block. Keep in mind that if your code does this on anyone's machine but your own, you're likely to find your code blocked as malware.
The "proper" way to do this is to use the APIs to create an IInternetZoneManager and call SetZoneActionPolicy to adjust the settings for URLACTION_HTML_MIXED_CONTENT in the zones you want to adjust.
You aren't supposed to do this "programmatically". That's why there isn't an API for it. Only the user can change their security settings, and they do it using the built-in interface that you've already discovered.
The poor IE team has been working overtime trying to tighten up the security of their browser. They're not going to throw in something like this that would nullify all of their efforts in a matter of seconds.
Recall that even once this option is selected, there's a confirmation dialog presented. How do you propose to "click" that programmatically? (Hmm, on second thought, don't tell me. That's probably the next question you'll be asking.)
Give up on trying to do this programmatically, and ask the user to do it themselves. Provide a complete help file or other documentation that explains why you're requesting that they make this change, what features will be unavailable if they do not choose to make this change, and what the possible security risks of making such a change are. And, of course, specific instructions on how the change is made.
Or, better yet, redesign your app so that it doesn't require a system-wide modification of IE's security settings. It's hard to imagine a legitimate case for this. A better solution might be asking the user to add your site to their "trusted sites". Remember that local pages have different security settings than remote pages by default.
Also do not forget Group Policies. Most (if not all) IE settings may also be specified in Group Policies.
According to Local group policy setting for IE security page vs Internet options security page
the Group Policy settings override user-defined settings.
So, on my home PC (works without domain controller) I have a choice to define IE settings either via Local Group Policy Editor or via Internet Options. For example, if I run gpedit.msc to open Local Group Policy Editor, select
Computer Configuration\Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone
change "Display mixed content" setting to "Enabled", then select "Enable" in drop down box, click Apply,
then open Security Settings for Internet Zone in IE - I will see that "Display mixed content" changed to Enable and
the selection is disabled because it is overriden by Policy.
For the entire list of supported policies download WindowsServer2012andWindows8GroupPolicySettings.xlsx
from
http://www.microsoft.com/en-us/download/details.aspx?id=25250
Now back to the question how to change settings programmatically.
EricLaw correctly suggested using SetZoneActionPolicy from IInternetZoneManager.
But it is hard to find samples for calling it from C#.
I ended up copying
http://www.pinvoke.net/default.aspx/Interfaces.IInternetZoneManager
into my code and then doing:
//This will disable "Download signed ActiveX" (IE setting # 0x1001) for Internet Zone (zone #3)
IInternetZoneManager izm = Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("7b8a2d95-0ac9-11d1-896c-00c04Fb6bfc4"))) as IInternetZoneManager;
IntPtr pPolicy = Marshal.AllocHGlobal(4);
Marshal.Copy(new int[] { 3 }, 0, pPolicy, 1);//3 means "Disable"
int result = izm.SetZoneActionPolicy((uint)UrlZone.Internet, (uint)0x1001, pPolicy, 4, (uint)UrlZoneReg.CurrentUserKey);
Marshal.ReleaseComObject(izm);
Marshal.FreeHGlobal(pPolicy);
I also tried changing group policy programmatically.
I used library from
https://bitbucket.org/MartinEden/local-policy
and then:
//This will disable "Download signed ActiveX controls" computer policy for Internet Zone (zone #3)
const string keyPath = #"SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3";
var gpo = new LocalPolicy.ComputerGroupPolicyObject();
using (var machine = gpo.GetRootRegistryKey(LocalPolicy.GroupPolicySection.Machine))
{
using (var terminalServicesKey = machine.CreateSubKey(keyPath))
{
terminalServicesKey.SetValue("1001", 3, Microsoft.Win32.RegistryValueKind.DWord);
}
}
gpo.Save();
After successfully testing the code above on Win7 SP1 with IE 11 I decided to go back to the original suggestion from EricLaw: modify
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\*\1001
directly because this is what Microsoft is recommending. See, for example How to strengthen the security settings for the Local Machine zone in Internet Explorer or Enhanced Browsing Security
I am not sure but I think you can find all these settings in "registry". You need to find out the appropriate key. And to change those values you need to have proper rights. Registry can be accessed from .net code
I have a program which I want to store information in a string. I have been using the Properties.Setting.Default.STRINGname to store the information, which works fine on my PC, and I can see the saved strings (when I go to the settings in the application). But when I take the application to a new PC it losses the strings. Is there a way to be able to edit this information and save it in the app? So basically I need to be able to convert the user setting to application setting, but after the runtime.
var settings = Properties.Settings.Default;
settings.H1 = textbox1.text;
settings.H2 = textbox2.text;
settings.Save();
MSDN explicit says something about this:
Settings that are application-scoped are read-only, and can only be changed at design time or by altering the .config file in between application sessions. Settings that are user-scoped, however, can be written at run time just as you would change any property value. The new value persists for the duration of the application session. You can persist the changes to the settings between application sessions by calling the Save method.
For this, Application setting will never work for you. However, if you are using a User scoped settings it does work, but soon you change the application from one computer to another (as you say you want to) you will loose the settings as that's another machine (another user-scope)...
There are way to continue to have the same settings, you can do, at least 2 things:
use a .config file to save the settings (it's an XML file)
use a service to host the settings and you can read if user has internet access
What you can't do is
using only one executable file, save the settings from computer to computer.
User settings are compiled differently than Application settings, and thus cannot be converted after compilation. Why not compile with Application Settings?
The code you are using should save the user settings. Rememeber that user settings will be saved in the user's data folder. Not in the configuration file where the app was installed (say program files). This is the usual path:
<Profile Directory>\<Company Name>\<App Name>_<Evidence Type>_<Evidence Hash>\<Version>\user.config
See this links form more information
Is there a way I could change the download folder of the default web browser using c#.
Concurring with other's comments, you can only do it in a desktop app if you have the right permissions.
Here's some sample code to find out the default browser of the system (from this post):
private string getDefaultBrowser()
{
string browser = string.Empty;
RegistryKey key = null;
try
{
key = Registry.ClassesRoot.OpenSubKey(#"HTTP\shell\open\command", false);
//trim off quotes
browser = key.GetValue(null).ToString().ToLower().Replace("\"", "");
if (!browser.EndsWith("exe"))
{
//get rid of everything after the ".exe"
browser = browser.Substring(0, browser.LastIndexOf(".exe")+4);
}
}
finally
{
if (key != null) key.Close();
}
return browser;
}
However, things get tricky from here. Different browsers have different ways of saving the default location.
E.g.,
IE may store it in registry (usually under HKEY_CURRENT_USER\ Software\ Microsoft\ Internet Explorer)
FF stores it in prefs.js in Profile folder (checkout this post to get to it via code)
Not sure about Chrome and Safari
but you get the idea.
Not sure what your end goal is, but from a UX standpoint, I think the best thing to do would be to ask user to specify the Download directory (in other words, you expose a Setting in your App for the default download location).
To expand on Ash's comment - if you're within a web app, no. If you're a desktop app, and you have sufficient permissions (i.e. running as Administrator), probably. But you'd need to find the default browser (from the registry presumably) and know how to set the download folder for each popular browser, or every browser you want to work with.
Where are you trying to do this from? If you mean "someone hits our website and ...", the answer is no, as anything you run is in a security context. You can certainly suggest the user changes the folder, but you are stuck.
Assuming you are not a web application, you have options. The main user download directory is located at X under the key {374DE290-123F-4565-9164-39C4925E467B}. Yeah, that sounds like a lot of fun. You can learn how to hack the registry programatically here. But, the user can specify a specific folder in the browser, as well. This means you have to know what browser the user is using and hack it, or you can attempt to hack all.
The bad news is the app, running (most likely) in the user context, may not have administrator rights and be able to whack the registry keys to change the folder.
I am using ItextSharp and I am getting a new font for it by doing this
string fontPath = Path.GetFullPath("C:\\BMSApplicationFiles\\Fonts\\FREE3OF9.TTF");
BaseFont barCodeBase = BaseFont.CreateFont(fontPath, BaseFont.CP1252, BaseFont.EMBEDDED);
That file is in that directory on both my dev machine and the server.
When i run this on my dev machine it works fine, when published to my server I get an error saying FREE3OF9.TTF is not found as a file or a resource.
I have double and triple checked that the file is in fact there on my server. My application has full trust on IIS.
and IIS user has full access to this folder. And still I get this error. Very frustrating.
Any ideas??
This code is Not inside the Web Application but inside a DLL class library that the web application is referencing. Do I need to add any more special permissions or something?
Your next step should be to confirm that what you think is happening is happening. If you are allowed to, download and install Process Monitor which will allow you to log activity including which files are being attempted to be accessed and by which user account. Apply filters when monitoring of course, or else you'll end up seeing all the activity on the server...
If that only confirms that the correct file is being attempted to be read by expected user then maybe there's something up with the font. Try replacing the font file temporarily with another standard one (e.g. arial or something) and see what happens. (this is unlikely to help as it works on your dev machine, but might be worth a go)
Most probably you have a security issue.
If you run IIS7 then check that IIS_IUSRS group has an access to the file (open file properties in explorer select Security tab etc).
If you run IIS6 then check that IUSR_MachineName account has an access to the file.
I had a similar error when I tried to get it working with IIS. Within IIS, I had to add he file directory as a virtual drive. That worked for me when I had a similar situation set up. Hopefully it works for you, best of luck