Visual Studio Reference Not Being Copied Over In Multiple Project Environment - visual-studio

I have a solution file in VS 2010 and it has multiple projects in it.
Now, I have a reference to this dll call MySql.Data.Entity.dll.
As an example, I have the following projects setup in the solution:
Domain (reference to MySql.Data.Entity.dll)
Domain.Test (reference to the project "Domain")
I want that Domain.Test to copy over all the references from Domain, so I set the Property on that dll to "Copy Local - True". It did not copy over to the Domain.Test project.
I have encounter this problem from before with over dlls. What I did was this:
namespace Domain.Helpers
{
/// <summary>
/// To trick VS to deploy required assemblies
/// </summary>
class BuildTricker
{
public void AssemblyTricker()
{
new LinFu.DynamicProxy.CallAdapter(null);
new NHibernate.ByteCode.LinFu.ProxyFactory();
}
}
}
And worked fine. If I "use" the class it will know to copy it over to "Domain.Test".
Problem with this is that there is nothing I can initialize/"use" from this MySql.Data.Entity.dll.
Note: Just adding the namespace in a Using statement won't do the trick, you HAVE TO "use" a class in the dll for it to be copied over.
I am currently manually referencing this dll into all the projects that requires it.
So, my question is. Is there something wrong with my configuration? Or is this a VS limitation?
Thanks,
Chi

That's the catch with COMReferences, they're not resources, so they don't get copied.
By setting the reference to MySql.Data.Entity.dll's Isolated property to True, the file is copied over from its original location to your "Domain" project's bin folder and finally to your "Domain.Test" project's bin folder.

Related

Visual Studio 2010 Not Recognizing Unit Test

In an existing solution I added a new Test Project. In my Test Project .cs file I have a class decorated with the [TestClass] attribute and a method decorated with the [TestMethod] attribute. I have verified that in Configuration Manager the build check box is checked for the Test Project (as my google search has revealed was the problem for others with this issue). I have set Test Project as my start up project for the solution. When I try to start the test I get "Can not start test project because the project does not contain any tests". I am really new to unit testing. What am I missing?
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Whole bunch of stuff
Assert.Inconclusive("Done");
}
}
Update: So I opened a new instance of VS, went to File => New => Project => Test Project. Did not touch or edit anything. Went straight to the cs file and here are its contents in its entirety:
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace TestProject2
{
public class Inspection
{
public bool SubmitInsp()
{
return true;
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Inspection insp = new Inspection();
bool result = insp.SubmitInsp();
Assert.IsTrue(result);
}
}
}
Same error about the project not containing any test when I try to start it. Also found this in the build output "Could not load file or assembly '~\my documents\visual studio 2010\Projects\TestProject2\bin\Debug\TestProject2.dll' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)"
I don't know that units tests get much simpler than this. What the heck???
I've had the same problem, when tests in an working test project suddenly weren't recognized anymore.
Comparing the project file with one from another working test project showed me that the <ProjectTypeGuids> node was missing from the main <PropertyGroup> node.
Adding this line inside the <PropertyGroup> node solved my problem:
C#:
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
VB:
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{F184B08F-C81C-45F6-A57F-5ABD9991F28F}</ProjectTypeGuids>
I was able to get this to work by modifying the devenv.exe configuration file found here:
C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe.config.
Add the following line to the <runtime> section, then restart Visual Studio:
<loadFromRemoteSources enabled = "true" />
(Here is the link that helped me)
The FrstCBC's anwser did not worked for me.
I am on a VirtualBox machine with Windows 7 64 bits and Visual Studio 2012.
I had to move the output to a local folder : open the unit tests project properties and in the Build tab, browse the Output path to a local folder. The tests are now detected and can be run.
Test Projects saved to a network folder or anywhere locally on my computer have this issue. Created another Test Project and saved it to my flash drive, works just fine. I don't know if it is because my machine is 64 bit or because its a virtual machine or what, but I guess I just need to test everything on external storage devices.
For me it was just that my class and method weren't public (I realize the poster did have public, but I found this post by Googling "testclass testmethod margin icons missing"). Dumb mistake on my part, but maybe it will help others.
Verify that all the .cs files are marked as Compile in the Properties window. If it is marked as Content then you will hit this issue.

Find Install directory and working directory of VSTO Outlook Addin; or any Office Addin

I created a VSTO Outlook Addin that uses a library Html2Xhtml.dll (.NET) which calls another Html2xhtml.exe by executing System.Diagnostic.Process.Start().
However, it fails to call Html2xhtml.exe (i think) because the working directory even when launched from Visual Studio is the current user My Documents folder. I have no control over the code in Html2Xhtml.dll so I cannot use absolute path; but I suppose I can change the working directory of the Add-in at runtime.
However, If I install this via ClickOnce or some other means where I do not know the install path the user is going to choose, how am I suppose to find my Html2xhtml.exe?
I found the answer here, full credits to robindotnet.wordpress.com.
//Get the assembly information
System.Reflection.Assembly assemblyInfo = System.Reflection.Assembly.GetExecutingAssembly();
//Location is where the assembly is run from
string assemblyLocation = assemblyInfo.Location;
//CodeBase is the location of the ClickOnce deployment files
Uri uriCodeBase = new Uri(assemblyInfo.CodeBase);
string ClickOnceLocation = Path.GetDirectoryName(uriCodeBase.LocalPath.ToString());
I've had a similar problem and solved it the same way as described by Christoph, I would also like to know whether there are any alternative ways of doing this but if you don't find anything here's an example
1)Create a custom actions library with the following InstallerClass
using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Microsoft.VisualStudio.Tools.Applications;
using Microsoft.Win32;
namespace Setup.CustomActions
{
[RunInstaller(true)]
public partial class AddCustomization : Installer
{
static readonly Guid solutionID = new Guid("d6680661-c31e-4c24-9492-5919dc0uagt5");
public override void Install(IDictionary stateSaver)
{
string installPath = Context.Parameters["installPath"];
if(!String.IsNullOrEmpty(installPath))
{
AddTemplateToAvailableTemplates(installPath);
}
base.Install(stateSaver);
}
public override void Rollback(IDictionary savedState)
{
}
public override void Uninstall(IDictionary savedState)
{
}
private void AddTemplateToAvailableTemplates(string installPath)
{
//The example below is very basic, put in checks to see whether the registry key already exists and so on
RegistryKey key = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Office\14.0\Common", true);
RegistryKey acturisKey = key.CreateSubKey(#"Spotlight\MyAppInstallPath");
acturisKey.SetValue("InstallPath", installPath);h);
}
}
}
2)In the setup project create a key on the Install custom action which points to the install directory:
If you need more info or would like to download the source have a look at this msdn post by Open Xml MVP Wouter Van Wugt titled "Deploying a Visual Studio 2010 Tools for Office Solution Using Windows Installer"
That is a real problem I had to fight with for quite some time. The solution used in an AddIn I had to work with was to write the install dir into the registry and read the value from there. That way things brought along which could not be embedded into the exe could be found. This is not a good solution but it worked.
Why MS sticks to this stupid "security mechanism" of copying the DLL to a random directory is a secret they will probably never reveal.
While writing my comment I actually had an idea which I did not try so far: Make your installer copy the files you need later on to %appdir%\YourCompany\YourApplication\libs or some such. You should be able to find your stuff then during runtime.
Had the same issue for ClickOnce applications. Here is what you need to do to get the deployment path of the addin:
Add System.Deployment.Application reference in your application
next is to use this property to retrieve the deployment path:
ApplicationDeployment.CurrentDeployment.UpdateLocation.ToString()
and there you go!
For COM plugins System.Reflection.Assembly.Location doesnt stable deliver what we need.
But even if it's possible to save the installation directory anyhow in the registry, it's not neccessary. Because:
A COM plugin has usualy a ID. You can define it with the GuidAttribute.
During installation/registration of your plugin, informations about this assembly are stored under:
Computer\HKEY_CLASSES_ROOT\CLSID\{...myPlugin id ....}\InprocServer32
in attribute "Codebase" you find the path to your file.
e.g.: file:///C:/Program Files/myPlugin.dll

Embedded Resource missing in Visual Studio 2010 when name ends with "No.xxx"

I've come across a strange behaviour in Visual Studio 2010.
When using embedded resources (files which are added to my C# project and for which the Build Action property is set to Embedded Resource), the files are included in the output assembly as binary data. Listing the resources is straightforward:
class Program
{
static void Main(string[] args)
{
string[] names = typeof (Program).Assembly.GetManifestResourceNames ();
foreach (var name in names)
{
System.Console.Out.WriteLine (name);
}
}
}
However, if the embedded resource file name ends with No.xxx (the extension is irrelevant), the file does not show up in the list. I cannot figure out any reason why Visual Studio 2010 would not include such a file. What did I miss?
Note: if I rename the embedded resource file in the solution explorer to something else, then everything works as expected.
Dan from the Microsoft Connect team has finally provided a valid explanation for this behaviour:
Hello, thanks for the report, this is actually working normally. The reason is that any resx files whose names match the pattern .VALIDCULTURE.resx are assumed to be specific to that culture. (This is how it has worked since VS2002, for better or worse)
In your case "no" is a valid culture (Norwegian, I guess) so the build process builds it into a satellite assembly. Here's what I got when I tried this. Note the "no" subfolder. If in your app you change your current culture to Norwegian, the resource load will load this set of resources.
So the problem has nothing to do with the word No itself, but rather with the fact that it is a valid, two-letter, culture name (in my case Norwegian). I checked, and indeed, there was a sub-folder in bin\Debug named No, containing a satellite assembly named Project.resources.dll in it.
Renaming the resource to end with .EN.xxx or .FR.xxx does, of course, exhibit the same behaviour.
As of MSBuild 16.9 you can include files like these by setting the WithCulture property to "false", as pointed out by #reduckted :-)
<EmbeddedResource Include="Resources.en.xml" WithCulture="false" />

Add a link to an existing item during project creation

I've created a custom VS template which uses an IWizard class to do some automatic actions when a user creates a project to set project properties and paths, I've managed to set some project properties like build path by saving the .csproj file with parameters inside $ signs and setting those parameters in the replacementDictionary, during the RunStarted method.
Unfortunately I'm having trouble adding items as links to the .csproj using the same method. I have a .cs file I need to add as an existing and as a link item to each project created, it's path would be determined by where the user chooses to save the project. I've got to the part where I know the path of the .cs file, (absolute and relative to the project's path).
Here's what I've tried so far:
Save the .csproj file with a section for the item, with placeholders for the path:
<Compile Include="$path_to_cs_file\cs_file_name.cs$">
<Link>$cs_file_name.cs$</Link>
</Compile>
I've tried doing this with both absolute and relative paths, but this for some reason makes VS replace the path with a completely different relative path under Documents and Settings\user\Local Settings.
In RunStarted, cast the automationObject as DTE and call it's ItemOperations.AddExistingItem method. Using either path results in errors (The parameter is incorrect).
In ProjectFinishedGenerating, save the project's path, then at RunFinished, create a Microsoft.Build.BuildEngine.Project object with that path, call DTE commands to save all files and unload the project, then call the project object's AddNewItem Method and SetMetaData on the resulting ProjectItem, afterwards I save the project and reload it with the DTE object, this, again results the same errors as before
I'd appreciate any help with the subject, I'm pretty much stumped. Thank you in advance.
I managed to "solve" this issue, what I did is the following:
Kept the placeholder in the csproj, but never added the related parameters to the replacement dictionary:
<Compile Include="$path_to_cs_file$\$cs_file_name.cs$">
<Link>$cs_file_name.cs$</Link>
</Compile>
At the ProjectFinishedGenerated method, unloaded the project, edited the csproj file to replace the paths, and reloaded the project:
projectFileName = project.FullName
// Unload file and manually add the linked item
dte.ExecuteCommand("File.SaveAll");
dte.ExecuteCommand("Project.UnloadProject"); // See Note Below
StreamReader reader = new StreamReader(projectFileName);
string content = reader.ReadToEnd();
reader.Close();
content = Regex.Replace(content, #"\$path_to_cs_file\$", ...);
content = Regex.Replace(content, #"\$cs_file_name\$", ...);
StreamWriter writer = new StreamWriter(projectFileName);
writer.Write(content);
writer.Close();
dte.ExecuteCommand("Project.ReloadProject");
Note: The above code assumes the project needed modifying is currently selected project, usually when ProjectFinishedGenerating runs this is the case, however in a multi-project template or if you've added a project manually to the solution this might not be the case, you'll have to call dte methods to choose your "main" project in the project explorer, then go on with unloading, editing, and reloading. The code to do so would look something like this:
UIHierarchy UIH = dte2.ToolWindows.SolutionExplorer;
UIHierarchyItem UIHItem = UIH.UIHierarchyItems.Item(1);
UIHItem.UIHierarchyItems.Item(testProjectName).Select(vsUISelectionType.vsUISelectionTypeSelect);
An alternative solution if you don't want to mess around with IWizard is to set CreateInPlace to true in your vstemplate in TemplateData.
<CreateInPlace>true</CreateInPlace>
I'm having exactly the same problem and it's driving me mad.
I have found one really dirty workaround however:
In my situation I am using the following in the RunStarted method:
EnvDTE.DTE dte = automationObject as EnvDTE.DTE;
string solutionPath = System.IO.Path.GetDirectory(dte.DTE.Solution.FullName);
This returns a path which includes the folder "documents". Calling System.IO.Directory.Exists() confirms that this is a valid directory, however on checking my file system, it seems that this does not exist. If you replace "documents" with "my documents", and then continue to use that path for the linked item, all works perfectly.
So it seems that VS is getting confused with the "documents" directory alias and therefore defaulting to some crazy "AppData" directory instead.
I hope this helps, but if you find a better way to do this, please let me know!

"Run Custom Tool" for resx files in MVC2 project (from an external application/script)

I am trying to get the localization for my MVC project working with our existing infrastructure for editing string resources. We store all our resource string in database tables and have a front end web UI to edit them with, and an export application which generated the .resx files. This all works great, but I am having a little difficulty with a new project using MVC2 and VS2010.
I have asked another question on this, the answer to which almost got me there, but not quite.
I have now changed the resources to be in a Resources folder (instead of App_GlobalResources), as recommended by a number of people. And have the following settings against my .resx files ...
Build Action = Embedded Resource
Copy to Output Directory = Do not copy
Custom Tool = PublicResXFileCodeGenerator
Custom Tool Namespace = Resources
File Name = MyApp.resx
I have changed my export application to run the resgen.exe tool with the following parameters ...
string args = string.Format("/publicClass \"{0}\" /str:cs,Resources,{1},\"{2}\"", resourceFile, Path.GetFileNameWithoutExtension(resourceFile), csFilename);
... which generates an almost identical .designer.cs file as I get when I add the .resx file to my project initially. The only difference is the
The generated .designer.cs file differs slightly from the file I get when I run the resgen.exe tool from within my export application.
This is the code generated by VS2010 when I first add the .resx file to my Resources folder ...
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Resources.MyApp", typeof(MyApp).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
... the difference when I run the resgen.exe tool is that is prefixs MyCompany.MyApp to the namespace in the constructor to ResourceManager
new global::System.Resources.ResourceManager("MyCompany.MyApp.Resources.MyApp", typeof(MyApp).Assembly);
Now, this to me seems to be a bug in the resgen.exe tool, because I've told it that the Namespace for my resources is Resources, not MyCompany.MyApp.Resources.
So, is there a fix/work-around for this problem?
The only thing I can think to do at the moment is to post-process the generated .designer.cs file with powershell and fix it!
Finally, I have solved the problem.
I decided to simplify things a bit by breaking my resources out in to a new assembly called Resources. I then added my resx files and set the properties for them as below ...
Build Action = Embedded Resource
Copy to Output Directory = Do not copy
Custom Tool = PublicResXFileCodeGenerator
Custom Tool Namespace = Resources
File Name = MyApp.resx
I then changed my export application to run ...
resgen MyApp.resx /str:c#,Resources,MyApp,MyApp.designer.cs /publicClass
... and to delete *.resources from the folder (created by the resgen.exe utility, but not needed)
This got rid of the prefix on the constructor to ResourceManager, and then i just added a reference to my new Resources assembly to my web application.
I've run a few tests to make sure all is good, including going in to the .designer.cs file and deleting one of the properties to cause a compiler error. Then re-ran my export app, and everything worked again.
So, I am a happy bunny!

Resources