Adding File under label header or source Visual Studio add-in - c#

With Following code I am able to add new files to visual studio project.
DTE dte = GetService(typeof(DTE)) as DTE;
System.Array theProjects = (System.Array)dte.ActiveSolutionProjects;
EnvDTE.Project theProject = null;
if (theProjects.Length > 0)
{
theProject = (EnvDTE.Project)(theProjects.GetValue(0));
EnvDTE.ProjectItem projItem = null;
projItem = theProject.ProjectItems.AddFromFile(#"E:\Avinash\test.cpp");
}
But if i have to add a header file, how do i add it under header label.

If I correctly understand what you are trying to do, I think you mean that you want to add your header files in the header folder. If it's already there you have to look for it among the items for your project. I.e. you have to loop looking for the ProjectItem with the name you are looking for. If it's not already there, you can add it using the AddFolder of ProjectItemsCollection, which returns the newly created ProjectItem. In either case you end up with a ProjectItem representing the headers folder. Now you can add your file to the ProjectItems of this object instead of the ProjectItems of the Project. Something like this:
theProject = (EnvDTE.Project)(theProjects.GetValue(0));
EnvDTE.ProjectItem projItem = null;
EnvDTE.ProjectItem hdrProjItem = theProject.ProjectItems.AddFolder("Header files", null);
projItem = hdrProjItem.ProjectItems.AddFromFile(#"E:\Avinash\test.cpp");
Anyway, I still think a template could avoid you much effort and pain

Related

Property of an AppModel application not getting updated in SCCM

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.

VlcLibDirectory not found

I'm using VS 2017 and coding in C#. I installed the 4 Vlc libraries to play videos in a Windows Form Application. I put a Vlc control in the form. And then, in the code, I wrote:
vlcControl1.SetMedia(curFolder + #"\media\1.mp4");
vlcControl1.Play();
When I run it, I get a "VlcLibDirectory not found". What I need to do? I see that I can set that directory through visual controls, in the VlcControl1 properties, but what is that folder?
I'm sorry this is late...
You got the first part, getting the packages in Visual Studio, now you need the libraries for it.
Download this: https://github.com/ZeBobo5/Vlc.DotNet/tree/master
Put the lib directory somewhere the application can find it, and set that VlcLibDirectory equal to a new DirectoryInfo(path to dir).
I did it like this:
var libDirectory = new DirectoryInfo(Path.Combine(".", "libvlc", IntPtr.Size == 4 ? "x86" : "x64"));
vlcControl1 = new Vlc.DotNet.Forms.VlcControl();
vlcControl1.VlcLibDirectory = libDirectory;
The library that it needs to be loaded is libvlc.dll that is found in the folder where is installed the VLC software.
I visited practically every Google result page for this, almost lost hope, but this worked for me in the end:
1) Created an object in my FormsApp file:
VlcControl vlcControl1 = new VlcControl();
2) Instantiated it in the constructor:
VlcControl vlcControl1 = new VlcControl();
3) In my FormsApp_Load() added the following lines:
vlcControl1.BeginInit();
vlcControl1.VlcLibDirectory = new DirectoryInfo(_exeFolder + #"\libvlc\win-x86"); //Make sure your dir is correct
vlcControl1.VlcMediaplayerOptions = new[] { "-vv"}; //not sure what this does
vlcControl1.EndInit();
YourControlContainer.Controls.Add(vlcControl1); //Add the control to your container
vlcControl1.Dock = DockStyle.Fill; //Optional
this.vlcControl1.Click += new EventHandler(vlcControl1_Click); //Optional - added a click event .Play()
Hope this helps someone.
I've also experienced this problem.
I just look into the properties of the VlcControl on the Form and change the VlcLibDirectory item under the Media Player category by browsing to the directory which the "libvlc.dll" located.
(in my application C:\Users\MCOT\source\repos\WindowsApp3\packages\VideoLAN.LibVLC.Windows.3.0.6\build\x86)
#Thanin's answer is what I needed, ... here is a code snippet to where the library should be installed.
//InitializeComponent();
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(
"SOFTWARE\\VideoLAN\\VLC",
RegistryKeyPermissionCheck.ReadSubTree,
RegistryRights.QueryValues))
{
_Vlc.SourceProvider.CreatePlayer(
new DirectoryInfo(rk.GetValue("InstallDir") as string),
new string[] { });
}

Sharepoint 2010 Programmatically Update List Item in Event Handler

Background
We have a custom developed installed .WSP on a SharePoint 2007 environment and have been in the process of upgrading to 2010. With the upgrade the custom event trigger no longer worked so trying to update and make it work in 2010. But I am running into one issue. Original developers no longer here and I've been the lucky one to have to figure this one out without much of a background with SP Dev.
Goal
When a new list item is created trigger event. Within event, create a shared folder using Item Name and return url, create a wiki-page using item name and include shared document link and return url to wiki page. Part three is update newly created list item with the New Folder url and Wiki Page URL.
Issue
I've gotten the first two parts working but so far have been unable to update the newly created list item with the new Links. I'm able to get the links. I've tried all the basic stuff for updating the list that I have been able to find online with no luck. Nothing to complicated(or so I think). But code is included below. VS is not installed on the server so unable to run debug mode, I don't have direct access to the server. When you create the item there are no client/user side error. Haven't been able to find a log file that has any, that is if it collects errors if the script were to fail out.
Initiation of the Event
public class CreateWikiAndFolder : Microsoft.SharePoint.SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
try
{
//this.DisableEventFiring();
base.EventFiringEnabled = false;
string sUrlOfWikiPage = string.Empty;
string sUrlOfNewFolder = string.Empty;
string sSubsiteRUL = string.Empty;
string sCurrentItemTitle = properties.ListItem["Title"].ToString();
string sWikiListName = "TR Wikis";
string sDocLibName = "Shared Documents";
string sTRListID = "TR Status";
if (sTRListID.ToUpper().Equals(properties.ListTitle.ToString().ToUpper()))
{
//Create the Folder
sUrlOfNewFolder = CreateFolder(properties.ListItem.Web, sDocLibName, sCurrentItemTitle);
//Create the Wiki
string ItemDispFormUrl = String.Concat(properties.ListItem.Web.Url, "/", properties.ListItem.ParentList.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url, "?ID=", properties.ListItem.ID.ToString());
sUrlOfWikiPage = CreateWiki(properties.ListItem.Web, sWikiListName, sCurrentItemTitle, ItemDispFormUrl, sUrlOfNewFolder);
//Update the current TR Item
//Have tried. properties.ListItem["WikiURL"] = sUrlOfWikiPage + ", " + "Wiki";
SPListItem myListItem = properties.ListItem;
SPFieldUrlValue shareFolderURLValue = new SPFieldUrlValue();
shareFolderURLValue.Description = "Shared Folder";
shareFolderURLValue.Url = sUrlOfNewFolder ;
myListItem["SharedFolder"] = shareFolderURLValue;
//I've tried each one separate and together to no luck
myListItem.UpdateOverwriteVersion();
myListItem.Update();
//properties.ListItem.UpdateOverwriteVersion();
}
base.EventFiringEnabled = true;
}
}
}
Note that this is the last thing needed to be figured out for our upgrade.
Got it working. I did both of these at the same time so I'm not sure if it was the combination of both or only one of the items. But one I removed the myListItem.UpdateOverwriteVersion(); line and surrounded the item updated with web.AllowUnsafeUpdates being set to true before and then back to false afterwards.
Also as a note to others, you need to save the properties.ListItem to its own SPListItem which you then update versus trying to manipulate the values at the properties.ListItem["Attribute"], and then update the properties.ListItem.Update. SharePoint doesn't allow the latter option so you have to save to an independent SPListItem, and then modify and update that one. This might not be the best SharePoint lingo, but that is what needs to be done.

Getting the selected file and using IVsSingleFileGenerator

I am trying to add several new functions to a package I developed for our company. One of these functions is to create a new file based on the file selected in the solution explorer and the menu option selected. I have created my dynamic menu items that are on the solution explorer and it looks like I need to use IVsSingleFileGenerator as shown in this sample.
The trouble I am having is getting the file I have selected and either reading it or passing it into a single file generator.
I would rather generate the file from this context menu than from a custom tool action
Looks like this will get me the path of the file
UIHierarchy solutionExplorer = _applicationObject.ToolWindows.SolutionExplorer;
var items = solutionExplorer.SelectedItems as Array;
if (items == null || items.Length != 2)
{
return;
}
String strFile1 = String.Empty;
UIHierarchyItem item1 = items.GetValue(0) as UIHierarchyItem;
foreach (UIHierarchyItem hierarchyItem in items)
{
ProjectItem prjItem = hierarchyItem.Object as ProjectItem;
string prjPath = prjItem.Properties.Item("FullPath").Value.ToString();
}
which I can then use to pass into the generate function of the ivs single file generator.
Is this the best approach?
I also posted this question to the msdn forums at:
VSX getting the selected file and using IVsSingleFileGenerator
I ended up using the IPyIntegration sample to figure out what i needed to do.

How do I find and open a file in a Visual Studio 2005 add-in?

I'm making an add-in with Visual Studio 2005 C# to help easily toggle between source and header files, as well as script files that all follow a similar naming structure. However, the directory structure has all of the files in different places, even though they are all in the same project.
I've got almost all the pieces in place, but I can't figure out how to find and open a file in the solution based only on the file name alone. So I know I'm coming from, say, c:\code\project\subproject\src\blah.cpp, and I want to open c:\code\project\subproject\inc\blah.h, but I don't necessarily know where blah.h is. I could hardcode different directory paths but then the utility isn't generic enough to be robust.
The solution has multiple projects, which seems to be a bit of a pain as well. I'm thinking at this point that I'll have to iterate through every project, and iterate through every project item, to see if the particular file is there, and then get a proper reference to it.
But it seems to me there must be an easier way of doing this.
To work generically for any user's file structure, you'll need to enumerate all the files in all the projects. This should get you started. And, well, pretty much finished :-)
internal static string GetSourceOrInclude(bool openAndActivate)
{
// Look in the project for a file of the same name with the opposing extension
ProjectItem thisItem = Commands.Application.ActiveDocument.ProjectItem;
string ext = Path.GetExtension(thisItem.Name);
string searchExt = string.Empty;
if (ext == ".cpp" || ext == ".c")
searchExt = ".h";
else if (ext == ".h" || ext == ".hpp")
searchExt = ".cpp";
else
return(string.Empty);
string searchItemName = thisItem.Name;
searchItemName = Path.ChangeExtension(searchItemName, searchExt);
Project proj = thisItem.ContainingProject;
foreach(ProjectItem item in proj.ProjectItems)
{
ProjectItem foundItem = FindChildProjectItem(item, searchItemName);
if (foundItem != null)
{
if (openAndActivate)
{
if (!foundItem.get_IsOpen(Constants.vsViewKindCode))
{
Window w = foundItem.Open(Constants.vsViewKindCode);
w.Visible = true;
w.Activate();
}
else
{
foundItem.Document.Activate();
}
}
return(foundItem.Document.FullName);
}
return(string.Empty);
}
Note that it is possible for a header to be in the include path without being added to the project, so if the above fails, you could potentially look in the include paths for the containing project too. I'll leave that as an exercise for the reader.

Categories

Resources