Здравствуйте, mrozov, Вы писали:
M>Давненько я этим не занимался, отвечаю по памяти.
M>1. У тебя в данном случае (по меньшей мере, если речь идет о com-приложении, а не библиотеке) и должен быть MarshalByRefObject. Приводиться он должен к интерфейсу (ты ведь определил интерфейс и назначил ему Guid, правда?).
M>2. В настройках COM+ приложения есть рабочая папка, которую можно задать.
Оказалось первая проблема — следствие второй. Вот тестовый пример.
Компонент.
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.EnterpriseServices;
using System.Reflection;
using System.Runtime.Remoting;
using Reference;
using System.IO;
[assembly: ComVisible(true)]
[assembly: Guid("640468B8-2988-4539-B8BA-7C3ED04EB5A8")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationAccessControl(false)]
namespace ComPlusComponent
{
#if(!TEST1)
[ComVisible(true)]
[Guid("406FFB62-DC77-47AE-8C78-A31F9DA50F57")]
[ProgId("ComPlusComponent.1")]
[ClassInterface(ClassInterfaceType.None)]
#endif
public class ComPlusComponentClass
#if(!TEST1)
: ServicedComponent
#endif
{
public ComPlusComponentClass()
{
}
static void Log(string message)
{
using (StreamWriter sw = new StreamWriter("c:\\ComPlusComponent.log", true))
sw.WriteLine(message);
}
static ComPlusComponentClass()
{
#if(TEST1)
Log("Test1");
#endif
#if(TEST2)
Log("Test2");
#endif
#if(TEST3)
Log("Test3");
#endif
#if(TEST4)
Log("Test4");
#endif
try
{
#if(TEST1)
Log(AppDomain.CurrentDomain.BaseDirectory);
AppDomain domain = AppDomain.CreateDomain("Second Domain");
ObjectHandle handle = domain.CreateInstanceFrom("Reference.dll", "Reference.ReferenceClass");
ReferenceClass refer = (ReferenceClass)handle.Unwrap();
refer.Init();
#endif
#if(TEST2)
Log(AppDomain.CurrentDomain.BaseDirectory);
AppDomain domain = AppDomain.CreateDomain("Second Domain");
ObjectHandle handle = domain.CreateInstanceFrom("Reference.dll", "Reference.ReferenceClass");
ReferenceClass refer = (ReferenceClass)handle.Unwrap();
refer.Init();
#endif
#if(TEST3)
Log(AppDomain.CurrentDomain.BaseDirectory);
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = new FileInfo(typeof(ComPlusComponentClass).Assembly.Location).DirectoryName;
AppDomain domain = AppDomain.CreateDomain("Second Domain", null, setup);
ObjectHandle handle = domain.CreateInstanceFrom
( "Reference.dll"
, "Reference.ReferenceClass");
object obj = handle.Unwrap();
Log(obj.GetType().ToString());
ReferenceClass refer = (ReferenceClass)obj;
refer.Init();
#endif
#if(TEST4)
Log(AppDomain.CurrentDomain.BaseDirectory);
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = new FileInfo(typeof(ComPlusComponentClass).Assembly.Location).DirectoryName;
Log(setup.ApplicationBase);
AppDomain domain = AppDomain.CreateDomain("Second Domain", null, setup);
ObjectHandle handle = domain.CreateInstanceFrom
( Path.Combine(setup.ApplicationBase, "Reference.dll")
, "Reference.ReferenceClass");
object obj = handle.Unwrap();
Log(obj.GetType().ToString());
ReferenceClass refer = (ReferenceClass)obj;
refer.Init();
#endif
}
catch (Exception ex)
{
Log(ex.GetType().ToString());
Log(ex.Message);
}
}
}
}
Сборка от которой зависит комопнент
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace Reference
{
public class ReferenceClass
: MarshalByRefObject
{
public ReferenceClass()
{
}
private void Log(string message)
{
using (StreamWriter sw = new StreamWriter("c:\\ComPlusComponent.log", true))
sw.WriteLine(message);
}
public void Init()
{
Log("Init Called");
}
}
}
Тестовый проект.
using System;
using System.Collections.Generic;
using System.Text;
using ComPlusComponent;
namespace Test
{
class Program
{
static void Main(string[] args)
{
ComPlusComponentClass c = new ComPlusComponentClass();
}
}
}
Вот результаты.
Test1
Z:\Tries\TryComPlus\Test\bin\Debug\
Init Called
Test2
C:\WINDOWS\system32\
System.IO.FileNotFoundException
Could not load file or assembly '
file:///C:\WINDOWS\system32\Reference.dll' or one of its dependencies. Не удается найти указанный файл.
Здесь вставляем путь к Com-dll в Службы компонентов->ComPlusComponent->Активизация->Корневая папка приложения
Test2
C:\WINDOWS\system32\
System.IO.FileNotFoundException
Could not load file or assembly '
file:///C:\WINDOWS\system32\Reference.dll' or one of its dependencies. Не удается найти указанный файл.
Test3
C:\WINDOWS\system32\
System.IO.FileNotFoundException
Could not load file or assembly '
file:///C:\WINDOWS\system32\Reference.dll' or one of its dependencies. Не удается найти указанный файл.
Test4
C:\WINDOWS\system32\
Z:\Tries\TryComPlus\Test\bin\Debug
System.MarshalByRefObject
System.InvalidCastException
Unable to cast transparent proxy to type 'Reference.ReferenceClass'
Переписываем Reference.dll в System32
Test2
C:\WINDOWS\system32\
Init Called
Test3
C:\WINDOWS\system32\
Reference.ReferenceClass
Init Called
Test4
C:\WINDOWS\system32\
Z:\Tries\TryComPlus\Test\bin\Debug
Reference.ReferenceClass
Init Called
Где копать?