Вот такая проблема - в одной программке референсе на COM обьект работает, a в другой рядышком нет. Обе компилирются на моей машине, а когда устанавливаю на сервер, одна работает, а другая нет (обьект _objDM не создается).
Вот ето работает (Windows forms app):
public class Form1 : System.Windows.Forms.Form
{.........
private KDIDataManager2.CDataManagerClass _objDM;
......
_objDM = new KDIDataManager2.CDataManagerClass();
this.Text += "[" + _objDM.GetCurrentDBName() + "]" + "[" + _sCurrentIP + "]";
....
}
А тут же рядышком, в другой программке, уже не работает (Windows service):
public class JobCacheCleaner : System.ServiceProcess.ServiceBase
{......
private KDIDataManager2.CDataManagerClass _objDM;
.........
_objDM = new KDIDataManager2.CDataManagerClass();
_objDM.CheckConnection();
sConnString = _objDM.sDBNETString.ToString();
_objDM.CloseDBConnection();
_objDM = null;
...
}
Ошибка:
1/7/2004 11:36 AM System.InvalidCastException: QueryInterface for interface KDIDataManager2._CDataManager failed.
at KDIDataManager2.CDataManagerClass.CheckConnection()
at JobCacheCleaner.JobCacheCleaner.InsertJobsDB(FileInfo[] arrFileInfos) in c:\code.net\jobcachecleaner\jobcachecleaner.c
В обоих программках использутся early binding с СОМ обьектом. Методы вызываются разные, но в принципе и тот и другой должны работать.
Какие будут советы?
Спасибо.
Problem with COM usage in .NET
-
- Уже с Приветом
- Posts: 358
- Joined: 20 May 2001 09:01
- Location: Урал --> Москва --> Midwest USA
-
- Уже с Приветом
- Posts: 518
- Joined: 04 Jun 2002 01:40
- Location: CA, USA
Possible reasons:
1. The service is running under an account with insufficient priveledges.
2. The service thread can't enter the STA apartment and cannot marshal the obj across apartments. I never wrote service in .net, but I would guess they use the MTA model, unlike WinForms that are always STA.
Possible solutions:
a) register the tlb on your server. This will allow marshaling across apartments.
b) make your service STA either by placing [STAThread] somewhere or setting Thread.CurrentThread.ApartmentState = STA.
If (b) works at all it should work faster than (a).
1. The service is running under an account with insufficient priveledges.
2. The service thread can't enter the STA apartment and cannot marshal the obj across apartments. I never wrote service in .net, but I would guess they use the MTA model, unlike WinForms that are always STA.
Possible solutions:
a) register the tlb on your server. This will allow marshaling across apartments.
b) make your service STA either by placing [STAThread] somewhere or setting Thread.CurrentThread.ApartmentState = STA.
If (b) works at all it should work faster than (a).
-
- Уже с Приветом
- Posts: 358
- Joined: 20 May 2001 09:01
- Location: Урал --> Москва --> Midwest USA
-
- Уже с Приветом
- Posts: 358
- Joined: 20 May 2001 09:01
- Location: Урал --> Москва --> Midwest USA
Попробовал вариант (б) - не работает.
Не знаю как быть с вариантом (а). СОМ обьект написан в VB6, там вроде бы tlb информация находится в самом обьекте. Не нужно иметь отдельный tlb file. Да и как его вытащить из VB6 СОМ DLL? Ну и другие программки как-то работают с этим обьектом без проблем. Но они все Windows Forms или ASP.NET....
Не знаю как быть короче. Просто hardcoded (как это по русски?) нужную информацию пока...
Не знаю как быть с вариантом (а). СОМ обьект написан в VB6, там вроде бы tlb информация находится в самом обьекте. Не нужно иметь отдельный tlb file. Да и как его вытащить из VB6 СОМ DLL? Ну и другие программки как-то работают с этим обьектом без проблем. Но они все Windows Forms или ASP.NET....
Не знаю как быть короче. Просто hardcoded (как это по русски?) нужную информацию пока...
-
- Уже с Приветом
- Posts: 518
- Joined: 04 Jun 2002 01:40
- Location: CA, USA
А как пробовали (б) - атрибутом или кодом?
Дело в том, что это дело надо устанавливать до того, как первый раз вызывается CoInitialize. А где он вызывается - никто не знает.
Я игрался с этим в WinForms. Там оно работает только когда навешен атрибут на Main(). (Visual Studio сама его навешивает).
Но раз вы говорите, что это VB obj, то проблема наверно не в этом.
Да, а когда вы его из ASP.Net вызываете, вы включаете ASPCompat, или как его там, атрибут в <@page>, который делает то же самое, что [STAThread]?
Если работает без этого атрибута, то проблема точно НЕ в threading.
Если работает с этим атрибутом, попробуйте его убрать. Если перестанет работать - проблема почти точно в threading.
Кстати, если работает и так и так, то надо его включить - будет быстрее работать
Если это не threading, то проверьте еще раз permissions.
Если обьект крутится в MTS - проверьте permissions и там.
Другие обьекты пробовали вызывать?
Дело в том, что это дело надо устанавливать до того, как первый раз вызывается CoInitialize. А где он вызывается - никто не знает.
Я игрался с этим в WinForms. Там оно работает только когда навешен атрибут на Main(). (Visual Studio сама его навешивает).
Но раз вы говорите, что это VB obj, то проблема наверно не в этом.
Да, а когда вы его из ASP.Net вызываете, вы включаете ASPCompat, или как его там, атрибут в <@page>, который делает то же самое, что [STAThread]?
Если работает без этого атрибута, то проблема точно НЕ в threading.
Если работает с этим атрибутом, попробуйте его убрать. Если перестанет работать - проблема почти точно в threading.
Кстати, если работает и так и так, то надо его включить - будет быстрее работать
Если это не threading, то проверьте еще раз permissions.
Если обьект крутится в MTS - проверьте permissions и там.
Другие обьекты пробовали вызывать?
-
- Уже с Приветом
- Posts: 107
- Joined: 25 Jun 1999 09:01
- Location: Russia
voron999 wrote:Попробовал вариант (б) - не работает.
А вариант в пп.1 by Bobo пробовал?
Сервис запускается с правами "LocalSystem", который не входит даже в "Everyone". Думаю, что проблема с правами доступа (кстати, никак нельзя получить код ошибки?), если простые приложения нормально работают. Попробуй запустить сервис, указав ему имя и пароль пользователя, под которым работает то самое Windows forms app.
-
- Уже с Приветом
- Posts: 107
- Joined: 25 Jun 1999 09:01
- Location: Russia
-
- Уже с Приветом
- Posts: 358
- Joined: 20 May 2001 09:01
- Location: Урал --> Москва --> Midwest USA
diam wrote: Попробуй запустить сервис, указав ему имя и пароль пользователя, под которым работает то самое Windows forms app.
Это проверено. Сервис работает под именем/паролем пользователя с самого начала. С permissions вроде все ОК. Это уже вошло в привычку после нескольких разов.
Также пробовал это:
Thread.CurrentThread.ApartmentState = STA прямо в том методе где обьект вызывается. Еще попробую прямо в Маин() вставить.
А куда [STAThread] вставить - так и не разобрался толком, честно говоря.
Будет время - попробую еще раз с "нитками" разобраться. ДоложУ.
Спасибо всем.
-
- Уже с Приветом
- Posts: 518
- Joined: 04 Jun 2002 01:40
- Location: CA, USA
-
- Уже с Приветом
- Posts: 358
- Joined: 20 May 2001 09:01
- Location: Урал --> Москва --> Midwest USA