I have a testing project Proj_Test with two nuget packages.
<packages>
<package id="NUnit" version="3.6.0" targetFramework="net45" />
<package id="NUnit3TestAdapter" version="3.6.0" targetFramework="net45" />
</packages>
Proj_Test has a reference to the tested project Proj.
Proj has references to several other dlls that need to be loaded.
Where can I add this information so that I can start the tests using the NUnit3TestAdapter from within my IDE without actually copying the dlls to the output folder.
There was a solution for the Nunit2 Runners. But I fail when attempting to use that for Nunit3 via NUnit3TestAdapter.
According to the tips and tricks section i added a settings file Test.runsettings via the menu.
<RunSettings>
<NUnit>
<PrivateBinPath>D:\Drive\AnyThirdParty</PrivateBinPath>
</NUnit>
</RunSettings>
The setting seems to be ignored.
How can I manage these dependencies for my tests?
EDIT:
This is what happened to me I think.
Private assemblies are deployed in the same directory structure as the application. If the directories specified for PrivateBinPath are not under ApplicationBase, they are ignored.
Is creating a copy really the only solution?
If you can't find anything better,try to resolve it yourself
using ConsoleApplication6;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Reflection;
namespace UnitTestProject1
{
[TestClass]
public class UnitTest1
{
[TestInitialize]
public void Init()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += MyResolveEventHandler;
}
[TestMethod]
public void TestMethod1() { Assert.AreEqual(new MyClass().DoSomething(), 1); }
[TestMethod]
public void TestMethod2() { Assert.AreEqual(new MyClass().DoSomething(), 1); }
private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
return Assembly.LoadFile(#"C:\MyPath\MyAssembly.dll");
}
}
}
Unfortunately assembly probing works only on subdirectories so you can't use it...
Thanks to George Vovos answer, this is what I ended up implementing.
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
//https://github.com/nunit/docs/wiki/SetUpFixture-Attribute
//A SetUpFixture outside of any namespace provides SetUp and TearDown for the entire assembly.
[SetUpFixture]
class GlobalSetup
{
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int SetDllDirectory(string NewDirectory);
static HashSet<string> directories = new HashSet<string>
{
#"D:\Drive\AnyThirdParty\"
};
[OneTimeSetUp]
public void RunBeforeAnyTests()
{
AddManagedHandler();
SetNativeDirectories();
}
private void SetNativeDirectories()
{
if(directories.Count() != 1)
{
//TODO: add support for multiple directories
throw new NotImplementedException("current implementation only supports exactly one directory");
}
if (0 == SetDllDirectory(directories.First()))
{
throw new Exception("SetDllDirectory failed with error " + Marshal.GetLastWin32Error());
}
}
private void AddManagedHandler()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
IEnumerable<string> candidates = FindCandidates(new AssemblyName(args.Name));
return Assembly.LoadFrom(candidates.First());
}
private static IEnumerable<string> FindCandidates(AssemblyName assemblyname)
{
List<string> candidates = new List<string>();
foreach (var path in directories)
{
string candidate = string.Format(#"{0}{1}.dll", path, assemblyname.Name);
if (File.Exists(candidate))
{
candidates.Add(candidate);
}
}
if (!candidates.Any())
{
throw new FileNotFoundException(string.Format("Can not find assembly: '{0}.dll'", assemblyname.Name));
}
return candidates;
}
}
Related
As the title describes I am having trouble getting CPU temps using the openhardwaremonitor.dll reference. I think I am running the program as an admin, I select run as admin when starting visual studio because I do not have the option to add an application.manifest file. This is the code I am using;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenHardwareMonitor.Hardware;
namespace Get_CPU_Temp5
{
class Program
{
public class UpdateVisitor : IVisitor
{
public void VisitComputer(IComputer computer)
{
computer.Traverse(this);
}
public void VisitHardware(IHardware hardware)
{
hardware.Update();
foreach (IHardware subHardware in hardware.SubHardware) subHardware.Accept(this);
}
public void VisitSensor(ISensor sensor) { }
public void VisitParameter(IParameter parameter) { }
}
static void GetSystemInfo()
{
UpdateVisitor updateVisitor = new UpdateVisitor();
Computer computer = new Computer();
computer.Open();
computer.CPUEnabled = true;
computer.Accept(updateVisitor);
for (int i = 0; i < computer.Hardware.Length; i++)
{
if (computer.Hardware[i].HardwareType == HardwareType.CPU)
{
for (int j = 0; j < computer.Hardware[i].Sensors.Length; j++)
{
if (computer.Hardware[i].Sensors[j].SensorType == SensorType.Temperature)
Console.WriteLine(computer.Hardware[i].Sensors[j].Name + ":" + computer.Hardware[i].Sensors[j].Value.ToString() + "\r");
}
}
}
computer.Close();
}
static void Main(string[] args)
{
while (true)
{
GetSystemInfo();
}
}
}
}
Error;
"System.IO.FileNotFoundException: 'Could not load file or assembly 'System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.'"
This error is at computer.Open();
I am using visual studio 2019.
Any help will be greatly appreciated!
I just ran into this issue with trying to use openhardwaremonitor.dll with .Net core. The fix I found was to load system.management from Nuget. Apparently the system.management assemblies are not included in .net core like they are with .net Framework.
Selenium C#: Getting error "Make sure test project has a nuget reference of package "Microsoft.NET.Test.Sdk" and framework version settings are appropriate. Rerun with /diag option to diagnose further."
Project Structure: Console App (.Net Core 2.0)
Here is my main code:
using NUnit.Framework;
using OpenQA.Selenium;
using System.Threading;
namespace Portal
{
class Program
{
private IWebDriver driver;
public Program()
{
driver = BaseDriver.GetDriver();
}
private static void Main(string[] args)
{
}
[SetUp]
public void Initialize()
{
driver.Navigate().GoToUrl("https://Portal.com");
}
[Test]
public void ExecuteTests()
{
driver.FindElement(By.Id("UserName")).SendKeys("Admin");
driver.FindElement(By.Id("Password")).SendKeys("Admin");
driver.FindElement(By.XPath(
"html/body/div[3]/div/div/form/div/div[4]/button/span")).Click();
}
}
}
Here is my Driver Class Definition:
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace portal
{
class BaseDriver
{
private static IWebDriver driver;
public static IWebDriver GetDriver()
{
if (driver == null)
{
driver = new ChromeDriver(#"C:\SeleniumC#\portal\portal");
driver.Manage().Window.Maximize();
}
return driver;
}
}
}
I've implemented a very small plugin system based on C# with MEF. The problem is, none of my plugins are instanced. In the Aggregate-Catalog I can see my plugin listed. But, after I'll compose these parts, there isn't my plugin in the plugin list, what I'm doing wrong?
Here's a snippet of my code:
Plugin-Loader:
[ImportMany(typeof(IFetchService))]
private IFetchService[] _pluginList;
private AggregateCatalog _pluginCatalog;
private const string pluginPathKey = "PluginPath";
...
public PluginManager(ApplicationContext context)
{
var dirCatalog = new DirectoryCatalog(ConfigurationManager.AppSettings[pluginPathKey]);
//Here's my plugin listed...
_pluginCatalog = new AggregateCatalog(dirCatalog);
var compositionContainer = new CompositionContainer(_pluginCatalog);
compositionContainer.ComposeParts(this);
}
...
And here, the plugin itself:
[Export(typeof(IFetchService))]
public class MySamplePlugin : IFetchService
{
public MySamplePlugin()
{
Console.WriteLine("Plugin entered");
}
...
}
Tested working sample.
Compile class library with code inside PluginNameSpace namespace and place it to the 'Test' folder which will be inside console app exe folder.
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Reflection;
using ConsoleApplication;
namespace ConsoleApplication
{
public interface IFetchService
{
void Write();
}
class PluginManager
{
[ImportMany(typeof(IFetchService))]
public IFetchService[] PluginList;
public PluginManager()
{
var dirCatalog = new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\Test");
var pluginCatalog = new AggregateCatalog(dirCatalog);
var compositionContainer = new CompositionContainer(pluginCatalog);
compositionContainer.ComposeParts(this);
}
}
class Program
{
static void Main(string[] args)
{
var pluginManager = new PluginManager();
foreach (var fetchService in pluginManager.PluginList)
{
fetchService.Write();
}
Console.ReadKey();
}
}
}
// Separate class library
namespace PluginNameSpace
{
[Export(typeof(IFetchService))]
public class MySamplePlugin : IFetchService
{
public void Write()
{
Console.WriteLine("Plugin entered");
}
}
}
I have C# solution with 2 project:
DLLTest (Console app)
BLib (library)
In DLLTest I set reference to BLib and set Copy Local property to false.
Compile solution.
Copy BLib.dll to 'C:\BLib.dll' and run application.
In first step in my code I load Assembly from path 'C:\BLib.dll' then invoke method from there. On invoking method from BLib assembly fire AssemblyResolver and try load assembly which I loaded before manually.
Can I do something that application to know that the library has already been loaded and not try load it again?
This is BClass.cs file from BLib project:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BLib
{
public class BClass
{
public static void PrintName()
{
Console.WriteLine("BLib");
}
}
}
This is Program.cs file from DLLTest project:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace DLLTest
{
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
Assembly.LoadFile(#"C:\BLib.dll");
Console.WriteLine("Loaded assembles:");
AppDomain.CurrentDomain.GetAssemblies().ToList()
.ForEach(p => Console.WriteLine(p));
Console.WriteLine("End list of assembles");
try
{
PrintMessage();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
private static void PrintMessage()
{
BLib.BClass.PrintName();
}
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
Console.WriteLine(args.Name);
return null;
}
}
}
I find similar question Why is AssemblyResolve called when Assembly is in CurrentDomain? Answer from there follow me to Choosing a Binding Context where everything was detailed described (row Neither column Disadvantages).
That I think so, this is security reason.
I have the VS2005 standard edition and MS says this:
Note: The Windows Service Application
project templates and associated
functionality are not available in the
Standard Edition of Visual Basic and
Visual C# .NET...
Is it possible to write a Windows Service application without upgrading my VS2005 Standard edition?
If you can cut and paste, an example is enough.
A simple service to periodically log the status of another service. The example does not include the ServiceInstaller class (to be called by the install utility when installing a service application), so installing is done manually.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Timers;
namespace SrvControl
{
public partial class Service1 : ServiceBase
{
Timer mytimer;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
if (mytimer == null)
mytimer = new Timer(5 * 1000.0);
mytimer.Elapsed += new ElapsedEventHandler(mytimer_Elapsed);
mytimer.Start();
}
void mytimer_Elapsed(object sender, ElapsedEventArgs e)
{
var srv = new ServiceController("MYSERVICE");
AppLog.Log(string.Format("MYSERVICE Status {0}", srv.Status));
}
protected override void OnStop()
{
mytimer.Stop();
}
}
public static class AppLog
{
public static string z = "SrvControl";
static EventLog Logger = null;
public static void Log(string message)
{
if (Logger == null)
{
if (!(EventLog.SourceExists(z)))
EventLog.CreateEventSource(z, "Application");
Logger = new EventLog("Application");
Logger.Source = z;
}
Logger.WriteEntry(message, EventLogEntryType.Information);
}
}
}
Yes, look here:
http://www.codeproject.com/KB/system/WindowsService.aspx
Sure, you just need to write the code yourself. It's not actually very hard. Here are a couple of references to how to do it:
http://msdn.microsoft.com/en-us/magazine/cc301845.aspx
http://www.aspfree.com/c/a/C-Sharp/Creating-a-Windows-Service-with-C-Sharp-introduction/