After registering(RegAsm) my C# COM visible class, I see that CoCreateInstance(__uuidof(myclass)) takes a lot of time only for the first time, subsequent attempts in the same client process are resolved instantly. Any idea why is it taking time?
NGen is not an option for me.
My COM Server is in C# and client is in MFC/ATL
CComPtr<namespace::Imyclass> obj;
hrx = obj.CoCreateInstance(__uuidof(namespace::myclass));
The first call to CoCreateInstance has to load into the process, and initialize, the .NET runtime. Then, your DLL has to be loaded, "verified", and compiled into machine code (although just-in-time helps a lot to speed-up the startup). The .NET runtime also has to parse the metadata of your assembly, and then dynamically generate and compile the "COM callable wrappers" (http://msdn.microsoft.com/en-us/library/f07c8z1c.aspx) which are the proxies that bridge between the unmanaged COM world and the managed .NET runtime. Any additional libraries your code might use also needs to be loaded, verified and possibly compiled into machine code (if not NGEN'd).
This is inherently an expensive process. The delays you mention are not unheard of.
I don't believe there is much you can do to speed things up. I suggest you think about whether you can take the hit early in your program's lifetime by creating an object soon after startup. It won't make it faster, but it might improve the user experience dramatically. if your program just can't tolerate the delays, then you should not use .NET to write the COM object (more specifically, you should not use .NET in your process at all. This is not an issue with using COM; it's an issue with loading .NET)
Incidentally, this is one of the reasons why writing shell extensions in .NET is... "highly discouraged". See this recent post on this subject, which touches on the startup performance of .NET as well: http://blogs.msdn.com/b/oldnewthing/archive/2013/02/22/10396079.aspx
(That's why I asked earlier what kind of client you were running. A client that already runs .NET managed code depends on the .NET runtime and would not be affected by these delays)
The first call to CoCreateInstance is likely having to consult the registry and the file system, loading the appropriate code, allowing it to initialize, and finally invoke a factory to create the instance you've asked for (if it could be located).
The second call benefits hugely from these previous steps. If the first call was successful, then the code is already loaded and initialized, and all it has to do is invoke a factory a second time.
If this delay is only for first load (after computer start), then this is caused by loading all libraries. First delay after start (or after long time without usage of .NET) will always be slow. (See Micelli answer)
Delay can be also caused on each loading. Today I found out that internet connection can also cause the delay.
Measured values:
No Ethernet and no WiFi connection delay: 94 ms (Win7) / 1.5 (WinXP)
Windows XP: Internet connection (with proxy and non standard gateway; not all ports are allowed): 4-5 s (WinXP)
Connected to Ethernet not not to Internet: 10 s (Win7)
Short after the connection to Ethernet (Windows test Internet connection; blue circle on the Network Icon): 30 s (Win7)
Internet connection (with proxy and non standard gateway; only few ports are allowed): 30 s (Win7)
*non standard gateway: allowed TCP ports and connections are different for each computer (Different for WinXP and Win7).
Tested on Windows 7 (x64) and WinXP. I tested it because it came as a complain from a customer and located the delay to CoCreateInstance The loaded library is in c# and is signed (signed assembly with snk and with standard certificate for signing executable files).
See also: http://social.msdn.microsoft.com/Forums/sqlserver/en-US/cda45e39-ed11-4a17-a922-e47aa2e7b325/ce-40-delay-when-cocreateinstance-on-pc-without-internet?forum=sqlce
Related
I am trying to proxy WS2_32.dll but no matter what I do it always loads the systems one instead. I used a tool to check and it is loading the systems one:
0x00000000775c0000 0x67000 C:\WINDOWS\SysWOW64\WS2_32.dll
I heard windows blocks this one from being loaded if its in the same directory. Is there anyway to override this?
You're describing a security feature of Windows here. Known Windows DLL's are loaded from trusted locations (and secured against modification there). So no, there's no publicly known method. And if one would become known, you would expect a patch very shortly afterwards.
This question already has answers here:
How to write a browser plugin?
(4 answers)
Closed 9 years ago.
In my legacy web application I need to read user system registry from JS and do some other stuff. I cannot not use ActiveX for security reasons so I have written a plugin. My Plugin consists of a DLL file which is a COM component. This COM component exposes few functions which I call from Java Script code.
In IE I package my DLL in a CAB file and install it, say it's test.dll, in the following way:
<object classid="clsid:some class id here" codebase="test.cab" height="0" width="0" onError="testInstalled=false; return true;" id="testComp"></object>
The above HTML tag install the COM component as plugin in IE and Im able to access the exposed functions of the same from my JS code:
var testCompApp = document.testComp;
testCompApp.callSomeFunction();
It works fine in IE. I need the same functionality in other browsers(Chrome,Firefox, Safari)
Can you pls suggest how to develop plugins for other browsers using my DLL file?
Thanks,
I don't get it: First you say "I can't use ActiveX for security reasons", and then you do the same bad things that ActiveX does in all its dangerous glory: a CAB-packaged COM object running unrestricted native Win32.
How does doing that solve your security concerns with ActiveX?
Leaving aside for a minute the question of "security": if you are not doing "ActiveX" already, you're pretty close. I don't remember off the top of my head all the details of what goes into [the-IE-plug-in-architecture-that-shares-with-other-stuff-the-marketing-moniker-of] "ActiveX", but I think all you are missing to be called "ActiveX" is a few interfaces you must implement. I also suspect that by being shy of "ActiveX" you don't even get to sign your CAB with Authenticode, which would provide your users with a modicum of confidence (assuming you maintain proper controls and key management, and that your users trust you enough to allow your native code to run on their computers).
In any case, that DLL you wrote will only ever run in IE. There is no other browser that supports Win32 native COM objects (whether you choose to follow the ActiveX specification to the letter or not). If you want to do the same thing in other browsers, you are going to have to rewrite it with something else.
I think you have (at most) two options for doing what you want to do:
COM/ActiveX: Native Win32 code in a COM object. What you are doing now. This only works on IE and it's extremely dangerous for users, unless it's done in a controlled environment (e.g. if this is a commercial product to be distributed by an enterprise customer's IT department, or if you have an established presence and a reputation, like some large companies do).
Java:. This would run on all browsers assuming your users have the proper runtime installed and enabled. But it will only work for you if Java allows access to the information you seek via a sandbox-authorized method, because you can't call registry API's from the Java sandbox. The same goes for "the other stuff" you need the plug-in to do.
Ok, so you have a third option:
Reimplement the whole thing in something that is not tied to the browser: a native Windows executable; maybe in a downloadable installer or maybe a .NET program deployed via ClickOnce.
You are in a pickle: You are saying "I have security concerns with running ActiveX but I need to do something dangerous". Any piece of code downloadable and runnable by a web browser that is able to access the registry directly is - necessarily - a dangerous piece of code. Any conceivable technology that allows you to run such code from a browser will immediately elicit the very same security concerns that ActiveX elicits.
Indiscriminate access to the registry is out of the question from a modern browser sandboxed environment, so you either have to find a different source for the specific information you want, or you have to use ActiveX/COM running under IE.
I have a very strange issue that i cannot figure out.
First i have a WCF service 4.0 done in VS2010.
the service have couple methods that return string array, datatable and such.
some of them use function from C++ dll throught [dllimport]
i made a test console to test everything. when i run the WCF from visual studio and use the generated path it works wonderfully.
now here is where it become strange. if i open my local IIS create a new application and point to my VS source code the WCF i can see it perfectly.
now using the http path from IIS local instead i refresh the methods all seems correct. But when i run my test app i can call any unction without any problem EXCEPT anyone using DLLIMPORT functions. they ALL crash and cannot trace even by tracing CES exceptions.
Doing line by line logging show that the exception is really on the call of those functions
the DLL in question is the same and the path is hardcoded for my computer since still in test phase and the folder is c:\DLL\mylib.DLL so nothing to do with shadow copy IIS/visual studio do when you actually run. also DLL reference by name withotu path even if it's in sys32 doesnt work.
Any clue ?
also. 32bit, changing app pool level right access on folder, full admin on machine already too. all tried but unsuccessful.
Edit: adding to all that since i haven't made this clear, it's not my first WCF real setup. i've already made alot of services before and deployed them myself (probably somewhere around 50-60 services). I am asking because i have never seen this issue before and i tried all tricks i knew and could find on the internet and resource people i know.
We have decided to incorporate the whole service in the WPF project locally since it work as long as IIS is not hosting. but this is really not a good thing as this data and work should NOT be done on client side but instead on server side. Right now it's fine since the software that need to use this is not released to public yet so it isn't critical.
Next option will be net TCP/IP windows service hosted on the web server if i don't find anything else.
We decided to go trough the trouble of having to hard code the logic in the main software and get away from web services for this issue. we will have to deal with updating, installing unregister and re register unmanaged DLL by hand somehow but at least it works.
we have added over 5 web services since that happen and no problem with them but again none of them use DLL imports.
Forgive me if this is a stupid question, I'm fairly new to writing services. I've written a service that runs a timer and the timer code runs some checks to ensure our systems are up and running. It's written in VB.Net, framework 1.1. I then install the service using "sc create". The service works beautifully on the XP Pro machine that I'm developing on. However, when I install the service on a Windows 2003 server 64 bit, the service fails with error 1053 immediately. I put some debugging in to write to a text file as the first line of code in the OnStart function but even that doesn't run, so there must be a problem in the program starting up. Finally in desperation I created a brand new Windows Service in a new VB project in Visual Studio 2003 and compiled an empty service that merely declares and sets the value of a string variable in the OnStart function as follows:
Dim strTmp As String
strTmp = "hello"
Even that failed on the W2K3 server, but works fine on the XP dev machine.
The server has .Net Framework 1.1 installed and working, we use it in our CMS (written in ASP.Net 1.1).
The service runs as the local system account. I tried enabling interaction with the desktop but that didn't help. I ran Process Monitor and there are no access denied events. I emptied the Application Event Log, still doesn't work. No other events to help me out in the logs. Definitely using the Release build of the application. Permissions on the exe file are full control for System and for Admins.
Any ideas anyone? It must be something simple, but I'm damned if I can figure it out!
Thanks in advance.
#DavidHi, many thanks for the suggestions. I donĀ“t think the first point is my problem, partly because the MS article is about stopping or pausing the service, mine fails on starting; but also because the service does not timeout, there is no 30 second wait, it fails immediately. Secondly, when you say add an exception handler to the service startup, do you mean the OnStart sub? I tried adding a debug file write in there, but I'll try adding an event log instead. Regarding the systems checks, it can't be that because the brand new empty test service I created shows the same behaviour and that does not do anything at all. You last point could be the key. My dev environment IS 32bit. I'll do some research on the corflags thing, or perhaps I can build a 64bit dev environment. Many thanks again, you've given me some new things to think about at least!
Ok, have found a workaround. I was putting my exe file in System32. When I put it in a different folder, created by myself, the service ran, albeit briefly. I then had to move the ini file and the log files that it reads/writes to that folder too, rather than System32, and all seems to work nicely. God knows why it doesn't like running from System32 but at least it works now! Thanks for the help guys.
This looks very similar to this question which might help you out:
Starting a windows service fails with error 1053
A couple of other things to look out for:
Make sure you don't have either of the following statements in your deployed service:
System.Diagnostics.Debugger.Launch
System.Diagnostics.Debugger.Break
You may need to run the service with an account other than Local System (depending upon the permissions required by your service).
The 1053 error is a timeout related to the service control manager waiting for the service to respond to your start request. There is a knowledgebase article that refers to managed service stop request issues specifically relating to Framework 1.1-based services, so it is not precisely describing your problem, but it may have relevance in your situation. The link is provided for your reference.
http://support.microsoft.com/kb/839174
The other suggestion I would make to further diagnose the issue is to determine whether the Start is failing due to a "hidden" exception occurring in your service's startup code; the start call would not see the exception and could make you think it was merely timing out.
I would suggest you add an exception handler to your service startup that does nothing more than log a message to the event log with the particulars of the exception if one is caught. That would at least give you an idea that something is going wrong specifically within the service, and give you more information than you have right now.
One last thought: Does the service check the systems you describe over a network connection? If so, LocalSystem won't have sufficient privileges to perform network access.
Good luck!
EDIT One other possibility:
Is your development environment/execuable 32-bit? You mention your server is 64-bit, so you may need to use the "corflags" tool that forces 32bit operation on your executable
corflags /32bit+ YourServiceExectubable.exe
The source for this information was the following SO post:
32-bit Windows services in 64-bit environment
**Unfortunately, it appears corflags is applicable only for 2.0 assemblies, and was designed for specifically this type of problem. **
I'm in need of distributing several old COM applications that are to be installed on locked down computers. I'm trying to get these applications to launch without having to be registered in the registry via regsvr32 or in the case of an EXE component via the /regserver switch. I can control and locally copy all the required dependencies in this scenario.
I know this is possible, however, I'm having a real tough time piecing together the different pieces or finding coherent information on how to set this up.
Any help or pointers would be greatly appreciated.
Microsoft has a good tutorial on Registration Free COM.
There are two basic parts to getting registration free COM working.
First, you need to convert the COM dlls to an assebmly: Just the COM dll's, and create a manifest describing them, and give it a name. Bundle this assembly in the same folder as your application.
Next, you need to tell your application to use the assembly you just created. When COM tries to create a new object, it will first look in any assemblies registered in the default activation context, before looking in the registry.
Registrationless COM can be tricky to set up but the overall process is not very complex. I wrote up my process along with some tools that help with debugging problems in a blog post here:
http://www.west-wind.com/weblog/posts/2011/Oct/09/An-easy-way-to-create-Side-by-Side-registrationless-COM-Manifests-with-Visual-Studio
FWIW, registrationless COM doesn't work with DCOM EXE servers unfortunately - only DLL servers are supported.