Programmatically list WMI classes and their properties - vbscript

Is there any known way of listing the WMI classes and their properties available for a particular system? Im interested in a vbscript approach, but please suggest anything really :)
P.S. Great site.

I believe this is what you want.
WMI Code Creator
A part of this nifty utility allows you to browse namespaces/classes/properties on the local and remote PCs, not to mention generating WMI code in VBScript/C#/VB on the fly. Very useful.
Also, the source code used to create the utility is included in the download, which could provide a reference if you wanted to create your own browser like interface.

This MSDN page walks through enumerating the available classes: How to: List the Classes in a WMI Namespace
for retrieving properties from a class:
ManagementPath l_Path = new ManagementPath(l_className);
ManagementClass l_Class = new ManagementClass(myScope, l_ManagementPath, null);
foreach (PropertyData l_PropertyData in l_Class.Properties)
{
string l_type = l_PropertyData.Type.ToString());
int l_length = Convert.ToInt32(l_PropertyData.Qualifiers["maxlen"].Value);
}

Related

How to set cluster resource "Use Network Name for computer name" checkbox programmatically?

I am programmatically setting up a cluster resource (specifically, a Generic Service), using the Windows MI API (Microsoft.Management.Infrastructure).
I can add the service resource just fine. However, my service requires the "Use Network Name for computer name" checkbox to be checked (this is available in the Cluster Manager UI by looking at the Properties for the resource).
I can't figure out how to set this using the MI API. I have searched MSDN and multiple other resources for this without luck. Does anybody know if this is possible? Scripting with Powershell would be fine as well.
I was able to figure this out, after a lot of trial and error, and the discovery of an API bug along the way.
It turns out cluster resource objects have a property called PrivateProperties, which is basically a property bag. Inside, there's a property called UseNetworkName, which corresponds to the checkbox in the UI (and also, the ServiceName property, which is also required for things to work).
The 'wbemtest' tool was invaluable in finding this out. Once you open the resource instance in it, you have to double-click the PrivateProperties property to bring up a dialog which has a "View Embedded" button, which is then what shows you the properties inside. Somehow I had missed this before.
Now, setting this property was yet another pain. Due to what looks like a bug in the API, retrieving the resource instance with CimSession.GetInstance() does not populate property values. This misled me into thinking I had to add the PrivateProperties property and its inner properties myself, which only resulted in lots of cryptic errors.
I finally stumbled upon this old MSDN post about it, where I realized the property is dynamic and automatically set by WMI. So, in the end, all you have to do is know how to get the property bag using CimSession.QueryInstances(), so you can then set the inner properties like any other property.
This is what the whole thing looks like (I ommitted the code for adding the resource):
using (var session = CimSession.Create("YOUR_CLUSTER", new DComSessionOptions()))
{
// This query finds the newly created resource and fills in the
// private props we'll change. We have to do a manual WQL query
// because CimSession.GetInstance doesn't populate prop values.
var query =
"SELECT PrivateProperties FROM MSCluster_Resource WHERE Id=\"{YOUR-RES-GUID}\"";
// Lookup the resource. For some reason QueryInstances does not like
// the namespace in the regular form - it must be exactly like this
// for the call to work!
var res = session.QueryInstances(#"root/mscluster", "WQL", query).First();
// Add net name dependency so setting UseNetworkName works.
session.InvokeMethod(
res,
"AddDependency",
new CimMethodParametersCollection
{
CimMethodParameter.Create(
"Resource", "YOUR_NET_NAME_HERE", CimFlags.Parameter)
});
// Get private prop bag and set our props.
var privProps =
(CimInstance)res.CimInstanceProperties["PrivateProperties"].Value;
privProps.CimInstanceProperties["ServiceName"].Value = "YOUR_SVC_HERE";
privProps.CimInstanceProperties["UseNetworkName"].Value = 1;
// Persist the changes.
session.ModifyInstance(#"\root\mscluster", res);
}
Note how the quirks in the API make things more complicated than they should be: QueryInstances expects the namespace in a special way, and also, if you don't add the network name dependency first, setting private properties fails silently.
Finally, I also figured out how to set this through PowerShell. You have to use the Set-ClusterParameter command, see this other answer for the full info.

What are the capabilities of .NET in AutoCad

Can anyone describe what you can create in C # in Autocad?
I would like to improve the work in the design office, but I do not know what my options are.
Can I create new objects?
Overlays forming an aomomatically drawing based on the given data
other
On the net I found only two blogs with posts from a few years earlier. There is nothing new.
Can anyone recommend any interesting articles, guides?
Any help will be helpful to get started. I know there is documentation but I will need some explanation step by step how everything works.
What you mentioned is possible. The API basics are the same since version 2007 (with incremental updated since and a couple binary breaks, but the code remains similar). For a new development, use the oldest version you plan to support (the last binary break release was 2013)
Visit the AutoCAD DevCenter and check:
Wizard for Visual Studio
Developer Guide
Training material
Webinars (Sessions 1-8)
You can definitely create new objects with the AutoCAD .Net API, below is an example I wrote a while ago, that creates a MLeader.
The .Net API is a managed wrapper around the C++ ObjectARX API, so it covers most of what the C++ API is capable of. The one thing that it cannot do is to derive custom classes from native ones, for Example AcDbLine cannot be extended through .Net. To achieve that you need to use the C++ API and can write a custom .Net wrapper in C++/CLI to expose it to .Net, then you will be able to instantiate your custom classes from .Net similarly to the built-in ones.
Modifying the behaviour of built-in entities can however be achieved directly in .Net by using overrules.
If your plugin is supposed to work only on Windows, then .Net is a more convenient choice than C++ and more flexible to implement UI's.
[CommandMethod("netTextMLeader")]
public static void netTextMLeader() {
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
using (Transaction Tx = db.TransactionManager.StartTransaction()) {
BlockTable table = Tx.GetObject(
db.BlockTableId,
OpenMode.ForRead) as BlockTable;
BlockTableRecord model = Tx.GetObject(
table[BlockTableRecord.ModelSpace],
OpenMode.ForWrite) as BlockTableRecord;
MLeader leader = new MLeader();
leader.SetDatabaseDefaults();
leader.ContentType = ContentType.MTextContent;
MText mText = new MText();
mText.SetDatabaseDefaults();
mText.Width = 100;
mText.Height = 50;
mText.SetContentsRtf("MLeader");
mText.Location = new Point3d(4, 2, 0);
leader.MText = mText;
int idx = leader.AddLeaderLine(new Point3d(1, 1, 0));
leader.AddFirstVertex(idx, new Point3d(0, 0, 0));
model.AppendEntity(leader);
Tx.AddNewlyCreatedDBObject(leader, true);
Tx.Commit();
}
}
With .Net can you create a new Object?
The answer is No. You need to use ObjectArx for that. However, with .Net you can modify how an object looks like. For example you can modify a line to look like an arrow. Not only how it looks but also how it behaves. So there is enough flexibility in .Net that is enough to compensate for the need to create new objects. Basically with .Net you have the power of windows and autocad.
A good resource of .Net samples is through the interface by Kean Walmsley. Try to go through this blog and you will learn more about .Net capabilities in AutoCAD than what I would ever be able to describe.

retrieving data from arbitrary memory addresses using VSIX

I am working on developing a debugger plugin for visual studio using VSIX. My problem is I have an array of addresses but I cannot set the IDebugMemoryBytes2 to a particular address. I use DEBUG_PROPERTY_INFO and get the array of addresses, and I also am able to set the context to the particular addresses in the array using the Add function in IDebugMemoryContext2. However, I need to use the ReadAt function to retrieve n bytes from a specified address (from IDebugMemoryBytes2).
Does anyone have any idea how to retrieve data from arbitrary addresses from memory?
I am adding more information on the same:
I am using the Microsoft Visual Studio Extensibility package to build my debugger plugin. In the application I am trying to debug using this plugin, there is a double pointer and I need to read those values to process them further in my plugin. For this, there is no way to display all the pointer variables in the watch window and hence, I am not able to get the DEBUG_PROPERTY_INFO for all the block of arrays which the pointer variable is pointing to. This is my problem which I am trying to address. There is no way for me to read the memory pointed to by this double pointer.
Now as for the events in the debuggee process, since the plugin is for debugging variables, I put a breakpoint at a place where I know this pointer is populated and then come back to the plugin for further evaluation.
As a start, I was somehow able to get the starting addresses of each of the array. But still, I am not able to read x bytes of memory from each of these starting addresses.
ie., for example, if I have int **ptr = // pointing to something
I have the addresses present in ptr[0], ptr[1], ptr[2], etc. But I need to go to each of these addresses and fetch the memory block they are pointing to.
For this, after much search, I found this link: https://macropolygon.wordpress.com/2012/12/16/evaluating-debugged-process-memory-in-a-visual-studio-extension/ which seems to address exactly my issue.
So to use expression evaluator functions, I need an IDebugStackFrame2 object to get the ExpressionContext. To get this object, I need to register to events in the debuggee process which is for breakpoint. As said in the post, I did:
public int Event(IDebugEngine2 engine, IDebugProcess2 process,
IDebugProgram2 program, IDebugThread2 thread, IDebugEvent2
debugEvent, ref Guid riidEvent, uint attributes)
{
if (debugEvent is IDebugBreakpointEvent2)
{
this.thread = thread;
}
return VSConstants.S_OK;
}
And my registration is like:
private void GetCurrentThread()
{
uint cookie;
DBGMODE[] modeArray = new DBGMODE[1];
// Get the Debugger service.
debugService = Package.GetGlobalService(typeof(SVsShellDebugger)) as
IVsDebugger;
if (debugService != null)
{
// Register for debug events.
// Assumes the current class implements IDebugEventCallback2.
debugService.AdviseDebuggerEvents(this, out cookie);
debugService.AdviseDebugEventCallback(this);
debugService.GetMode(modeArray);
modeArray[0] = modeArray[0] & ~DBGMODE.DBGMODE_EncMask;
if (modeArray[0] == DBGMODE.DBGMODE_Break)
{
GetCurrentStackFrame();
}
}
}
But this doesn't seem to invoke the Event function at all and hence, I am not sure how to get the IDebugThread2 object.
I also tried the other way suggested in the same post:
namespace Microsoft.VisualStudio.Debugger.Interop.Internal
{
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("1DA40549-8CCC-48CF-B99B-FC22FE3AFEDF")]
public interface IDebuggerInternal11 {
[DispId(0x6001001f)]
IDebugThread2 CurrentThread { [return:
MarshalAs(UnmanagedType.Interface)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime)]
get; [param: In, MarshalAs(UnmanagedType.Interface)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime)] set; }
}
}
private void GetCurrentThread()
{
debugService = Package.GetGlobalService(typeof(SVsShellDebugger)) as IVsDebugger;
if (debugService != null)
{
IDebuggerInternal11 debuggerServiceInternal =
(IDebuggerInternal11)debugService;
thread = debuggerServiceInternal.CurrentThread;
GetCurrentStackFrame();
}
}
But in this method, I think I am missing something but I am not sure what, because after the execution of the line
IDebuggerInternal11 debuggerServiceInternal =
(IDebuggerInternal11)debugService;
when I check the values of the debuggerServiceInternal variable, I see there is a System.Security.SecurityException for CurrentThread, CurrentStackFrame (and so obviously the next line causes a crash). For this, I googled the error and found I was missing the ComImport attribute to the class. So I added that and now, I get a System.AccessViolationException : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
I am new to C# programming as well and hence, it is a bit difficult to grasp many things in short duration. I am lost as to how to proceed further now.
Any help in the same or suggestions to try another way to achieve my objective will be greatly appreciated.
Thanks a lot,
Esash
After much search, since I am short of time, I need a quick solution and hence, for now, it seems like the quickest way to solve this problem is to hack the .natvis files by making it display all the elements of the pointer and then using the same old way by using IDebug* interface methods to access and retrieve the memory context for each of the pointer elements. But, after posting the same question in msdn forums, I think the proper answer to this problem is as mentioned by Greggs:
"For reading memory, if you want a fast way to do this, you just want the raw memory, and the debug engine of the target is the normal Visual Studio native engine (in other words, you aren't creating your own debug engine), I would recommend referencing Microsoft.VisualStudio.Debugger.Engine. You can then use DkmStackFrame.ExtractFromDTEObject to get the DkmStackFrame object. This will give you the DkmProcess object and you can call DkmProcess.ReadMemory to read memory from the target."
Now, after trying a lot to understand how to implement this, I found that you could just accomplish this using :
DkmProcess.GetProcesses() and doing a ReadMemory on the process returned.
There is a question now, what if more than one processes are returned. Well, I tried attaching many processes to the current debugging process and tried attaching many processes to the debuggee process as well, but found that the DkmProcess.GetProcesses() gets only the one from which I regained the control from, and not the other processes I am attached to. I am not sure if this will work in all cases but for me, it worked this way and for anyone who has similar requirements, this might work as well.
Using the .natvis files to accomplish this means, using IndexListItems for VS2013 and prior versions, and using CustomListItems for VS2015 and greater versions, and to make it look prettier, use the "no-derived" attribute. There is no way to make the Synthetic tag display only the base address of each variable and hence, the above attribute is the best way to go about, but this is not available in VS2013 and prior versions (The base address might get displayed but for people who want to go beyond just displaying contents and also access the memory context of the pointer element, Synthetic tag is not the right thing).
I hope this helps some developer who struggled like me using IDebug* interfaces. For reference, I am also giving the link to the msdn forum where my question was answered.
https://social.msdn.microsoft.com/Forums/en-US/030cef1c-ee79-46e9-8e40-bfc59f14cc34/how-can-i-send-a-custom-debug-event-to-my-idebugeventcallback2-handler?forum=vsdebug
Thanks.

How to implement custom resource provider dependent on different criteria than UI culture?

I am working on .NET 4.0 MVC3 web application. The application is all in English and allows users to fill information regarding different regions. For simplicity let's say we have two regions: United States and Western Europe.
Now in the view I present a string let's say Project opening, but if the user works on region United States I would like it to read Project initiation.
When I think about this functionality I immediately think about resource files for different regions, but independent from the UI culture.
Does anyone have a recipe how to achieve what I want?
Would be also nice, if in the future I could make it read e.g. ExtendedDisplayAttribute(string displayName, int regionId) placed over properties of my ViewModels.
EDIT
I am already at the stage where I can access region information in a helper that should return the string for this region. Now I have a problem with the resource files. I want to create multiple resource files with failover mechanism. I expected there would be something working out of the box, but the ResourceManager cannot be used to read resx files.
Is there any technique that will allow me to read the values from specific resource files without some non-sense resgen.exe?
I also do not want to use System.Resources.ResXResourceReader, because it belongs to System.Windows.Forms.dll and this is a Web app.
Just in case someone wants to do the same in the future. This article turned out to be really helpful: http://www.jelovic.com/articles/resources_in_visual_studio.htm
The piece of code that I use (VB) is:
<Extension()>
Public Function Resource(Of TModel)(ByVal htmlHelper As HtmlHelper(Of TModel), resourceKey As String) As MvcHtmlString
Dim regionLocator As IRegionLocator = DependencyResolver.Current.GetService(GetType(IRegionLocator))
Dim resources = New List(Of String)
If Not String.IsNullOrEmpty(regionLocator.RegionName) Then
resources.Add(String.Format("Website.Resources.{0}", regionLocator.RegionName))
End If
resources.Add("Website.Resources")
Dim value = String.Empty
For Each r In resources
Dim rManager = New System.Resources.ResourceManager(r, System.Reflection.Assembly.GetExecutingAssembly())
rManager.IgnoreCase = True
Try
value = rManager.GetString(resourceKey)
If Not String.IsNullOrEmpty(value) Then
Exit For
End If
Catch
End Try
Next
Return New MvcHtmlString(value)
End Function

Moving SP-Linq queries from test site to production site

I see articles on using SPMetal to generate the .cs file that allows LINQ to work properly. The file I'm talking about inherits from the Microsoft.SharePoint.Linq.DataContext class. How can I use LINQ without recompiling on my production environment, since I would need to regenerate this file using SPMetal on my production environment? I suspect the answer is going to be "can't do it".
I guess I'll use a CAML query instead unless there is some easier way to use LINQ that I am missing.
If the objective is just to query lists using LINQ and you want to avoid such recompilations, do not use SPMetal.
LINQ can be directly used on SPListItemCollection
e.g.
var FindCustomer = from SPListItem Item in Customers.Items
where Item["Orders"] as int == 5
select Item;
//or select new{Title = Item["Title"]}
This does not have hard coded entities but is more flexible. And as long as your list column names remain same, code can be deployed on any environment even if other lists are changing.
Also you can choose to retrieve few chosen field's data instead of retrieving data of all the fields every time.
There is no problem I guess. Personally I have been using Linq for good amount of time. I never generated the cs specifically for production. Is your site different across environments?
Im not sure if I'm missing the point or not, but the DataContext object takes the URL as apart of the constructor, so you should retrieve the URL from config somewhere E.g. database
DataContext teamSite = new DataContext("http://MarketingServer/SalesTeam");
OR use the SPContext object, if your code has a SharePoint context. E.g. in a web part
DataContext teamSite = new DataContext(SPContext.Current.Web.Url);

Resources