Since I switched to VS 2019 (from 2017) I am pretty sure I got a degraded IntelliSense experience. I looked for settings under Tools -> Options... but did not find anything helpful.
The matter is this: suppose I have a variable kvp that has a property Key, I could type "key.", scroll to the "Key" property (if this is not already selected) and then type ";" to complete the statement.
But this does not work anymore. Instead it now ignores what I selected and I get
key.;
The only way to get the selected property is to explicitly hit enter. Same when I type the first character(s) to select the desired option: when pressing ; it just leaves what I already typed and adds the ; immediately behind it, ignoring what I selected in the popup menu.
What happened and how do I get the proper behavior back?
I am using the Preview version but I already had a couple of updates and it does not improve so I guess it is by design or default behavior now.
Here's some of my code for Perry. It is just an example though, the problem (or what I regard to be a problem) occurs with any object variable.
private static void AddBlockNodes(TreeNode node, IDictionary<string, Block> blocks)
{
foreach (KeyValuePair<string, Block> kvp in blocks)
{
string name = kvp.Key;
Block block = kvp.Value;
TreeNode childNode = new TreeNode(name);
childNode.Tag = block;
node.Nodes.Add(childNode);
AddBlockNodes(childNode, block.Subblocks);
}
}
it just leaves what I already typed and adds the ; immediately behind
it, ignoring what I selected in the popup menu.What happened and how
do I get the proper behavior back?
It is quite an abnormal behavior and l have installed Visual Studio 16.6.0 Preview 2.1 and test your code in my side and it works well.
Type variable kvp. and then select property Key and it types as expected. I did not face missing property Key during the process.
You can try these steps to troubleshoot your issue:
Suggestion
1) reset all settings by Tools-->Import and Export Settings-->Reset all settings
2) close VS Instance, enter the project path and delete .vs hidden folder which stores some Intellisense settings, bin, obj folder and then restart your project again. I wonder if you migrate an old project into VS2019 preview version, I think you should complete this step.
3) disable any third party extensions if you have under Extensions-->Manage Extensions in case they cause this behavior.
4) delete all component caches under C:\Users\xxx\AppData\Local\Microsoft\VisualStudio\16.0_xxx(16.0 is VS2019)\ComponentModelCache
5) try to create a new project in VS2019 Preview version and test whether this issue persists in the new platform and if it works, I think it is an issue of your project itself. Or you can try to migrate your project into the new project.
Hope it could help you.
Related
I'm trying to update SDMPackageXML property of an AppModel application through C# code. SDMPackageXML is an XML property. I've to update only one node named AutoInstall in the
SDMPackageXML XML property. Here is my code:
ObjectGetOptions opt = new ObjectGetOptions(null, System.TimeSpan.MaxValue, true);
var path = new ManagementPath("SMS_Application.CI_ID=16777568");
ManagementObject obj = new ManagementObject(scope, path, opt);
obj.Get();
foreach (PropertyData property in obj.Properties)
{
if (property.Name == "SDMPackageXML")
{
//change the property value. Set AutoInstall to true
XmlDocument xml = new XmlDocument();
xml.LoadXml(property.Value.ToString());
var autoInstallTag = xml.GetElementsByTagName("AutoInstall");
autoInstallTag[0].InnerText = "false";
property.Value = xml.OuterXml;
}
}
obj.Put();
The problem is that obj.Put(); updates nothing on the SCCM server. Can someone help me please?
So similar to what I talked about in this answer the main problem here is that Microsoft uses a special method to serialize their XML. The deserialization still works with using the default classes but to serialize again there is no documentation as to how to (I'm pretty sure it is possible but I am not knowledgeable enough to do it)
Instead of documentation they provide wrapper classes for this which are shipped with the SCCM Console (Located in the bin directory of the Installation folder of the Console).
In this case this would be Microsoft.ConfigurationManagement.ApplicationManagement.dll. Unlike in powershell where the dependencies in the same path seem to be loaded as well you seem also to have to reference at least Microsoft.ConfigurationManagement.ApplicationManagement.TaskSequenceInstaller.dll as well.
There are also further dlls with names like Microsoft.ConfigurationManagement.ApplicationManagement.MsiInstaller.dll present however at least in my tests the two above were the only ones needed, but if you notice the deserialization failing with "InvalidPropertyException" errors you might need the dll matching your specific application type.
With those two dlls referenced you can write something like this (note I deserialized using the dll as well because why not if it is already loaded and it creates a nice application object to directly modify the properties. This is however technically not necessary. You could deserialize like in your example and only use the serialization part.
ManagementObject obj = new ManagementObject(#"\\<siteserver>\root\SMS\site_<sitecode>:SMS_Application.CI_ID=<id>");
Microsoft.ConfigurationManagement.ApplicationManagement.Application app = Microsoft.ConfigurationManagement.ApplicationManagement.Serialization.SccmSerializer.DeserializeFromString(obj["SDMPackageXML"].ToString(), true);
app.AutoInstall = true;
obj["SDMPackageXML"] = Microsoft.ConfigurationManagement.ApplicationManagement.Serialization.SccmSerializer.SerializeToString(app, true);
obj.Put();
Now one thing to keep in mind is that is can be a little tricky referencing the applications by their CI_ID because if you update the application the id for the currently valid version of the app changes (the old id still can be used to reference the older revision). So if you change the application gotten using the ID and then change it back with the same ID it will look like only the first change worked. I don't know if this is problematic for you (If you just get all IDs then change every application only once it should not matter) but if it does you can search for the application using their name plus isLatest = 'true' in the WQL query to always get the current one.
I used to work on an Android/Xamarin project for Android 4.4, API Level 19 that contains an activity with the following code:
private void RadioButtonClick(object sender, EventArgs e)
{
RadioButton rb = (RadioButton)sender;
switch (rb.Id)
{
case Resource.Id.radioButton1:
...
The last time I looked at the project a couple of month ago, this used to work just fine. Now I want to continue working on the project for Android 8.0, API Level 26, but when I opened it in Visual Studio 2017 I got the compiler error (field)int ResourceId.RadioButton1 A constant value is expected.
Now this is not a problem in itself, as I can always use if (rb.Id == ...) instead of switch/case, but I would like to know why all of a sudden Resource.Id.radioButton1 is not recognized as a constant anymore, even though it is declared as such in Resource.Designer.cs:
public const int radioButton1 = 2131165244;
Has anyone else encountered something similar?
EDIT: Even stranger is that the project builds without complaint, but deployment is not possible due to the said error.
EDIT: It seems that the build process generates another Resource.Designer.cs file which is put into a folder obj\Debug\designtime. Once the file exists, the activities source code refers for the Id declarations to this new file and not to the original Resource.Designer.cs in the Resources folder.
However, all Ids in the new file are static and not const (which of course is the reason for the compiler error that prompted this question in the first place) and moreover they are all set to zero.
Are there any Android/Xamarin experts out there who can explain what is going on here? Might that even be a bug in Visual Studio 2017/Xamarin?
EDIT: Here is a link shedding some light on this topic: https://forums.xamarin.com/discussion/19369/compiling-resource-ids-static-vs-const
What I don't get is this: Why did the above code work at all considering that this problem is known since 2014?
I'm changing our installer to support the possibility of having several versions of our software installed at the same time.
This leads to the scenario where several earlier versions of our product are installed and I need to let the user choose which of the current versions should be upgraded.
Currently I'm using a property called OLDERFOUND to detect if their are older versions at all:
<Upgrade Id='$(var.UpgradeCode)'>
<UpgradeVersion
OnlyDetect='yes'
Property='OLDERFOUND'
Minimum='0.0.0'
Maximum='$(var.Version)'
IncludeMaximum='no'
IncludeMinimum='yes' />
</Upgrade>
On OLDERFOUND a dialog whith a combobox is shown. I dynamically add items to the combobox using a c# CustomAction:
[CustomAction]
public static ActionResult FillVersionList(Session xiSession)
{
View view = xiSession.Database.OpenView("SELECT * FROM ComboBox");
view.Execute();
Record record = xiSession.Database.CreateRecord(4);
//CURRENTVERSIONS is the name of the combobox property
record.SetString(1, "CURRENTVERSIONS");
record.SetInteger(2, 1);
record.SetString(3, "foo");
record.SetString(4, "foo");
view.Modify(ViewModifyMode.InsertTemporary, record);
record = xiSession.Database.CreateRecord(4);
record.SetString(1, "CURRENTIVARVERSIONS");
record.SetInteger(2, 2);
record.SetString(3, "bar");
record.SetString(4, "bar");
view.Modify(ViewModifyMode.InsertTemporary, record);
view.Close();
return ActionResult.Success;
}
What I can't figure out how to do is
populate the combobox with all previous installed versions
and then update the one chosen by the user
I tried to figure out a way to read from the registry to get all versions (I have a registry key for each version installed), but haven't come up with anything. I have no idea how to specify which earlier version to update.
I dont understand why you want the user to select which version to upgrade. When your new product is distributed, it will have an upgrade code/product/package code combination which matches one of the previous installation and it can be used to upgrade ONLY that installation. You wont be able to change that behaviour based on user's decision.
Read more about the upgrade code/product code here:
UPGRADE CODE
Product vs package vs upgrade code
I am looking for a way to have my extension check if the currently opened window in visual studio 2012 is one, where the user can write code (or any kind of text, really).
To check if the currently opened window has changed, I use
_DTE.Events.WindowEvents.WindowActivated.
This gives me the EnvDTE.Window that received the focus.
When I look at the properties of that window while debugging, and I look at EnvDTE.Window.Document.Type and it's value is "Text".
However, if I stop debugging and try to access the Document.Type property, it does not exist.
If I look for this property in the documentation of EnvDTE.Window.Document, its description says
Infrastructure. Microsoft Internal Use Only.
So now I am looking for any advice on how I could check if the currently active window is one, where I can write code (or anything else), or some other kind of document (like the solution properties for example).
Edit:
I also tried checking Window.Type and Window.Kind of the active window, but they just tell me that it's a document, not making any differentiation between a resource file, an image file or an actual source file, which is what I'm trying to find out.
Edit²:
The reason why I want to check if the current document is one where I can write code in, is because I want my extension to store information about some of those documents and I want to modify the right-click context menu based on the information I have stored, if any.
It is not a "real" answer, but you can follow status of VS GoTo command - it is available only for text editors:
bool isCodeWindow = IsCommandAvailable("Edit.GoTo");
private bool IsCommandAvailable(string commandName)
{
EnvDTE80.Commands2 commands = dte.Commands as EnvDTE80.Commands2;
if (commands == null)
return false;
EnvDTE.Command command = commands.Item(commandName, 0);
if (command == null)
return false;
return command.IsAvailable;
}
You can check to see if the document is a 'TextDocument'
bool isCodeWindow = dte.CurrentDocument.Object() is EnvDTE.TextDocument;
I've read several articles that tell you how to add text to the output window in visual studio from within an Add-On (specifically, a visual studio 2008 integration package, via the visual studio 2008 SDK 1.1), but no examples of how to read text from the output window. My goal is to parse text from the debug output window while debugging a certain application (TRACE output and possibly stdin/stdout). The IVsOutputWindowPane interface has no methods for reading in text from the output window. The documentation seems to imply that it is possible, but it doesn't provide an example:
http://msdn.microsoft.com/en-us/library/bb166236(VS.80).aspx
Quote: In addition, the OutputWindow and OutputWindowPane objects add some higher-level functionality to make it easier to enumerate the Output window panes and to retrieve text from the panes.
Preferably I'd like to be able to subscribe to an event that fires when a new line of text arrives, similar to a StreamReader's asynchronous reads.
It is possible, it is just a long winding path to get to it:
ServiceProvider -> IVsOutputWindow -> GetPane( debugwindow ) -> IVsUserData -> GetData( wpftextviewhost ) -> IWpfTextViewHost -> IWpfTextView -> TextBuffer -> Changed event.
Presuming you have a VS IServiceProvider from somewhere else (vsix extension/whatever, global service provider), and without any error checking, it looks like this:
IVsOutputWindow outWindow = ServiceProvider.GetService(typeof(SVsOutputWindow)) as IVsOutputWindow;
Guid debugPaneGuid = VSConstants.GUID_OutWindowDebugPane;
IVsOutputWindowPane pane;
outWindow.GetPane(ref debugPaneGuid, out pane);
// from here up you'll find in lots of other stackoverflow answers,
// the stuff from here down is interesting to this question
IVsUserData userData = (IVsUserData)pane;
object o;
Guid guidViewHost = DefGuidList.guidIWpfTextViewHost;
userData.GetData(ref guidViewHost, out o);
IWpfTextViewHost viewHost = (IWpfTextViewHost)o;
IWpfTextView textView = viewHost.TextView;
textView.TextBuffer.Changed += YourTextChangedHandlerHere;
Your text changed handler will then get called every time the output window gets more data. you won't necessarily get it line by line, but you'll probably more likely than not get big chunks you'll need to deal with on your own.
It is highly likely that some of the above did not even exist in VS in 2010. But it exists now!
The default behavior (when you don’t set the listener explicitly) of VS is to display trace massages in the debugger output window, which you appreciate if you want a simple solution and do no other actions with the massages.
Unfortunately this is not your case. So you have to define a trace listener to send (and store) your trace massages where you then will be able to read them. The trace listener could be a file (for example XML) or you can create a custom listener by deriving a class from the base class TraceListener if you don't want to bother yourself with an additional file.
I don't know that what you ask is possible. But, you can register your add-in as a debugger for your application so that you get the output the trace messages. These are typically routed to OutputDebugString, and can be captured as described in this article: http://www.drdobbs.com/showArticle.jhtml?articleID=184410719. It does not give you the normal output, only debug, but it does not depend on the technology of the debugged application.
The solution on this page selects the text in order to read it. I'm hoping there's a better way.
Automatically stop Visual C++ 2008 build at first compile error?
Private Sub OutputWindowEvents_OnPaneUpdated(ByVal pPane As OutputWindowPane) Handles OutputWindowEvents.PaneUpdated
pPane.TextDocument.Selection.SelectAll()
Dim Context As String = pPane.TextDocument.Selection.Text
pPane.TextDocument.Selection.EndOfDocument()
End Sub