I'm looking for a way to make a Registry Change take affect right away.
Specifically the value I want to touch is:
HKEY_CURRENT_USER/Control\ Panel/Desktop/WindowArrangementActive
When you change this setting directly from the Control Panel it takes effect immediately, but when I'm changing it manually, it is not registered before rebooting.
I'm trying to make a script to disable/enable window snapping in Windows 10.
I've currently tried running the following command after the change with no luck:
RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters ,1 ,True
I ended up getting the job done in C# using the SystemParametersInfo:
[DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
public static extern bool SystemParametersInfo(int uiAction, int uiParam, IntPtr pvParam, int fWinIni);
and calling it with the following params:
SystemParametersInfo(0x0083, 0, IntPtr.Zero, 0x001A);
The final param is the one informing the system that the variable has changed in accordance with this documentation by Microsoft:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms725497(v=vs.85).aspx
Related
In my understanding currently there are two ways to copy virtual files from a Shell Namespace Extension with the Explorer so that Copy GUI will be shown to the user:
Via IDataObject interface:
Reading a file is done via IDataObject::GetData that should support CFSTR_FILEDESCRIPTORW, CFSTR_FILECONTENTS and CFSTR_SHELLIDLIST clipboard formats at very minimum. Requesting CFSTR_FILECONTENTS from IDataObject::GetData should create an IStream that is used to access the data. UI is enabled via setting FD_PROGRESSUI flag when CFSTR_FILEDESCRIPTORW is requested.
Via ITransferSource interface:
Reading a file is done via ITransferSource::OpenItem requesting for IShellItemResources. Then IShellItemResources should report {4F74D1CF-680C-4EA3-8020-4BDA6792DA3C} resource as supported (GUID indicating that there is an IStream for the item). Finally an IStream is requested via parent ShellFolder::BindToObject for accessing the data. UI is handled by the Explorer itself, it is always shown.
My problem is: these two mechanisms are working just fine separately (as you can see from the screenshots). But once I enable both IDataObject from IShellFolder::GetUIObjectOf and ITransferSource from IShellFolder::CreateViewObject - the approach via IDataObject is always used leading to the old copy GUI (as on the first screenshot). I see from the trace logs that ITransferSource is requested several times, but no actions are performed, it just gets Released and destroyed right away.
So how may I force Explorer to show fancy copy GUI when copying from my Shell Namespace Extension?
A minimal reproducible example may be found here: https://github.com/BilyakA/SO_73938149
While working on Minimal Reproducible example I somehow managed to make it work as expected with both IDataObject and ITranfserSource interfaces enabled. It happened after:
unregistred x64 build SNE example (regsvr32 /u)
registred x32 build SNE example (it was not working in x64 explorer, root was not opening)
unregistred x32
registred x64 again.
Somehow new copy UI was shown to me when copying the files.
But I was not able to reproduce this result constantly after I have unregistred x64 SNE, restarted explorer and registered SNE x64 again.
What I have tried:
Registred both x32 and x64 SNE - still old GUI
Removed Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Cached value with my NSE GUID and restarted Explorer afterwards. Still old GUI.
I suspect there is some kind of cache (other than Registry) that keeps track if NSE supports ITransferSource. And since I have developed and tested without ITransferSource at the beginning - it is cached that my NSE does not support it even that I have added it later. And somehow registering 32bit reset that cache value.
The current code is doing something like this when asked for an IDataObject:
HRESULT CFolderViewImplFolder::GetUIObjectOf(HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT rgfReserved, void **ppv)
{
....
if (riid == IID_IDataObject)
{
CDataObject* dataObject = new (std::nothrow) CDataObject(this, cidl, apidl);
return ::SHCreateDataObject(m_pidl, cidl, apidl, dataObject, riid, ppv);
}
...
}
SHCreateDataObject already creates already a full-blown IDataObject with everything needed from the (optional) input PIDL(s), including all Shell formats for items in the Shell namespace (CFSTR_SHELLIDLIST, etc.).
Passing an inner object 1) will probably conflict with what the Shell does and 2) requires a good implementation (I've not checked it).
So you can just replace it like this:
HRESULT CFolderViewImplFolder::GetUIObjectOf(HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT rgfReserved, void **ppv)
{
....
if (riid == IID_IDataObject)
{
return ::SHCreateDataObject(m_pidl, cidl, apidl, NULL, riid, ppv);
}
...
}
In fact, the IDataObject provided by the Shell is complete (supports SetData method, etc.) so you should never need to implement it yourself, it's more complex than it seems. You can reuse it as a general purpose IDataObject (you can pass nulls and 0 for the 4 first arguments).
PS: the Shell also provides the "reverse" method: SHCreateShellItemArrayFromDataObject that gets a list of Shell items from an IDataObject (if the data object contains the expected clipboard formats).
For those who need to use inner IDataObject within SHCreateDataObject for additional format:
Inner IDataObject should support CFSTR_SHELLIDLIST clipboard format in GetData() as well as report this format in EnumFormatEtc(). Supporting SetData() with CFSTR_SHELLIDLIST format is really useful here since DefDataObject sets inner data object with already fully constructed CIDA and you may just store a copy of it.
Once inner data object will report CFSTR_SHELLIDLIST in EnumFormatEtc() and return valid CIDA in GetData() - modern Copy UI will be used since it relies only on PIDL of the items.
I'm trying to make an extension and I need to call two commands from code...
SolutionExplorer.SyncWithActiveDocument
The Collapse All command in the Solution Explorer.
I can't find anyway to call these functions.
Does anyone know how to do this?
Have you tried executing the commands via the DTE?
dte.Windows.Item(EnvDTE.Constants.vsWindowKindSolutionExplorer).Activate();
// Sync with Active Document
dte.ExecuteCommand("SolutionExplorer.SyncWithActiveDocument");
// Collapse All
int cmdidSolutionExplorerCollapseAll = 29;
Guid guidCMDSETID_StandardCommandSet11 = new Guid("D63DB1F0-404E-4B21-9648-CA8D99245EC3");
dte.Commands.Raise(guidCMDSETID_StandardCommandSet11.ToString("B"), cmdidSolutionExplorerCollapseAll, null, null);
If you need to identify the ID's for any other commands, you can switch on VSIP logging:
http://blogs.msdn.com/b/dr._ex/archive/2007/04/17/using-enablevsiplogging-to-identify-menus-and-commands-with-vs-2005-sp1.aspx
How to get the screen auto-rotate's status (disable or enable) by Regetry or ACPI in windows8?
I need to disable screen auto-rotate, and I will use winkey + O to change the screen auto-rotate control.
Does anyone have similar experiences?
Below maybe helpful if you want to change auto-rotate status:
//C++
typedef BOOL (WINAPI* SETAUTOROTATION)(BOOL bEnable);
SETAUTOROTATION SetAutoRotation = (SETAUTOROTATION)GetProcAddress(GetModuleHandle(TEXT("user32.dll")), (LPCSTR)2507);
if(SetAutoRotation != NULL)
{
SetAutoRotation(TRUE);
}
or
//C#
[DllImport("user32.dll", EntryPoint = "#2507")]
extern static bool SetAutoRotation(bool bEnable);
SetAutoRotation(true);
I found the answer.
public enum tagAR_STATE : uint
{
AR_ENABLED = 0x0,
AR_DISABLED = 0x1,
AR_SUPPRESSED = 0x2,
AR_REMOTESESSION = 0x4,
AR_MULTIMON = 0x8,
AR_NOSENSOR = 0x10,
AR_NOT_SUPPORTED = 0x20,
AR_DOCKED = 0x40,
AR_LAPTOP = 0x80
}
[DllImport("user32.dll")]
public static extern bool GetAutoRotationState(ref tagAR_STATE input);
Hope that can help the other people.
This MSDN example appears to do the job, using what looks like an 'official' API call, SetDisplayAutoRotationPreferences, which is in User32.dll (not kernel.dll as the example states) and is defined in WinUser.h.
The advantage of this example over the other suggestions is that it first checks whether auto-rotation is supported and enabled first.
The registry and Windows+O hotkey work at the system level, tweaking a user setting. Applications aren't supposed to mess with it. There is an application-level way to set autorotation preferences, and once the user closes your app or switches to a different one, then their existing settings (or the other app's) take over.
MSDN has a good example of using the relevant APIs here: https://code.msdn.microsoft.com/windowsapps/Auto-Rotation-Preferences-87ae2902
If your app has only one autorotation preference that it keeps throughout its lifetime, then it is simplest to just set it in your manifest. There are a few options there that you don't get with the APIs such as supporting both landscape and landscape flipped.
Another alternative, and this is the one that seems to work consistently on my tablet. Check this registry key. You can also change the key and the device will immediately pick up the change:
Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AutoRotation
Setting: Enable
It's a DWORD, so set to 0 to disable auto-rotate or 1 to enable auto-rotate.
Now, if only I could find a way to force the app to work in Landscape mode only!...
Is there a way to clean the most recently started applications from the Windows 7 start menu programmatically?
I'm looking for some registry entries and/or files to delete so the corresponding items in the Winodws 7 start menu are removed.
SHAddToRecentDocs(SHARD_PIDL,NULL) is the documented way to clear the recent documents, not messing in the registry like surya suggests.
Since your question includes the word "applications" I'm assuming that you are actually mean the list of applications, and there is no real way to modify that programmatically since that list "belongs" to the user.
If you want to go the undocumented hacky route you can use get a IContextMenu for the specific .lnk and call the "Remove from this list" command.
On XP the start menu application usage is stored in HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist{75048700-EF1F-11D0-9888-006097DEACF9} but explorer will cache those entries so you can't just delete the key without killing explorer first.
Now this is the solution for my question:
I Cleaned the values under the Registry Keys
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}\Count
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}\Count
Then I executed the following PInvoke to refresh the cache of the Explorer.exe:
C#:
using System.Runtime.InteropServices;
[DllImport("shell32.dll")]
static extern void SHChangeNotify(int wEventId, int uFlags, IntPtr dwItem1, IntPtr wItem2);
private const int SHCNE_ASSOCCHANGED = 0x08000000;
private const int SHCNF_IDLIST = 0x0000;
private void ClearCache()
{
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);
}
Regards,
Boris
In the Registry, delete unneccessary stuff. The key is HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs
Is there a way to place a watch on variable and only have Visual Studio break when that value changes?
It would make it so much easier to find tricky state issues.
Can this be done?
Breakpoint conditions still need a breakpoint set, and I'd rather set a watch and let Visual Studio set the breakpoints at state changes.
In the Visual Studio 2005 menu:
Debug -> New Breakpoint -> New Data Breakpoint
Enter:
&myVariable
You can also choose to break explicitly in code:
// Assuming C#
if (condition)
{
System.Diagnostics.Debugger.Break();
}
From MSDN:
Debugger.Break:
If no debugger is attached, users are
asked if they want to attach a
debugger. If yes, the debugger is
started. If a debugger is attached,
the debugger is signaled with a user
breakpoint event, and the debugger
suspends execution of the process just
as if a debugger breakpoint had been
hit.
This is only a fallback, though. Setting a conditional breakpoint in Visual Studio, as described in other comments, is a better choice.
In Visual Studio 2015, you can place a breakpoint on the set accessor of an Auto-Implemented Property and the debugger will break when the property is updated
public bool IsUpdated
{
get;
set; //set breakpoint on this line
}
Update
Alternatively; #AbdulRaufMujahid has pointed out in the comments that if the auto implemented property is on a single line, you can position your cursor at the get; or set; and hit F9 and a breakpoint will be placed accordingly. Nice!
public bool IsUpdated { get; set; }
Imagine you have a class called A with the following declaration.
class A
{
public:
A();
private:
int m_value;
};
You want the program to stop when someone modifies the value of "m_value".
Go to the class definition and put a breakpoint in the constructor of A.
A::A()
{
... // set breakpoint here
}
Once we stopped the program:
Debug -> New Breakpoint -> New Data Breakpoint ...
Address: &(this->m_value)
Byte Count: 4 (Because int has 4 bytes)
Now, we can resume the program. The debugger will stop when the value is changed.
You can do the same with inherited classes or compound classes.
class B
{
private:
A m_a;
};
Address: &(this->m_a.m_value)
If you don't know the number of bytes of the variable you want to inspect, you can use the sizeof operator.
For example:
// to know the size of the word processor,
// if you want to inspect a pointer.
int wordTam = sizeof (void* );
If you look at the "Call stack" you can see the function that changed the value of the variable.
Change the variable into a property and add a breakpoint in the set method. Example:
private bool m_Var = false;
protected bool var
{
get {
return m_var;
}
set {
m_var = value;
}
}
Update in 2019:
This is now officially supported in Visual Studio 2019 Preview 2 for .Net Core 3.0 or higher. Of course, you may have to put some thoughts in potential risks of using a Preview version of IDE. I imagine in the near future this will be included in the official Visual Studio.
https://blogs.msdn.microsoft.com/visualstudio/2019/02/12/break-when-value-changes-data-breakpoints-for-net-core-in-visual-studio-2019/
Fortunately, data breakpoints are no longer a C++ exclusive because they are now available for .NET Core (3.0 or higher) in Visual Studio 2019 Preview 2!
If you are using WPF, there is an awesome tool : WPF Inspector.
It attaches itself to a WPF app and display the full tree of controls with the all properties, an it allows you (amongst other things) to break on any property change.
But sadly I didn't find any tool that would allow you to do the same with ANY property or variable.
I remember the way you described it using Visual Basic 6.0. In Visual Studio, the only way I have found so far is by specifying a breakpoint condition.
Right click on the breakpoint works fine for me (though mostly I am using it for conditional breakpoints on specific variable values. Even breaking on expressions involving a thread name works which is very useful if you're trying to spot threading issues).
As Peter Mortensen wrote:
In the Visual Studio 2005 menu:
Debug -> New Breakpoint -> New Data Breakpoint
Enter: &myVariable
Additional information:
Obviously, the system must know which address in memory to watch.
So
- set a normal breakpoint to the initialisation of myVariable (or myClass.m_Variable)
- run the system and wait till it stops at that breakpoint.
- Now the Menu entry is enabled, and you can watch the variable by entering &myVariable,
or the instance by entering &myClass.m_Variable. Now the addresses are well defined.
Sorry when I did things wrong by explaining an already given solution. But I could not add a comment, and there has been some comments regarding this.
You can use a memory watchpoint in unmanaged code. Not sure if these are available in managed code though.
You can probably make a clever use of the DebugBreak() function.
You can optionally overload the = operator for the variable and can put the breakpoint inside the overloaded function on specific condition.