idobatter / node-win32ole

Asynchronous, non-blocking win32ole bindings for node.js .
http://idobatter.github.com/node-win32ole/
208 stars 53 forks source link

Working with Activex components #1

Open umutm opened 11 years ago

umutm commented 11 years ago

Hi,

I have found the module through an entry of mine from Stackoverflow.

I'm trying to make ping requests with nodejs without forking any new processes (ping.exe or cscript.exe).

As there are no raw sockets modules for nodejs, I want to make use of an Activex component for that which is: http://www.activexperts.com/activsocket/objects/icmp/

Can I make this work with node-win32ole?

A simple ASP code I use for the component is as below:

Query = "www.google.com"

set Ping1 = Server.CreateObject("Dart.1")    
set Reply = Ping1.Echo(Query)

if Err = 0 then
    dim Result
    if Reply.Error = 0 then
        Result = "Result for " & Reply.RemoteName & "(" & Reply.RemoteAddress & "): " & Reply.ElapsedTime & " milliseconds"
    else
        Result = "Result for " & Reply.RemoteName & "(" & Reply.RemoteAddress & "): Error #" & Reply.Error & "<br>" & Reply.ErrorDescription
    end if
else
    Result = "There was an error:<br>" & Err.Number & " " & Err.Description
end if

I would appreciate any guidance on using it with node-win32ole.

idobatter commented 11 years ago

Hi, Thank you to create an issue, and I tried http://www.activexperts.com/activsocket/objects/icmp/ "AxNetwork.Icmp" component. As the sample of that page, you can write it in node.js with node-win32ole (version 0.1.x) without forking any new processes.

var win32ole = require('win32ole');
var axn_sample = function(){
  try{
    var query = 'www.google.com';
    var icmpObj = win32ole.client.Dispatch('AxNetwork.Icmp');
    console.log(icmpObj.Version);
    icmpObj.Ping(query, 2000);
    var result = 'Request for ' + query + ': ';
    if(icmpObj.LastError == 0){
      result += '' + icmpObj.LastDuration + ' milliseconds';
      result += ' TTL=' + icmpObj.LastTtl;
    }else{
      var errno = icmpObj.LastError;
      result += 'Error ' + errno;
      result += ': ' + icmpObj.GetErrorDescription(errno);
    }
    console.log(result);
  }catch(e){
    console.log('(exception catched)' + e);
  }
  console.log('completed');
};
axn_sample();

But sadly it does not work now. At the line var icmpObj = win32ole.client.Dispatch('AxNetwork.Icmp'); an Exception is throwed "Dispatch failed in CoCreateInstance()". I think there is something wrong with Client::Dispatch in src/client.cc . So please wait for fix it or use other component supports ping.

* additional comment * I found it works with "ActiveXperts\Network Component\Program\AxNetwork32.dll" , but it does not work with "ActiveXperts\Network Component\Program\AxNetwork64.dll" . So please try "regsvr32 /u AxNetwork64.dll" and "regsvr32 AxNetwork32.dll" on dlls' directory by Administrator account.

* sample source was edited * New accessor was Implemented. Remove '._' ideoms and fix version string.

umutm commented 11 years ago

Thanks so much for the effort and the update.

I have recently found a nodejs ping with raw sockets module (https://bitbucket.org/umutm/node-net-ping) and giving the ping a try with it.

But, will probably be using win32ole for many other stuff.

Thanks so much again.

idobatter commented 11 years ago

Thanks so much for your reply. I edit and add comment to the above source.

umutm commented 11 years ago

Wow, you're awesome. Thanks so much. I'll be using it as a fallback for my app.

Thanks so so much.

greeeen commented 11 years ago

Hi, I think there is the way to connect from 32bit client to 64bit server by CoCreateInstance(). CLSCTX_ACTIVATE_32_BIT_SERVER = 0x40000, CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000, http://msdn.microsoft.com/en-us/library/windows/desktop/ms693716%28v=vs.85%29.aspx

greeeen commented 11 years ago

Hi, I tried these flags (CLSCTX_ACTIVATE_nn_BIT_SERVER), but each flag takes no effect. I think COM server must support 32-64 compatibility itself. In the case of ActiveXperts, "regsvr32 AxNetwork32.dll" is need, but "regsvr32 /u AxNetwork64.dll" is not need because these inprocess server can be coexistence on 64bit OS. PreferredServerBitness (COM) http://msdn.microsoft.com/en-us/library/windows/desktop/ms694319%28v=vs.85%29.aspx http://mariusbancila.ro/blog/2010/11/04/32-bit-and-64-bit-com-servers/ http://social.msdn.microsoft.com/Forums/en-US/vcgeneralja/thread/f166d8e1-eb8f-4c42-85da-4f5d4049e0a6/

idobatter commented 11 years ago

Hi, Thanks so much. Sadly 'PreferredServerBitness = 3' does not work AxNetwork32.dll without registration. I want to continue researching about this.

paco3346 commented 11 years ago

I'm having a similar issue. I only have a 32 bit ocx but I keep getting the following error:

FAILED CoCreateInstance: 0: 0x80040154 FAILED CoCreateInstance: 1: 0x80040154 ASSERT in 000003f0 module ..\src\client.cc(135) @node_win32ole::Client::Dispatch: !(((HRESULT)(hr)) < 0) error: An attempt was made to reference a token that does not exist.

c:\Users\Administrator\node_modules\win32ole\lib\win32ole.js:171 return win32ole.client.Dispatch(args); ^ TypeError: Dispatch failed at new global.ActiveXObject (c:\Users\Administrator\node_modules\win32ole\lib\win32ole.js:171:26) at Object. (c:\Users\Administrator\Desktop\icomm\script.js:3:13) at Module._compile (module.js:449:26) at Object.Module._extensions..js (module.js:467:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Module.runMain (module.js:492:10) at process.startup.processNextTick.process._tickCallback (node.js:244:9)

I've triple checked and I know I'm using the correct ProgID. I can spawn other COM objects (such as Access.Application or Excel.Application) with no issue.

I have a deep understanding of javascript and node.js but my knowledge is rather shallow when it comes to Windows objects / ActiveX. Any input or ideas would be appreciated.

paco3346 commented 11 years ago

Should have tried this before the first post...

Looks like running a 32 bit version of node fixes the problem.