How to publish wmi classes in .net? - c#

I've created a seperate assembly with a class that is intended to be
published through wmi. Then I've created a windows forms app that
references that assembly and attempts to publish the class. When I try to
publish the class, I get an exception of type
System.Management.Instrumentation.WmiProviderInstallationException. The
message of the exception says "Exception of type
'System.Management.Instrumentation.WMIInfraException' was thrown.". I have
no idea what this means. I've tried .Net2.0 and .Net3.5 (sp1 too) and get the same results.
Below is my wmi class, followed by the code I used to publish it.
//Interface.cs in assembly WMI.Interface.dll
using System;
using System.Collections.Generic;
using System.Text;
[assembly: System.Management.Instrumentation.WmiConfiguration(#"root\Test",
HostingModel =
System.Management.Instrumentation.ManagementHostingModel.Decoupled)]
namespace WMI
{
[System.ComponentModel.RunInstaller(true)]
public class MyApplicationManagementInstaller :
System.Management.Instrumentation.DefaultManagementInstaller { }
[System.Management.Instrumentation.ManagementEntity(Singleton = true)]
[System.Management.Instrumentation.ManagementQualifier("Description",
Value = "Obtain processor information.")]
public class Interface
{
[System.Management.Instrumentation.ManagementBind]
public Interface()
{
}
[System.Management.Instrumentation.ManagementProbe]
[System.Management.Instrumentation.ManagementQualifier("Descriiption",
Value="The number of processors.")]
public int ProcessorCount
{
get { return Environment.ProcessorCount; }
}
}
}
//Button click in windows forms application to publish class
try
{
System.Management.Instrumentation.InstrumentationManager.Publish(new
WMI.Interface());
}
catch (System.Management.Instrumentation.InstrumentationException
exInstrumentation)
{
MessageBox.Show(exInstrumentation.ToString());
}
catch (System.Management.Instrumentation.WmiProviderInstallationException
exProvider)
{
MessageBox.Show(exProvider.ToString());
}
catch (Exception exPublish)
{
MessageBox.Show(exPublish.ToString());
}

To summarize, this is the final code that works:
Provider class, in it's own assembly:
// the namespace used for publishing the WMI classes and object instances
[assembly: Instrumented("root/mytest")]
using System;
using System.Collections.Generic;
using System.Text;
using System.Management;
using System.Management.Instrumentation;
using System.Configuration.Install;
using System.ComponentModel;
namespace WMITest
{
[InstrumentationClass(System.Management.Instrumentation.InstrumentationType.Instance)]
//[ManagementEntity()]
//[ManagementQualifier("Description",Value = "Obtain processor information.")]
public class MyWMIInterface
{
//[System.Management.Instrumentation.ManagementBind]
public MyWMIInterface()
{
}
//[ManagementProbe]
//[ManagementQualifier("Descriiption", Value="The number of processors.")]
public int ProcessorCount
{
get { return Environment.ProcessorCount; }
}
}
/// <summary>
/// This class provides static methods to publish messages to WMI
/// </summary>
public static class InstrumentationProvider
{
/// <summary>
/// publishes a message to the WMI repository
/// </summary>
/// <param name="MessageText">the message text</param>
/// <param name="Type">the message type</param>
public static MyWMIInterface Publish()
{
// create a new message
MyWMIInterface pInterface = new MyWMIInterface();
Instrumentation.Publish(pInterface);
return pInterface;
}
/// <summary>
/// revoke a previously published message from the WMI repository
/// </summary>
/// <param name="Message">the message to revoke</param>
public static void Revoke(MyWMIInterface pInterface)
{
Instrumentation.Revoke(pInterface);
}
}
/// <summary>
/// Installer class which will publish the InfoMessage to the WMI schema
/// (the assembly attribute Instrumented defines the namespace this
/// class gets published too
/// </summary>
[RunInstaller(true)]
public class WMITestManagementInstaller :
DefaultManagementProjectInstaller
{
}
}
Windows forms application main form, publishes provider class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Management;
using System.Management.Instrumentation;
namespace WMI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
WMITest.MyWMIInterface pIntf_m;
private void btnPublish_Click(object sender, EventArgs e)
{
try
{
pIntf_m = WMITest.InstrumentationProvider.Publish();
}
catch (ManagementException exManagement)
{
MessageBox.Show(exManagement.ToString());
}
catch (Exception exPublish)
{
MessageBox.Show(exPublish.ToString());
}
}
}
}
Test web application, consumer:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Management.Instrumentation;
using System.Management;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ManagementClass pWMIClass = null;
pWMIClass = new ManagementClass(#"root\interiorhealth:MyWMIInterface");
lblOutput.Text = "ClassName: " + pWMIClass.ClassPath.ClassName + "<BR/>" +
"IsClass: " + pWMIClass.ClassPath.IsClass + "<BR/>" +
"IsInstance: " + pWMIClass.ClassPath.IsInstance + "<BR/>" +
"IsSingleton: " + pWMIClass.ClassPath.IsSingleton + "<BR/>" +
"Namespace Path: " + pWMIClass.ClassPath.NamespacePath + "<BR/>" +
"Path: " + pWMIClass.ClassPath.Path + "<BR/>" +
"Relative Path: " + pWMIClass.ClassPath.RelativePath + "<BR/>" +
"Server: " + pWMIClass.ClassPath.Server + "<BR/>";
//GridView control
this.gvProperties.DataSource = pWMIClass.Properties;
this.gvProperties.DataBind();
//GridView control
this.gvSystemProperties.DataSource = pWMIClass.SystemProperties;
this.gvSystemProperties.DataBind();
//GridView control
this.gvDerivation.DataSource = pWMIClass.Derivation;
this.gvDerivation.DataBind();
//GridView control
this.gvMethods.DataSource = pWMIClass.Methods;
this.gvMethods.DataBind();
//GridView control
this.gvQualifiers.DataSource = pWMIClass.Qualifiers;
this.gvQualifiers.DataBind();
}
}
}

I used gacutil - installutil to to test your class (as a dll). The gacutil part worked, but installutil (actually mofcomp) complained about a syntax error:
...
error SYNTAX 0X80044014:
Unexpected character in class name (must be an identifier)
Compiler returned error 0x80044014
...
So I changed the class name to 'MyInterface' the installutil part worked, but the class didn't return any instances. Finally I changed the hosting model to Network Service and got it to work.

Related

How to get Crystal Reports to bind to data provided in a List<T> for some T?

I want to print data from stored procedure in SQL Server with Crystal Report. I used Dapper to connect to SQL Server and fetch the data, but I don't know how to display that data in WPF Viewer and print it as PDF.
Here is the code that I wrote to load data using Dapper:
using System;
using System.Collections.Generic;
using System.Data;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Interop;
using MvvmCross.ViewModels;
using Ophtalmology.BusinessLogic.ViewModel.CorrectiveLensesLogic;
using Ophtalmology.View.Reports.PrintingUI;
using Ophtalmology.View.Reports.CorrectiveLensRepports;
using Dapper;
using Microsoft.Data.SqlClient;
using Ophtalmology.BusinessLogic.Helpers;
using Database = Ophtalmology.View.Reports.ConnectionClass.Database;
namespace Ophtalmology.View.CorrectiveLenses
{
/// <summary>
/// Interaction logic for CorrectiveLenses.xaml
/// </summary>
public partial class CorrectiveLenses
{
public CorrectiveLenses()
{
InitializeComponent();
}
private List tblRpt;
private static string ReadCliniqueQuery =>
#"SELECT [Clinique].Id
,Patient.Bar_code
,[Clinique].[FIrst_Name]
,[Clinique].[Last_Name]
,[Age]
,[p1_G]
,[Axe_G]
,[p2_G]
,[VPPPD]
,[VPPPD1_ADITION]
,[p1_D]
,[Axe_D]
,[p2_D]
,[VPPPPG]
,[VPPPG1_ADDITION]
,[DIP]
FROM [dbo].[Clinique],Patient where Patient.Last_Name = Clinique.Last_Name and Patient.First_Name = [Clinique].[FIrst_Name]
Order By [Date_consultation];";
public IEnumerable<Domain.Clinique> GetCliniques()
{
using (IDbConnection context = new SqlConnection(Connection.ConnectionString))
{
return context.Query<Domain.Clinique>(ReadCliniqueQuery).AsList();
}
}
private void PrintButton(object sender, RoutedEventArgs e)
{
Print();
}
private void Print()
{
tblRpt = (List)GetCliniques();
PrintingUI frm = new PrintingUI();
CorrectiveLensfarRepport rpt = new CorrectiveLensfarRepport();
rpt.SetDatabaseLogon("", "", #".\SERVEUR", "Ophtalmology");
rpt.SetDataSource(tblRpt);
frm.ShowDialog();
}
}
}
This is my WPF Viewer
I will be glad for any kid of help ^_^
Thank you

How to use the Debug API in Visual Studio Extension?

I have seen a lot about the related issues, but still feel very puzzled
I now mainly encountered the problem is unable to obtain the current state of the debugging process, such as when to encounter breakpoints.
I have seen a lot of problems that can be used IDebugEventCallback2 to solve the problem, but I was a novice, no specific examples difficult to understand
I have never written this related code, MSDN can be found on the information is also very few examples, if there are some information or examples I would be very grateful....QAQ
English is not my mother tongue, there may be some grammatical mistakes and i feel Sorry for it.
this answer is base on the Visual Studio Package template in C#
File structure is as follows, different project name settings may be different but similar, I have made changes to the selected two documents (MyControl.xaml, VSPackageHW2Package.cs)
FileStruct
1.Define the variable
public static VSPackageHW2Package package;
readonly IVsDebugger _debugger;
readonly DTE _dte;
readonly Debugger2 _dteDebugger;
readonly uint _debuggerEventsCookie;
2.pass value from VSPackageHW2Package.cs to MyControl.xaml(the only place to change VSPackageHW2Package.cs)
public VSPackageHW2Package()
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
MyControl.package = this;
}
3.Implement interface in MyControl.xaml
IVsDebuggerEvents
4.in Constructor
public MyControl()
{
InitializeComponent();
var packageServiceProvider = (IServiceProvider)package;
_debugger = packageServiceProvider.GetService(typeof(SVsShellDebugger)) as IVsDebugger;
_dte = packageServiceProvider.GetService(typeof(SDTE)) as DTE;
if (_debugger.AdviseDebuggerEvents(this, out _debuggerEventsCookie) != VSConstants.S_OK)
{
MessageBox.Show("DebugManager setup failed");
}
else
{
MessageBox.Show("ok");
}
}
Complete MyControl.xaml file:
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Company.VSPackageHW2
{
/// <summary>
/// Interaction logic for MyControl.xaml
/// </summary>
public partial class MyControl : UserControl,IVsDebuggerEvents
{
public static VSPackageHW2Package package;
readonly IVsDebugger _debugger;
readonly DTE _dte;
readonly Debugger2 _dteDebugger;
readonly uint _debuggerEventsCookie;
public MyControl()
{
InitializeComponent();
var packageServiceProvider = (IServiceProvider)package;
_debugger = packageServiceProvider.GetService(typeof(SVsShellDebugger)) as IVsDebugger;
_dte = packageServiceProvider.GetService(typeof(SDTE)) as DTE;
if (_debugger.AdviseDebuggerEvents(this, out _debuggerEventsCookie) != VSConstants.S_OK)
{
MessageBox.Show("DebugManager setup failed");
}
else
{
MessageBox.Show("ok");
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions")]
private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(string.Format(System.Globalization.CultureInfo.CurrentUICulture, "We are inside {0}.button1_Click()", this.ToString()),
"lzyToolWindow");
}
public int OnModeChange(DBGMODE dbgmodeNew)
{
MessageBox.Show("debug mode change");
throw new NotImplementedException();
}
}
}

Registery install programs containing space

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Win32;
namespace Demo
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
GetInstallApps();
}
public void GetInstallApps()
{
string uninstallkey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryKey rk;
using (rk = Registry.LocalMachine.OpenSubKey(uninstallkey))
{
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
try
{
lsitBox1.Items.Add(sk.GetValue("DisplayName") + " " + sk.GetValue("DisplayVersion"));
}
catch (Exception ex)
{ }
}
}
// txtblock1.Text = lsitBox1.Items.Count.ToString();
}
}
}
}
Application give information about All install software in my windows but it containing space, i want to delete that space , And i know it will register with registery key, Because of that it will containing space if i want to remove that particular registry what can i do any idea Thank you
before try catch block add one line
if (sk.GetValue("") != null)

Matching MEF imports to exports

In the code below I am attempting to use MEF to match an import to a matching export. The TestMEFClass has an import and an export which share a matching contract name. The export should increment a counter every time it's called.
When I printed the export to the console, it did not increment the counter. Could someone point out my mistake?
Thank you very much,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
namespace MEFConsoleTest {
public class TestMEFClass {
/// <summary>
/// This counter should increment everytime the getter in the ExportString property gets called.
/// </summary>
private int counter = 0;
[Export("Contract_Name")]
public string ExportString {
get {
return "ExportString has been called " + counter++.ToString();
}
}
[Import("Contract_Name")]
public string ImportString { get; set; }
/// <summary>
/// Default Constructor.
/// Make a catalog from this assembly, add it to the container and compose the parts.
/// </summary>
public TestMEFClass() {
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
class Program {
static void Main(string[] args) {
TestMEFClass testClass = new TestMEFClass();
Console.WriteLine(testClass.ImportString);
Console.WriteLine(testClass.ImportString);
Console.ReadLine();
}
}
For reasons I cannot explain at this moment I wasn't able to get MEF and properties imports/exports to work on a mutable property. However, using functions did the trick. I hope this code helps someone else.
Thanks,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
namespace MEFConsoleTest {
public class TestMEFClass {
/// <summary>
/// This counter should increment everytime the getter in the ExportString property gets called.
/// </summary>
private int counter = 0;
[Export("Contract_Name")]
string ExportMethod() {
return ExportString;
}
public string ExportString {
get {
return "ExportString has been called " + counter++.ToString();
}
}
[Import("Contract_Name")]
Func<string> ImportMethod;
public string ImportString { get { return ImportMethod(); } }
/// <summary>
/// Default Constructor.
/// Make a catalog from this assembly, add it to the container and compose the parts.
/// </summary>
public TestMEFClass() {
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
class Program {
static void Main(string[] args) {
TestMEFClass testClass = new TestMEFClass();
for (int x = 0; x < 10; x++) {
Console.WriteLine(testClass.ImportString);
}
Console.ReadLine();
}
}
}

Unit testing in visual studio 2010 without a main method

Trying to unit test some simple code for a class project, however every time I try to run the test I get an error that there is no home.exe and no main static main method. However, we haven't gotten to the point where we are supposed to have either of those things yet, so how can I run the test without them?
My code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Home
{
class InventoryType
{
/// <summary>
/// Selects the inventory type and returns the selected value
/// </summary>
public class InventorySelect
{
private string inventoryTypes;
public String InventoryTypes
{
set
{
inventoryTypes = value;
}
get
{
return inventoryTypes;
}
}
/// <summary>
/// Validate that the inventory is returning some sort of value
/// </summary>
/// <returns></returns>
public bool Validate()
{
if (InventoryTypes == null) return false;
return true;
}
}
}
}
My Test Code
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Home.InventoryType.InventorySelect;
namespace HomeTest
{
[TestClass]
public class TestInventoryTypeCase
{
[TestMethod]
public void TestInventoryTypeClass()
{
InventorySelect select = new InventorySelect();
select.inventoryTypes = "Collection";
if (Validate() = true)
Console.WriteLine("Test Passed");
else
if (Validate() = false)
Console.WriteLine("Test Returned False");
else
Console.WriteLine("Test Failed To Run");
Console.ReadLine();
}
}
}
OK, a couple things here.
Make sure that your Output type for your main project (the project to be tested) is ClassLibrary
Use Assertions in your tests
I created a ClassLibrary solution called ExampleLibrary. Created a class called InventoryType and copied in your code e.g.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ExampleLibrary
{
class InventoryType
{
/// <summary>
/// Selects the inventory type and returns the selected value
/// </summary>
public class InventorySelect
{
private string inventoryTypes;
public String InventoryTypes
{
set
{
inventoryTypes = value;
}
get
{
return inventoryTypes;
}
}
/// <summary>
/// Validate that the inventory is returning some sort of value
/// </summary>
/// <returns></returns>
public bool Validate()
{
if (InventoryTypes == null) return false;
return true;
}
}
}
}
I then created a Unit Test and coded it as follows:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ExampleLibrary;
namespace HomeTest
{
[TestClass]
public class TestInventoryTypeCase
{
[TestMethod]
public void TestInventoryTypeClass()
{
InventoryType.InventorySelect select = new InventoryType.InventorySelect();
select.InventoryTypes = "Collection";
Assert.IsTrue(select.Validate());
select.InventoryTypes = null;
Assert.IsFalse(select.Validate());
}
}
}
I compile and run the test as described above and it runs and returns Test Passed.
To run a test on the main menu bar at the top of your Visual Studio...
Test - Windows - Test Explorer
In the Test Explorer window, select the test you wish to run and click on the run Icon at the top of the window.

Categories