JScript.NET: Enumerating WMI collections - collections

In JScript.NET the following snippet:
wmi.js
------
var wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2"),
col =null, prc=null;
col=wmi.ExecQuery("SELECT * From Win32_Process", "WQL", 32);
//col=wmi.InstancesOf("Win32_Process");
var e = new Enumerator(col);
for (; !e.atEnd(); e.moveNext()){
prc = e.item();
print(prc.CommandLine);
}
compiles with:
%windir%\Microsoft.NET\Framework64\v4.0.30319\jsc.exe /platform:x64 wmi.js
and executes, but changing the WMI call with:
col=wmi.ExecQuery("SELECT * From Win32_Process", "WQL", 32);
compilation still works, while the execution gives the:
Unhandled Exception: System.InvalidCastException:
Unable to cast COM object of type 'System.__ComObject' to interface type 'System.Collections.IEnumerable'.
This operation failed because the QueryInterface call on the COM component for the interface with IID '{496B0ABE-CDEE-11D3-88E8-00902754C43A}' failed due to the following error:
'No such interface supported (Exception from HRESULT: 0x80004002
I don't understand why, since for both
InstancesOf
and
ExecQuery documentation says:
If successful, the method returns an SWbemObjectSet
Also, WSH JScript can enumerate both InstancesOf collection and ExecQuery.

First things first, remove the flag for wbemFlagForwardOnly and the ExecQuery returns an object that works as expected.
var wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2")
, col =null, prc=null;
col=wmi.ExecQuery("SELECT * From Win32_Process");
//col=wmi.InstancesOf("Win32_Process");
var e = new Enumerator(col);
for (; !e.atEnd(); e.moveNext()){
prc = e.item();
print(prc.CommandLine);
}
For the explanation, here's a shot in the dark (I don't work with Jscript.NET every day nor am I an expert).
from https://msdn.microsoft.com/en-us/library/ms974547.aspx:
"A forward-only enumerator performs much faster than the default enumerator, because WMI doesn't maintain references to objects in the SWbemObjectSet"
from the error:
"Unable to cast COM object of type 'System.__ComObject' to interface type 'System.Collections.IEnumerable."
It seems that converting collection to enumerator requires a reference to the object being casted. With wbemFlagForwardOnly flag, there is no reference passed so cast fails.
That is how I read this. Take it for what it's worth.
An interesting thing I found when researching: there is no error with this enumerator using wscript/cscript versus executing exe from jsc/csc.
Also, it seems VBScript has no problem enumerating with these flags; check out the examples and compare - https://msdn.microsoft.com/en-us/library/ms525775(v=vs.90).aspx.

Related

String.intern() returning different values in a JDBC driver

Whilst I was trying to make a fake JDBC driver to test a secure classloader I found an odd behaviour with the following code:
val stringClass = java.lang.String::class.java
val intern = stringClass.getMethod("intern")
val pooledString = intern.invoke("Hello World") as String
val valueField = stringClass.getDeclaredField("value")
valueField.isAccessible = true
val pooledValue = valueField.get(pooledString) as ByteArray
println(
"""|----------------------------------------
| String: ${System.identityHashCode(stringClass)}
| Thread: ${Thread.currentThread()}
| Pooled: ${System.identityHashCode(pooledString)}
| Internal: ${System.identityHashCode(pooledValue)}
|----------------------------------------""".trimMargin()
)
for (index in pooledValue.indices) {
pooledValue[index] = 'X'.toByte()
}
Running the above code from a JDBC driver's companion object gives this:
String: 349885916
Thread: Thread[main,5,main]
Pooled: 718231523
Internal: 1349414238
but running the same code from a method of the test class before loading the JDBC driver (during the same execution of the program) gives this:
String: 349885916
Thread: Thread[main,5,main]
Pooled: 1635756693
Internal: 504527234
I would have thought that getting the interned version of the string should have given the same string in both cases, but it seems that even within the same run of the program the 2 locations give different values for String.intern, which conflicts with the javadoc which says:
When the intern method is invoked, if the pool already contains a
string equal to this String object as determined by
the equals(Object) method, then the string from the pool is
returned. Otherwise, this String object is added to the
pool and a reference to this String object is returned.
Is this to be expected, and if so why is it that the values differ?
Most likely the reference has been garbage collected. The contract says that if you get the same string twice and compare the returned strings they will be equal. However, if you get a string, release the reference (making the pooled string available for gc) and then get a similar string again, nothing guarantees that it will still be pooled. You will get a new pooled string instead and that has a different identityHashCode.
Keep a reference to pooledString so that it cannot be garbage collected and see what happens!

BizTalk getting "invalid token" when try to run Orchestration with the expression below

I have a task that involves using an Orchestration to de-batch a multi-record XML file and then sort it based on one field's value. The first expression outside the loop gets the record count:
recordCount = System.Convert.ToInt32(xpath(CustFile,("count/*[local-name()='Root' and namespace-uri()='']/*[local-name()='People' and namespace-uri()='']/*[local-name()='Customer' and namespace-uri()='']")));
counter = 0;
recordNumber = 0;
Next Expression inside the loop sets the Xpath value:
sXPath = System.String.Format("/*[local-name()='Root' and namespace-uri()='']/*[local-name()='People' and namespace-uri()='']/*[local-name()='Customer' and namespace-uri()='']", recordNumber);
The Next Expression defines the final message:
InternalCust = xpath(CustFile,sXPath);
The final expression increments the record counter for the loop to back and start again with the next record:
counter = counter + 1;
I think I can manage the sorting of the output message, but when I try to run it as is I get the following error in the console:
xlang/s engine event log entry: Uncaught exception (see the 'inner exception' below) has suspended an instance of service 'BizTalk_SelfStudy_Week_4_Project.BizTalk_Orchestration1(ae65e0c4-9db7-6f19-1e08-6f4fbe08affe)'.
The service instance will remain suspended until administratively resumed or terminated.
If resumed the instance will continue from its last persisted state and may re-throw the same unexpected exception.
InstanceId: 4a2d7256-4882-4853-8f7c-6e6054e78c4c
Shape name: Debatch Message
ShapeId: 6ee14c8d-e55b-408b-be63-e5d83fa412a6
Exception thrown from: segment 1, progress 19
Inner exception: The part 'part' of message 'InternalCust' contained a null value at the end of the construct block.
Exception type: NullPartException
Source: Microsoft.XLANGs.Engine
Target Site: Void ConstructionCompleteEvent(Boolean)
The following is a stack trace that identifies the location where the exception occured
at Microsoft.XLANGs.Core.Part.ConstructionCompleteEvent(Boolean fKillUnderlyingPart)
at Microsoft.XLANGs.Core.XMessage.ConstructionCompleteEvent(Boolean killUnderlyingPartWhenDirty)
at BizTalk_SelfStudy_Week_4_Project.BizTalk_Orchestration1.segment1(StopConditions stopOn)
at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception& exp)
I am at a loss, as I've tried to validate the xpath and all I get is the invalid token message on the validator. Ideas anyone?
As Johns-305 has pointed out, your construction of the XPath is wrong
sXPath = System.String.Format("/*[local-name()='Root' and namespace-uri()='']/*[local-name()='People' and namespace-uri()='']/*[local-name()='Customer' and namespace-uri()='']", recordNumber);
It is missing a placeholder e.g. '{0}' which it would substitute the recordNumber into.
It probably should look like the below, which tells it which instance of Customer to select.
sXPath = System.String.Format("/*[local-name()='Root' and namespace-uri()='']/*[local-name()='People' and namespace-uri()='']/*[local-name()='Customer' and namespace-uri()=''][{0}]", recordNumber);
It also helps to Debug an Orchestration which would have allowed you to see that the XPath didn't include the Record Number and to test the Xpaths produced, a tool useful for this is Dan Sharps XML Viewer

PHP7. Reflection doesn't work from old versions php

I have a php script which was written on php 5.6.19, works on 5.3 version to, with some installed addons.
I decide to try execute it on php7.
The special of the script that I am initializing a class with parameter by reference via creating a new instance with Reflection::class. And there warning then waited variable by reference but value received.
Definition of the class' constructor method tried to create an instance from:
public function __construct($user, IDatabase &$repository, $errors = null);
Sample of code where this constructor is used:
// define manager type to create (all managers has the same constructor)
$manager = $managersNamespace . ucfirst($this->_manager) . "Manager";
// trying to create the manager
// !!!And here a Warning occurs
$reflect = new \ReflectionClass($manager);
$manager = $reflect->newInstance($user, $database, $errors);
After these I am invoking a method I need, and here the fatal error with stopped the script:
$method = "show" . ucfirst($this->_page) . "Page";
$reflect->getMethod($method)->invoke($manager);
I didn't see any changes in documentation. Anyone had the same issue?
First and foremost, why are you passing an object by reference !?
Objects have pass-by-reference semantics, forcibly trying to pass objects by reference has not made good sense since PHP 4.
Just remove the & ...
Let's ignore that, and pretend there is still a problem, so that you can try to understand what is going on.
To break down the problem, first you need to understand the distinction between a variable and an expression:
mine(1 + 2);
The argument to mine has no name, it's represented by a temporary variable in the engine: it's an expression.
mine(1);
The argument to mine has no name, it's not an expression, but a literal constant, represented by a compiler variable in the engine. It's similar to a temporary variable, a kind of constant expression.
mine($a);
The argument to mine has a name, which you can use to refer to it's value. It's a normal variable.
Only variables can be passed by reference because you cannot refer to expressions or literal constants
Next you need to understand why we pass-by-reference:
function mine(int $thing) {
$thing++;
}
$a = 1;
mine($a);
var_dump($a); // int(1)
In this code, $a is passed to mine() by value, so that the changes that mine() make to $thing are only visible inside the scope of mine. $a is unchanged after the call to mine() returns because $a and $thing are distinct, having been passed-by-value, which means it's value was copied on to the call stack for the invocation of mine().
function mine(int &$thing) {
$thing++;
}
$a = 1;
mine($a);
var_dump($a); // int(2)
In the code above, $a is passed to mine() by reference, this means that $a and $thing are no longer distinct. The changes mine() make to $thing are now visible after the call to mine() returns.
The last piece in the puzzle is Reflection:
function mine(int &$thing) {
$thing++;
}
$a = 1;
$reflector = new ReflectionFunction("mine");
$reflector->invoke($a);
The code above will raise:
Warning: Parameter 1 to mine() expected to be a reference, value given in /usr/src/php-src/refs.php on line 9
This is because ReflectionFunction::invoke and similar reflection functions (ReflectionClass::newInstance) accept their parameters by value and pass them onto the invoked function by value.
But ...
There is still a difference between pass-by-reference semantics, and passing by reference, a dangerous one:
class Foo {
public function qux() {}
}
class Bar {}
function mine(Foo &$foo) {
$foo = new Bar();
}
$foo = new Foo;
mine($foo);
$foo->qux();
Will obviously yield:
PHP Fatal error: Uncaught Error: Call to undefined method Bar::qux() in /usr/src/php-src/refs.php:16
Stack trace:
#0 {main}
thrown in /usr/src/php-src/refs.php on line 16
The declaration of mine() tells lies about the type safety of it's parameter. Type safety is only guaranteed upon entry to the function, the function body is free to break type safety, but it doesn't usually affect the caller when relying on the engines pass by reference semantics for objects.
This is an extremely scary kind of API, that should be avoided.

ORA-28579: network error during callback from external procedure agent...(some issue with heap allocation)

Snippet: An external C dll which receives a collection(Nested Table of numbers) from PLSQL and does some processing(not shown in the code).
Issue: When this external C function is called from PLSQL(library and wrapper created in PLSQL) the numbers are received by the C function in the array(on stack). HOWEVER, if I un-comment the commented lines for a dynamic array(on Heap) instead of a static the call fails with:
ORA-28579: network error during callback from external procedure agent.
Please suggest
#define ARRSIZE 107
extern "C" __declspec(dllexport) int ooci_ntm(OCIExtProcContext *context, OCITable* clients)
{
OCIEnv *envhp;
OCISvcCtx* svch;
OCIError *errhp;
double onumm[ARRSIZE]; //Works if its a static array on stack
//double* onumm= (double*)malloc(sizeof(double) * ARRSIZE);
//However, if instead of the above array if the memory is allocated dynamically on heap then the captioned error is thrown.
sword status;
boolean exist;
uword nelems;
OCIExtProcGetEnv (context, &envhp, &svch, &errhp);
OCINumber **client_elem = (OCINumber**)malloc(sizeof(OCINumber*) * ARRSIZE);
status = OCICollGetElemArray(envhp, errhp, clients, index, &exist, (void**)client_elem, (dvoid **)0, &nelems);
status = OCINumberToRealArray(errhp,(const OCINumber**)client_elem,nelems,sizeof(double),(void*)onumm);
free(client_elem);
//free(onumm);
return size;
}
It looks like this is one of those errors that essentially means any number of things could have gone wrong with the external procedure.
There is a known bug in 10.2.0.3, no idea if it's relevant:
ORA-28579 occurs when trying to select
data from a pipelined table function
implemented in "C" using the
ODCITable/ANYDATASET interface.
ODCITableDescribe works fine but
ODCITableFetch generates an ORA-28579
error.
Try to Contact Oracle support

Array of Dictionaries - Julia

I'm trying to make a constructor for a custom type in Julia:
type Cell
Base::Dict{String, String}
zLayers::Array{Dict{String, String},2}
X::Int
Y::Int
Cell() = new(Dict{String,String}(),[Dict{String, String}(),Dict{String, String}()],0,0)
end
try
gamestate = Cell()
catch err
print("connection ended with error $err\n")
end
Throws error:
connection ended with error MethodError(convert,(Array{Dict{String,String},2},[Dict{String,String}(),Dict{String,String}()]))
So how do we do proper initialization for Arrays of Dictionaries?
This question was double posted and answered on the mailiglist.
https://groups.google.com/forum/m/#!topic/julia-users/zE8Ri8rbfHQ
I think you’re confusing the 2 in an Array parameter set with the number of items, when it’s the number of dimensions. I’m pretty sure you’re creating a Vector, not a Matrix.

Resources