I've got an app that needs to disable infrastructure access and then re-enable it (please don't ask why. I'm under NDA and it would be hard to explain why without violating that). I'm doing this with p/Invoke in C#.
To disable it, I'm creating the INTF_ENTRY structure, setting the adapter guid, then setting dwCtlFlags to 0 and calling
uint outFlags;
WZCSAPI.INTF_ENTRY intf = new WZCSAPI.INTF_ENTRY();
intf.wszGuid = adapterGuid;
intf.dwCtlFlags = 0;
WZCSetInterface(null, (uint)INTF_FLAGS.INTF_CM_MASK, ref intf, out outFlags)
This works beautifully and does exactly what I expect. My XP settings under "Wireless Network Connection Properties/Wireless Networks/Advanced" switches from "Any available network (access point preferred)" to "Computer-to-computer (ad hoc) networks only". This is exactly what I need it to do...
Before doing this, I retrieve the original settings for the CM_MASK.
So, later on, I try the same thing to restore it (in this case, origCMMask = 2):
uint outFlags;
WZCSAPI.INTF_ENTRY intf = new WZCSAPI.INTF_ENTRY();
intf.wszGuid = adapterGuid;
intf.dwCtlFlags = origCMMask;
WZCSetInterface(null, (uint)INTF_FLAGS.INTF_CM_MASK, ref intf, out outFlags)
But the "Any Available Network" option is not restored in the settings dialog and the HKLM\SOFTWARE\Microsoft\WZCSVC\Parameters\Interface{guid}\ControlFlags concurs that the CM Mask is NOT set back to 2, but is still set to 0 (actual value is 0x07918000, instead of the normal 0x07818002).
Is there some step I'm missing?
You could try with the WlanSetInterface Function, if you have Windows XP with SP3, passing wlan_intf_opcode_bss_type as the OpCode.
Alternatively, you can also try manually with one of the NETSH WLAN command line actions, at least to validate the approach.
disable the wireless card (you can use devcon.exe)
regedit HKLM\SOFTWARE\Microsoft\WZCSVC\Parameters\Interface{guid}\ControlFlags value
enable the wireless card (you can use devcon.exe)
Related
This is related to my other recent question on Selenium (that question was about a Firefox-specific issue, this one is about an IE-specific issue).
Basically, when I ran the following code
ieDriver.Navigate().GoToUrl("http://localhost:51282");
IWebElement linkToAboutPage = ieDriver.FindElement(By.Id("test"));
linkToAboutPage.Click();
to simulate clicking on a link, it successfully navigates to the page but when it tries to retrieve the actual element I get the following exception:
An exception of type 'OpenQA.Selenium.NoSuchWindowException' occurred in WebDriver.dll but was not handled in user code
Additional information: Unable to find element on closed window
The accepted answer to this question suggests that "Enable Protected Mode" in IE Security Settings should either be all selected or all unselected. Indeed, when I look at these settings, "Enable Protected Mode" is unselected for Intranet but not for the others:
Unfortunately, as the screenshot shows, that's being managed by my corporate IT department and I'm not sure that I'll have much luck convincing them to let me change the settings. I was also unable to edit my registry in the way suggested by some of the other answers (presumably due to the lack of administrative rights).
Some of the other solutions I've seen include setting IntroduceInstabilityByIgnoringProtectedModeSettings to true, providing a InitialBrowserUrl, or setting EnsureCleanSession to true. As shown below, I'm currently doing all of those things:
var ieOptions = new InternetExplorerOptions()
{
InitialBrowserUrl = "http://www.google.com",
IntroduceInstabilityByIgnoringProtectedModeSettings = true,
IgnoreZoomLevel = true,
EnableNativeEvents = true,
EnsureCleanSession = true
};
ieDriver = new InternetExplorerDriver(ieOptions);
ieDriver.Manage().Timeouts().ImplicitWait = new TimeSpan(0, 0, 10);
However, I'm still having the exact same problem.
Is there something else I can try that doesn't involve me bugging corporate IT for policy exceptions?
Perhaps significantly, this only happens when I'm running on localhost (which is a problem because that's where I intend to do most of my testing).
I found that setting the InitialBrowserUrl capability to the starting URL you want to navigate to, paired with IntroduceInstabilityByIgnoringProtectedModeSettings = true, works for me.
var ieOptions = new InternetExplorerOptions()
{
InitialBrowserUrl = <your-starting-url>
IntroduceInstabilityByIgnoringProtectedModeSettings = true,
...
};
Unfortunately I don't have a reason as to why this works, so this "fix" might simply be anecdotal...
Here's some other solutions you can try (from the official reference):
Required Configuration
The IEDriverServer exectuable must be downloaded and placed in your PATH.
On IE 7 or higher on Windows Vista or Windows 7, you must set the Protected Mode settings for each zone to be the same value. The value can be on or off, as long as it is the same for every zone. To set the Protected Mode settings, choose "Internet Options..." from the Tools menu, and click on the Security tab. For each zone, there will be a check box at the bottom of the tab labeled "Enable Protected Mode".
Additionally, "Enhanced Protected Mode" must be disabled for IE 10 and higher. This option is found in the Advanced tab of the Internet Options dialog.
The browser zoom level must be set to 100% so that the native mouse events can be set to the correct coordinates.
For IE 11 only, you will need to set a registry entry on the target computer so that the driver can maintain a connection to the instance of Internet Explorer it creates. For 32-bit Windows installations, the key you must examine in the registry editor is HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BFCACHE. For 64-bit Windows installations, the key is HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BFCACHE. Please note that the FEATURE_BFCACHE subkey may or may not be present, and should be created if it is not present. Important: Inside this key, create a DWORD value named iexplore.exe with the value of 0.
Reference:
https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver#required-configuration
I noticed that when I start up IE in SeleniumWebdriver with
var ieoptions = new InternetExplorerOptions()
{
EnablePersistentHover = false,
EnsureCleanSession = true,
RequireWindowFocus = true,
};
I have this -noframemerging flag in my IE command line. I don't want this flag
After some digging I managed to find that I can seemingly take it out by adding
ForceCreateProcessApi = true,
BrowserCommandLineArguments = "-framemerging"
but that would only work with an accompanying regedit for
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main = 0
I'd prefer to keep my IE working in the same way in manual and automated tests - i.e. not messing about with the number of processes in play. So is there an easier solution available here? I find it hard to understand why the -noframemerging flag is turned on by IEServerDriver
No, there is no easier solution here. IEDriverServer.exe does nothing to modify the command line used to launch IE. If a switch is being added to the command line, it's being done by the Windows IELaunchURL API, which is what the driver uses by default to launch the browser to be able to accommodate Protected Mode. The way to have "control" over what command line is used is with the CreateProcessAPI, and you've already discovered how to make the driver do that. "Control" is deliberately put in scare quotes here because unfortunately, CreateProcess isn't reliable with IE unless you use the registry entry. Moreover, IE doesn't have the concept of user profiles, and your desire to maintain the browser's behavior for your non-WebDriver use is exactly why the driver doesn't set registry entries for you.
Ok, first of all: my task is, to map a network drive programmatically from a C# program that runs as administrator.
I managed to map a drive as my normal admin user without elevated privileges and it was still visible after logoff/reboot (even though it didn't reconnect, but that's a different story). I did this with the WNetAddConnection2 WinApi function and also with the net use command in cmd, just to check.
Sadly, both didn't work with elevated privileges. In this case the drive is added as it schould, but after a reboot it is completely gone.
Is it even possible to achieve this with elevated privileges or is there some Windows account magical stuff I don't know about that prevents that?
Here is the Code I used, setting all flags that should usually make the drive be remembered and also reconnected:
uint flags = (uint)(Flags.CONNECT_CMD_SAVECRED |
Flags.CONNECT_INTERACTIVE |
Flags.CONNECT_COMMANDLINE |
Flags.CONNECT_UPDATE_PROFILE);
NETRESOURCE NetworkResource = new NETRESOURCE();
oNetworkResource.dwType = ResourceType.RESOURCETYPE_DISK;
oNetworkResource.lpLocalName = Console.ReadLine() + ":";
oNetworkResource.lpRemoteName = #"\\[Server]\foo";
oNetworkResource.lpProvider = null;
Console.WriteLine(WNetAddConnection2(NetworkResource, "[Password]", #"[Domain]\[Username]", flags));
it was still visible after logoff/reboot
this is because, when CONNECT_UPDATE_PROFILE flag used - called exported, but undocumented function I_MprSaveConn (from mpr.dll) which save in registry, under HKEY_CURRENT_USER\Network\<lpLocalName> information which you pass to WNetAddConnection2. but I_MprSaveConn at very begin call function bool IsElevatedCaller(PLUID ) and if function return true - it just exit, without saving in registry. so you absolute correct - when you call WNetAddConnection2 from elevated process (without impersonation) - this connection not persist (info not saved in registry)
solution: you need got not elevated token (say from explorer) - open/duplicate (for TokenImpersonation type) and call SetThreadToken. in this case IsElevatedCaller (can) return false (it first try open thread token (only if it not exist - process token) ) and query opened token for TokenElevationType (and return true if TokenElevationTypeFull )
so this of course not documented, but current (i test) if you impersonate self thread with not elevated token (how you got it separate question) flag CONNECT_UPDATE_PROFILE will be worked well
So, I have a task to:
1. Delete all settings in Internet Connection Properties
2. Set Use Automatic Configuration Script to my script
This is my code, and sometimes it works and values are in IE, and sometimes values are not in IE. I am frustrated with this hectic behavior and wondering where is my error (not in DNA ;))
RegistryKey registry = Registry.CurrentUser.OpenSubKey(
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
registry.SetValue("ProxyEnable", 0);
registry.Close();
RegistryKey registry2 = Registry.CurrentUser.OpenSubKey(
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections", true);
registry2.DeleteValue("DefaultConnectionSettings", false);
registry2.Close();
RegistryKey registry3 = Registry.CurrentUser.OpenSubKey(
#"Software\Microsoft\Windows\CurrentVersion\Internet Settings", true);
registry3.SetValue("AutoConfigURL", #"http://wwwwwwwww/configscript.pac", Microsoft.Win32.RegistryValueKind.String);
registry3.SetValue("ProxyEnable", 000000, RegistryValueKind.DWord);
registry3.Close();
I suspect that the issue you face has something to with stale values on the UI.
The quickest way to check whether your settings are "sticky" is to open Internet options and going to Lan settings directly from control panel.
The following command will launch "internet options"
control inetcpl.cpl
Further if your machine belongs to some corporate domains, there might be group policies set by admins that periodically enforces some values for these parameters.
In such cases, you might have to schedule a task for say every 10 minutes, and enforce values of your choice. (note: that is what I have been doing for quite some time)
Using the answer in this question I can get the "screen" count. However, this doesn't seem to work with monitors that are set to "duplicate" (one monitor is reported instead of 2). My application prompts a user to switch from VGA to HDMI (this is on a device with both output ports), and then puts a "can you see this?" prompt on screen to verify that both video ports are working.
I am trying to detect that the switch has happened before showing the prompt, but due to the above mentioned problem the code does not see the monitor count decrement, then increment (that is how I am detecting the switch).
How can I detect the video device switch if everything is set to duplicate? The existing code works if the monitors are set to "extend". There is an internal video device that is always present as well (not trying to test this one).
See This question and use the provided (and fixed in the answer) wrapper for QueryDisplayConfig.
change the signature of the import to have out DisplayConfigTopologyId topology as the last parameter.
Use the QueryDisplayFlags.DatabaseCurrent for the display flags, otherwise you'll get status 87 (invalid parameter)
After calling QueryDisplayFlags the topology will be Clone, Extend etc.
call the method...
var status = CCDWrapper.QueryDisplayConfig(
CCDWrapper.QueryDisplayFlags.DatabaseCurrent,
ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements,
modeInfoArray, out currentTopologyId);
In my tests numPathArrayElements always came back as the number of monitors currently In Use. If I changed it to "Show Only Screen 1", It said 1 screen, topology internal. "Show Only Screen 2" came back with 1 screen external. "Cloned" showed 2 screens.
James Barrass' answer didn't work for me. I ended up going with the answer here: link
Here's the code:
public static int GetScreenCount()
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_PnPEntity where service =\"monitor\"");
return searcher.Get().Count;
}