I have a bunch of COM objects which all implement the same interface, and need to create one of them as chosen at runtime from a list of options. Since I know the CLSID for
It's probably because your application is not elevated outside of Visual Studio and is failing on permissions to interact with the COM components.
Right-click and run as administrator
to see if it makes a difference.
Two suggestions.
Use [STAThread] attribute.
[STAThread]
static void Main(string[] args)
{...}
Try calling CoInitialize
[DllImport("ole32.dll")]
static extern int CoInitialize(IntPtr pvRes);
CoInitialize((System.IntPtr)null)
Not sure what is happening there but as a workaround I wonder if you might try launching the process with something like...
System.Diagnostics.Process.Start("THE_PROCESS.exe");
Then once the process is running you could try to get the object from the running objects table using the ProgID...
object appObj = System.Runtime.InteropServices.Marshal.GetActiveObject("THE_PROGID");
So I spent some time testing this out, and I was able to reproduce the issue exactly as you describe. I recreated your exact console app and I see the same behavior, but I think I can at least add some new information.
At first I thought the same as you, that it was something with visual studio making it work, but that's not actually the case. If you build this into a console executable, and then launch it from explorer, it works fine with no visual studio involvement. Also I added Debugger.Launch() to the beginning so I could attach to it when run from the command prompt, and I get the error even with VS fully attached and debugging. My results all indicate that it's not VS that's making it work, it's actually running it from the command prompt that is breaking it.
I tried all kinds of stuff to make the environment the same between command prompt launching and windows explorer launching, but I get the same thing every time; works perfect from explorer and dies from command line.
Digging in with reflector, the setup is passing all of its tests and everything. It's the actual call to:
RuntimeTypeHandle.CreateInstance(this, publicOnly, noCheck, ref canBeCached, ref ctor, ref bNeedSecurityCheck);
In the RuntimeType class which is bombing out, and there's no more managed code to dig into at that point. At this point my guess is that it has to be something entirely contained in the Adobe COM Server that is killing it off when run from the command prompt.
Maybe someone who knows more about the guts of windows can speak to the differences between executing from the command line vs. explorer?
"Technically speaking adobe supplied and correctly registered the PDF text extraction filter DLL (ACRORDIF.DLL) but it wouldn't be instantiated by any common means, that is either using LoadIFilter API or using direct COM object creation after looking up the filter object CLSID in the registry. Was it broken? No, because somehow windows search could use it!? Some people argued that the filter was dropped in STA threading mode (like it did in the old v6 days) but that isn't corroborated by the ThreadingModel of the filter DLL. Some talked about running it only through a Job object. Adobe support kept themselves tight lipped and were claiming that the restriction was there for our security — ahem." ... "Can you guess how the trick works? They hard coded the names of MS tools like FILTDUMP in the PDF filter ACRORDIF.DLL!!! So when the PDF IFilter object is being instantiated, it checks the calling process name, and if it is one in the "whitelist" it works, otherwise it fakes a problem and E_FAILs. Scandalous. For proof, rename your program to "filtdump.exe" and as if by magic everything works, even plain LoadIFilter without job objects."
Does Adobe reader support PDF text extraction or not?
This Question is old (and answered), but I thought I would add a little information.
Adobe X (10.1.x) will fail to provide an IFilter interface under some conditions. Calls to QueryInterface, or ClassFactory->CreateInstance or ::LoadIFilter or whatever will fail with E_FAIL. The condition I'm referring to is when the process that is running is not part of a "Job".
I.e., their 10.x IFilter checks to see if the current process is in any job. If not, it fails (for me at least). My work around 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 to this, i.e., the new job gets default security of the current user. I have more testing to do. I welcome anyone's input.