Activator.CreateInstance (<guid>) works inside VSIDE, but not externally
I have a bunch of COM objects that all implement the same interface, and I need to create one of them, selected at runtime from the list of options. Since I know the CLSID for each of the implementing COM servers, this should be easy. However, for a subset of COM libraries, I can only do this work if I run VS2010 inside ID2.
Here is the whole program that I use for testing:
using System; namespace ComTest { class Program { static void Main(string[] args) { var clsid = "{E8978DA6-047F-4E3D-9C78-CDBE46041603}"; var type = Type.GetTypeFromCLSID(new Guid(clsid)); var obj = Activator.CreateInstance(type, true); Console.WriteLine("Obj is {0}", obj); } } } I can do this work for every COM CLSID I have tried so far, as long as I run VS2010. With or without an attached debugger and with or without hosting, I get System.__ComObject back from CreateInstance .
When I compile and run this code from the console window, for certain CLSID values, I get instead:
Unhandled Exception: System.Runtime.InteropServices.COMException: Creating an instance of the COM component with CLSID {E8978DA6-047F-4E3D-9C78-CDBE46041603} from the IClassFactory failed due to the following error: 80004005. at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) at System.Activator.CreateInstance(Type type, Boolean nonPublic) at ComTest.Program.Main(String[] args) in This only happens with specific CLSIDs - for example, "{c1243ca0-bf96-11cd-b579-08002b30bfeb}" (embedded text IFilter), but "{E8978DA6-047F-4E3D-9C78-CDBE46041603}" (Acrobat Reader X IFilter) not. What I cannot understand is how starting through the IDE does things differently if the COM Interop call succeeds. Any ideas?
EDIT:
I do not start VS2010 as an administrator, but I had trying to run the binary output file using the Powershell elevated console, but it still does not work.
EDIT 2:
So far, the only COM server that I have used that reproduces this βerrorβ is Acrobat Reader X AroRdIf.dll (previous versions work fine). I'm not worried about working with Acrobat specific IFilter, but I'm very concerned that I have code that works in my development environment, but not outside. And, as an aside, the Windows SDK FILTDUMP tool does not have problems loading this COM server, so I know that it is possible, I just donβt know how .
So, I spent some time on this, and I was able to reproduce the problem exactly as you described. I recreated your exact console application and I see the same behavior, but I think I can at least add new information.
At first I thought just like you, that it was something with a visual studio that made you work, but in fact it is not. If you create this in the console executable file and then run it from Explorer, it works fine without the participation of the visual studio. I also added Debugger.Launch () to the beginning so that I can connect to it when starting from the command line, and I get an error even with VS fully connected and debugged. My results show that it is not VS that makes it work, it actually launches it from the command line, which splits it.
I tried all kinds of things to make the environment the same between starting a command prompt and starting Windows Explorer, but I get the same thing every time; works fine from the explorer and dies from the command line.
Digging with a reflector, the installation passes all its tests and that's it. This is the actual call:
RuntimeTypeHandle.CreateInstance(this, publicOnly, noCheck, ref canBeCached, ref ctor, ref bNeedSecurityCheck); In the RuntimeType class, which takes off, and in this place there is no more managed code. At this point, I assume that it should be something that is completely contained in Adobe COM Server, which kills it when it starts from the command line.
Maybe someone who knows more about window guts can talk about the differences between command line vs. explorer?
This question is old (and answered), but I thought I would add some information.
Adobe X (10.1.x) will not be able to provide the IFilter interface under some conditions. Calls QueryInterface or ClassFactory-> CreateInstance or :: LoadIFilter or something fails with E_FAIL. The condition I'm talking about is that the process that is running is not part of the "Work."
Ie, their 10.x IFilter checks to see if the current process is in any job. If not, it will fail (at least for me). My job is something like the following psuedo code:
HANDLE curProc = GetCurrentProcess(); BOOL bResult = FALSE; int iResult = IsProcessInJob(curProc, NULL, &bResult); if(iResult != 0 && bResult == FALSE) { HANDLE hJob = CreateJobObject(NULL,"whatever"); AssignProcessToJob(hJob,curProc); } There may be side effects for this, i.e. a new task receives default protection for the current user. I have more tests. I welcome any user.
I cannot reproduce the problem you described ... some general pointers to check:
- If you use Adobe IFilter by default, then you will see strange behavior when working as a 64-bit or AnyCPU on a 64-bit machine ... running VS can make a subtle difference here.
- http://support.microsoft.com/kb/2018558
- http://support.microsoft.com/kb/927675/en-us
- http://social.technet.microsoft.com/Forums/en-US/sharepointsearch/thread/aa966100-17f6-4ea9-8753-085cfbe5f17a/
- http://social.technet.microsoft.com/Forums/en/sharepointsearch/thread/0f062b26-b6ad-4c18-8c33-192e2a741dec
"Technically speaking, Adobe and a properly registered filter for extracting PDF DLL files (ACRORDIF.DLL), but it will not be created in any general way that either uses the LoadIFilter API or uses the direct creation of a COM object after searching to filter the CLSID object in "Was it damaged? No, because somehow the search on Windows could use it!" Some people claimed that the filter was disabled in STA streaming mode (as in the old days of v6), but this is not confirmed with the ThreadingModel DLL filter. Some talked about running it only through the Job object. Adobe support kept itself tightly compressed and claimed that the limitation was for our safety - gem . "..." Can you guess how the trick works? They are hard-coded names for MS-tools, such as FILTDUMP, in the PDF file ACRORDIF.DLL !!! So, when the PDF IFilter object is created, it checks the name of the calling process, and if it is alone in the whitelist, it works, otherwise it creates a problem and E_FAILs. Scandalous. To confirm, rename your program to "filtdump.exe" and, as if by magic everything works, even a simple LoadIFilter without job objects. "
Not sure what is going on there, but as a workaround, I wonder if you can try to start the process with something like ...
System.Diagnostics.Process.Start("THE_PROCESS.exe"); Then, as soon as the process is running, you can try to get the object from the table of working objects using ProgID ...
object appObj = System.Runtime.InteropServices.Marshal.GetActiveObject("THE_PROGID");