Почему этот простой пример удаленного взаимодействия работает на моем ноутбуке, но не на моем рабочем столе?

Я пытался создать удаленный объект и получал ошибки, хотя казалось, что все в порядке, поэтому я решил упростить и запустить образец кода прямо из Microsoft (http://msdn.microsoft.com/en-us). /library/system.marshalbyrefobject.aspx).

Когда я запускаю этот код, я получаю TypeLoadException, когда он вызывает CreateInstanceAndUnwrap(). Тем не менее, я только что попробовал это на своем ноутбуке, и он работал нормально. Кто-нибудь знает, почему это будет работать на ноутбуке, но не на рабочем столе?? Я только что создал консольное приложение для каждого и скопировал/вставил приведенный ниже код, поэтому я не понимаю, чем они отличаются друг от друга.

using System;
using System.Reflection;

public class Worker : MarshalByRefObject
{
    public void PrintDomain() 
    { 
        Console.WriteLine("Object is executing in AppDomain \"{0}\"",
            AppDomain.CurrentDomain.FriendlyName); 
    }
}

class Example
{
    public static void Main()
    {
        // Create an ordinary instance in the current AppDomain
        Worker localWorker = new Worker();
        localWorker.PrintDomain();

        // Create a new application domain, create an instance 
        // of Worker in the application domain, and execute code 
        // there.
        AppDomain ad = AppDomain.CreateDomain("New domain");
        Worker remoteWorker = (Worker) ad.CreateInstanceAndUnwrap(
            Assembly.GetExecutingAssembly().FullName,
            "Worker");
        remoteWorker.PrintDomain();
    }
}

РЕДАКТИРОВАТЬ: Итак, я только что попытался создать экземпляр типа с помощью Activator в локальном домене, и даже это дало мне ошибку, говорящую о том, что он не может загрузить файл или сборку «System.RuntimeType» или одну из его зависимостей. Видя, что это внутренний тип для .Net Framework, который я не мог бы предотвратить его развертывание, даже если бы захотел, я сейчас совершенно сбит с толку.

РЕДАКТИРОВАТЬ: нет InnerException, но вот стек:

   at System.Reflection.RuntimeAssembly.GetType(RuntimeAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type)
   at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
   at System.Activator.CreateInstance(String assemblyName, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(String assemblyName, String typeName)
   at System.AppDomain.CreateInstance(String assemblyName, String typeName)
   at System.AppDomain.CreateInstance(String assemblyName, String typeName)
   at ConsoleApplication1.Example.Main(String[] args) in D:\Projects\Remoting\ConsoleApplication1\Program.cs:line 28
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

О, и исключение гласит:

{"Could not load type 'Worker' from assembly 'ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.":"Worker"}

Кроме того, я попытался запустить эту строку кода:

var w = Activator.CreateInstance(typeof(Worker).GetType().FullName, "Worker");

и получил FileNotFoundException:

Could not load file or assembly 'System.RuntimeType' or one of its dependencies.  The system cannot find the file specified.

person Brandon Moore    schedule 19.01.2013    source источник
comment
@HansPassant Нет InnerException, иначе я бы точно опубликовал это. И я понятия не имею, что делать со стеком, поэтому я не думал о его публикации, но, надеюсь, вы сможете увидеть там что-то полезное.   -  person Brandon Moore    schedule 19.01.2013
comment
@HansPassant Да, они оба в клиентском профиле Framework 4.   -  person Brandon Moore    schedule 19.01.2013
comment
@HansPassant Даже когда я просто пытаюсь использовать активатор в локальном домене, он вылетает (как было отмечено в последнем обновлении моего поста)   -  person Brandon Moore    schedule 19.01.2013
comment
@HansPassant Да, поверьте мне, я всегда был парнем, который задавал вопросы, которые учитель не мог понять. Вы правы в том, что «: Worker» не является частью исключения, но когда вы нажимаете «Просмотреть подробности» во всплывающем помощнике по исключению и копируете его оттуда, как я, он добавляет это. И я так же невежественен, как и вы, о том, что, черт возьми, System.RuntimeType там делает, но он там, и поэтому я здесь:/ Я не знаю, что такое Fuslogvw.exe, но я узнаю и опубликую это скоро.   -  person Brandon Moore    schedule 19.01.2013
comment
@HansPassant Я не вижу никаких настроек для «присоединения» средства просмотра журнала привязки сборки к моему приложению, поэтому мое первое предположение состоит в том, что оно имеет какой-то глобальный хук и показывает все, но в нем нет записей даже после запуска моего приложения в отладчике. Я все еще изучаю этот инструмент, поэтому, возможно, я еще не настроил его правильно.   -  person Brandon Moore    schedule 19.01.2013


Ответы (1)


В исходном коде вы пытаетесь создать экземпляр неполного имени типа, и этот код нигде не должен работать, если у Worker нет пространства имен. Так должно быть:

var workerType = typeof(Worker);
Worker remoteWorker = (Worker) ad.CreateInstanceAndUnwrap(
            // Where Worker is defined (probably the same as current assembly in you case)
            workerType.Assembly.FullName,
            // Worker's *fully-qualified* typename, including the namespace 
            workerType.FullName); 

Ваш локальный код активации ошибочно вызывает typeof(Worker).GetType().FullName, а не typeof(Worker).FullName.

typeof(Anything).GetType() всегда будет возвращать System.RuntimeType

person jlew    schedule 19.01.2013
comment
Итак, активация была отвлекающим маневром, потому что я ошибся. Однако первоначальный код взят прямо с веб-сайта Microsoft (по ссылке в моем посте), и он определенно работает так, как написано на моем ноутбуке, но не на моем рабочем столе. Хотел бы я знать, почему это так, но код, который вы здесь предоставили, определенно работает, поэтому, думаю, я не могу жаловаться :) - person Brandon Moore; 19.01.2013
comment
Образец кода MS не имеет пространств имен, могу поспорить, что ваш класс Worker в какой-то момент был помещен в пространство имен и перестал работать, а переключение на другую машину было случайным. Возможный? Отсутствие FullName не имело бы значения, если бы не было пространства имен. - person jlew; 19.01.2013
comment
Я просто использовал шаблон консольного приложения по умолчанию, и определенно есть пространство имен. Я не думаю, что он даже скомпилировался бы, если бы не был в пространстве имен, не так ли? - person Brandon Moore; 19.01.2013
comment
Да, он будет скомпилирован (пример кода на msdn и то, что вы вставили, не имеют пространств имен.) Если нет явного пространства имен, код помещается в пространство имен global:: и не требует квалификации, если нет конфликта с другим пространством имен. . - person jlew; 19.01.2013
comment
Ой, вы абсолютно правы :) Я только что вернулся и проверил свой ноутбук, и когда я копировал / вставлял туда, я контролировал-а, прежде чем вставлять, но на рабочем столе я не сдул пространство имен. - person Brandon Moore; 19.01.2013