Read and change project properties "Start external program" and "command line arguments" - c#

I'm trying to read (and change) the project properties "Start external program" and "Command line arguments" of a VisualStudio 2013 project within a VSPackage. The code I wrote so far looks like:
var dte = GetService(typeof(DTE)) as DTE2;
if (dte == null)
return;
var sb = (SolutionBuild2)dte.Solution.SolutionBuild;
var projectNames = sb.StartupProjects as Array;
if (projectNames == null || projectNames.Length == 0)
return;
var project = dte.Solution.Item(projectNames.GetValue(0));
var config = project.ConfigurationManager.ActiveConfiguration;
But I can't find the two spcific properties neither in the project nor in the config.

The EnvDTE.Configuration class has a Properties collection that has your desired values:
config.Properties.Item("StartProgram").Value
config.Properties.Item("StartArguments").Value
FWIW, the VSLangProj.dll assembly has a VSLangProj.ProjectConfigurationProperties class with the property names that you can expect in the config.Properties collection.

Related

Resource files not detected when using restext files

I am working on the HealthVault SDK from Microsoft, I am trying to include a few translations for the text resources provided with SDK.
This is a piece of resource file used
resources.restext
# Used in many files
ListSeparator=,
ListFormat=, {0}
GroupSeparator=;
GroupFormat=; {0}
Range={0} - {1}
DateRange={0} to {1}
This is the code that initializes the Resource manager.
private static ResourceManager InitRMWithAssembly(
string baseName,
Assembly assemblyToUse,
Type usingResourceSet)
{
ResourceManager rm = null;
if (usingResourceSet != null &&
baseName != null &&
assemblyToUse != null)
{
rm =
new ResourceManager(
baseName,
assemblyToUse,
usingResourceSet);
}
else if (usingResourceSet != null &&
baseName == null &&
assemblyToUse == null)
{
rm = new ResourceManager(usingResourceSet);
}
else if (usingResourceSet == null &&
baseName != null &&
assemblyToUse != null)
{
rm = new ResourceManager(baseName, assemblyToUse);
}
else
{
throw new ArgumentException("assemblyToUse cannot be null", "assemblyToUse");
}
return rm;
}
where baseName is resources, assemblyToUse is Assembly.GetCallingAssembly().
The default strings are present in a text file named resources.restext. I wish to translate a few strings to Swedish and I added resources.sv-se.restext and made the translations. When I built the project, Satellite assembles were created in the bin folder inside a folder named sv-se. But the strings are still taken from the default resource file. I modified the default file and the changes are reflected immediately.
I tried loading the dll manually and the manifest names consisted of a name Microsoft.Health.ItemTypes.resources.sv-se.resources. I initialized the ResourceManager with that name and the same assembly.
var rm = new ResourceManager("Microsoft.Health.ItemTypes.resources.sv-se.resources", assembly);
rm.GetString("Key"); // Causes MissingManifestResourceException
However, I tried and was able to get the key by using the following
var rm = new ResourceManager("Microsoft.Health.ItemTypes.resources.sv-se", assembly); // manifest name - trailing resources
rm.GetString("Key"); // works!
My question is this:
What is the correct way to use ResourceManger? Should the satellite assembly be passed to the RM constructor? and how must be the resource files named, so that I do not have to edit the manifest name to create the resource manager instance?
Solved.
In the .csproj for the project, the logical name of the resource was changed.
Changing the csproj to following solved my issues
<ItemGroup>
<EmbeddedResource Include="resources.restext">
<LogicalName>resources.resources</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="resources.sv-se.restext">
<LogicalName>resources.sv-se.resources</LogicalName>
</EmbeddedResource>
</ItemGroup>

How to skip the code which produces error when dll is Missing in C#?

I have a Console Application in C# and a Class Library named AppManager.cs. The Method of this class is used in the console Application as given below.
try
{
AppManager mgr = new AppManager(); //Want to skip this line when dll is missing.
mgr.Method_Name(this, true); //Want to skip this line when dll is missing.
}
catch (Exception)
{
}
When I have published the Code and extracted only exe then application fails to run [I know as the exe try to find that dll and method present in dll won't available].
Now my Question is That Is there any way to skip the code which will produce error when it will not find the reference of dll.
I also tried this but it didn't worked:
String file = null;
String filePath = Path.GetDirectoryName(Application.ExecutablePath);
file = Directory.GetFiles(filePath, "myLibrary.dll", SearchOption.AllDirectories)
.FirstOrDefault();
if (file != null)
{
AppManager mgr = new AppManager();
mgr.Method_Name(this, true);
}
If you do that, it won't give the desired output too. Why don't you integrate the dll with your exe? You can do it by using this tool
Can you not simply check if the dll exists or not?
string filePath = #"SOME_PATH";
var exists = File.Exists(filePath);
if(exists)
{
AppManager mgr = new AppManager();
mgr.Method_Name(this, true);
}

How to "programmatically" integrate diff tool with Visual Studio

Is there a way to "programatically" integrate a diff tool (like WinDiff and WinMerge) with Visual Studio 2010? These files are not the files found at Solution Explorer.
The program would have to search and store in the List the files found from certain directory, and then compare the files with same names recursively.
As far as I can gather, you're looking for the TFS Difference class. Here's an example of how to use it:
string f1 = #"file1.cs";
string f2 = #"f2.cs";
Microsoft.TeamFoundation.VersionControl.Common.DiffOptions options = new Microsoft.TeamFoundation.VersionControl.Common.DiffOptions();
options.Recursive = true;
options.StreamWriter = new System.IO.StreamWriter(Console.OpenStandardOutput());
options.UseThirdPartyTool = true;
options.OutputType = Microsoft.TeamFoundation.VersionControl.Common.DiffOutputType.Unified;
var diff = Difference.DiffFiles(
f1, FileType.Detect(f1, null),
f2, FileType.Detect(f2, null),
options);
while (diff != null)
{
// Do whatever it is that you want to do here
diff = diff.Next;
}
You may want to take a look whether this extension is what you need: http://visualstudiogallery.msdn.microsoft.com/dace3633-0b51-4629-85d4-c59cdce5bb3b?SRC=Featured

How to cast ComObject to ENVDTE.Project for Unmodeled projects?

My question is very similar to this one: How to cast ComObject to ENVDTE.Project?
I want to process the Project items selected in Visual Studio -> Solution Explorer. If project is loaded the code works fine but I have troubles for unloaded projects (they are called Unmodeled projects (http://msdn.microsoft.com/en-us/library/hw7ek4f4%28v=vs.80%29.aspx).
Casting selected item for loaded projects uiItem.Object is EnvDTE.Project is fine, but how to cast Unmodeled projects?
There is no 'UnmodeledProject' class and casting uiItem.Object is ProjectItem does not work.
This is my code:
Window solutionExplorer = mApplicationObject.Windows.Item(Constants.vsWindowKindSolutionExplorer);
if(solutionExplorer != null)
{
UIHierarchy uiHierarchy = (UIHierarchy)solutionExplorer.Object;
if (uiHierarchy != null)
{
object[] selectedItems = (object[])uiHierarchy.SelectedItems;
foreach (UIHierarchyItem uiItem in selectedItems)
{
// Valid project
if (uiItem.Object is EnvDTE.Project)
{
EnvDTE.Project project = uiItem.Object as EnvDTE.Project;
if (project.FullName.Contains(".vdproj") || project.Kind == "{54435603-DBB4-11D2-8724-00A0C9A8B90C}")
{
}
}
else if (uiItem.Object is ProjectItem)
{
// This is never jumped...
}
else
{ ...
As I did not find a solution for this situation I used this trick:
string pathToVdProject = null;
try
{
Window solutionExplorer = mApplicationObject.Windows.Item(Constants.vsWindowKindSolutionExplorer);
if (solutionExplorer != null)
{
UIHierarchy uiHierarchy = (UIHierarchy)solutionExplorer.Object;
if (uiHierarchy != null)
{
object[] selectedItems = (object[])uiHierarchy.SelectedItems;
foreach (UIHierarchyItem uiItem in selectedItems)
{
// Valid project
if (uiItem.Object is EnvDTE.Project)
{
EnvDTE.Project project = uiItem.Object as EnvDTE.Project;
if (project.FullName.Contains(".vdproj") || project.UniqueName.Contains(".vdproj")
|| (String.Compare(project.Kind, ProjectsGuids.guidVdSetupProject, true) == 0))
{
// Valid Project has property FullName which is full path to .vdproj file
pathToVdProject = project.FullName;
break;
}
}
else if (uiItem.Object is ProjectItem)
{
// This never happens...
}
else
{
// This is a little tricky: Unmodeled Projects cannot be casted to EnvDTE.Project http://msdn.microsoft.com/en-us/library/hw7ek4f4%28v=vs.80%29.aspx
Solution2 solution = (Solution2)mApplicationObject.Solution;
// So get all projects in solution (including unmodeled) and try to find a match by name
foreach (Project project in solution.Projects)
{
if (project.Kind == EnvDTE.Constants.vsProjectKindUnmodeled)
{
// Unmodeled project found (Normal projects are recognized in 'uiItem.Object is EnvDTE.Project'
if (project.Name.Contains(uiItem.Name))
{
// This is 'Project' for selected item
if (project.Name.Contains(".vdproj") || project.UniqueName.Contains(".vdproj"))
{
// Unmodeled projects does not offer property FullName and UniqueName does NOT contain full path to file!
FileInfo fileInfo = new FileInfo(solution.FullName);
// Create full path from solution (.sln) path and project relative path
pathToVdProject = fileInfo.DirectoryName + "\\" + project.UniqueName;
break;
}
}
}
}
}
}
}
}
List of all loaded/Unloaded projects inside the solution explorer will be available in your EnvDTE application object. Without using solution Explorer window and UIHierarchy i got the project details. Below code snippets working fine for me. Please check out weather it will fit for you..
For Each item As EnvDTE.Project In mApplicationObject.Solution.Projects
If item.Globals Is Nothing AndAlso item.Object Is Nothing Then
Console.WriteLine(item.Name + " is currently unloaded!")
End If
Next

Assigning TestCases to TestFolders via Rally web service

I have a situation where there are lots of test cases that don't belong to a test folder. This is fine, but I'd like to write an application to move these 'orphaned' test cases into a test folder (mostly so it's easy to easily see how the tests are doing)
All of the test cases and the test folder I create are in the same project, but I get the following errors;
Validation error: TestFolder.TestCases is an invalid relationship. One or more of the artifacts is in a different project.
Validation error: TestCase.TestFolder is an invalid relationship. One or more of the artifacts is in a different project.
These seem to be telling me that I am assigning the test cases to a test folder in a different project - but they aren't.
Here's a snip of the code - m_currentRallyProject and m_workspace have already been set by a different method
Any thoughts?
public void CreateTestFolderForOrphanedTestCases(HierarchicalRequirement aUserStory, List<TestCase> testCases)
{
TestFolder myNewTestFolder = createTestFolder(aUserStory.Name);
for (int i = 0; i < testCases.Count; i++)
{
TestCase myTestCase = (TestCase)testCases[i];
myTestCase.TestFolder = myNewTestFolder;
OperationResult myResult = m_rallyService.update(myTestCase);
if (hasErrors(myResult))
{
updateStatus("Could not set Test Folder for " + myTestCase.FormattedID);
printWarningsErrors(myResult);
}
else
{
updateStatus("updated test case " + myTestCase.FormattedID);
}
}
}
private TestFolder createTestFolder(String testFolderName, TestFolder aParentTestFolder = null)
{
TestFolder myNewTestFolder = new TestFolder();
myNewTestFolder.Name = testFolderName;
myNewTestFolder.Project = m_currentRallyProject;
myNewTestFolder.Workspace = m_workspace;
CreateResult createTestFolderResult = m_rallyService.create(myNewTestFolder);
if (hasErrors(createTestFolderResult))
{
// something went wrong
Console.WriteLine("Could not create Test Folder");
printWarningsErrors(createTestFolderResult);
}
else
{
myNewTestFolder = (TestFolder)m_rallyService.read(createTestFolderResult.Object);
return myNewTestFolder;
}
return null;
}
Dropping an answer in from the comments above :)
Make certain they're in the same project - you shouldn't get this message if they are. Being in the same Project Hierarchy doesn't count. I.E. a Test Folder that is in a Child Project of the current Project, even with child scoping down = true, counts as being in a different Project. Try adding some logging that outputs the Project Name or ref for both the Test Case and the Target Test Folder.
If you add some logging that outputs Project metadata for both TestCase and target TestFolder, make sure to output both Name and ref - since Project Name is not guaranteed to be unique (different Rally Projects can have the same Name).

Categories