2012-02-15 17 views
10

मेरे पास निम्नलिखित सी # प्रोजेक्ट लक्ष्यीकरण .NET 4.0 है जो एक स्रोत कोड फ़ाइल लेता है, इसे फ्लाई पर एक असेंबली में संकलित करता है और फिर उस असेंबली में निहित प्रकार के एक स्थिर विधि को निष्पादित करता है।एक डीबगर संलग्न होने पर फ्लाई पर संकलित सी # कोड क्यों काम नहीं करता है?

यह अपेक्षित कार्य करता है, जब तक कि मैं एक डीबगर संलग्न प्रोग्राम के साथ प्रोग्राम शुरू नहीं करता। उस स्थिति में मुझे xmlSerializer.Serialize(sw, family); पर कॉल पर एक अपवाद मिलता है, System.InvalidOperationException के अंदर System.TypeInitializationException के अंदर अधिक सटीक System.NullReferenceException

यदि मैं एक ही प्रोग्राम लेता हूं, तो परियोजना में स्रोत कोड फ़ाइल शामिल करें और इसे सीधे मुख्य प्रोग्राम असेंबली में संकलित करें, मुझे डिबगर संलग्न होने के बावजूद अपवाद नहीं मिलेगा।

कृपया ध्यान दें कि मेरी परियोजना फ्लाई पर संकलन करते समय सूचीबद्ध समान असेंबली का संदर्भ देती है।

फ्लाई पर संकलित कोड के लिए यह महत्वपूर्ण क्यों है कि डीबगर संलग्न है या नहीं? मैं क्या खो रहा हूँ?

मुख्य फ़ाइल Program.cs:

using System; 
using System.CodeDom.Compiler; 
using System.IO; 
using System.Reflection; 
using System.Linq; 

namespace DebugSerializeCompiler 
{ 
    class Program 
    { 
     static void Main() 
     { 
      if (!Environment.GetCommandLineArgs().Contains("Compile")) 
      { 
       DebugSerializeCompiler.SerializerTest.Run(); 
      } 
      else 
      { 
       Assembly assembly; 
       if (TryCompile("..\\..\\SerializerTest.cs", new[]{ "Microsoft.CSharp.dll", 
        "System.dll", "System.Core.dll", "System.Data.dll", "System.Xml.dll" }, 
        out assembly)) 
       { 
        Type type = assembly.GetType("DebugSerializeCompiler.SerializerTest"); 
        MethodInfo methodInfo = type.GetMethod("Run"); 
        methodInfo.Invoke(null, null); 
       } 
      } 
      Console.ReadKey(); 
     } 

     static bool TryCompile(string fileName, string[] referencedAssemblies, 
      out Assembly assembly) 
     { 
      bool result; 

      CodeDomProvider compiler = CodeDomProvider.CreateProvider("CSharp"); 
      var compilerparams = new CompilerParameters 
            { 
             GenerateExecutable = false, 
             GenerateInMemory = true 
            }; 
      foreach (var referencedAssembly in referencedAssemblies) 
      { 
       compilerparams.ReferencedAssemblies.Add(referencedAssembly); 
      } 

      using (var reader = new StreamReader(fileName)) 
      { 
       CompilerResults compilerResults = 
        compiler.CompileAssemblyFromSource(compilerparams, reader.ReadToEnd()); 
       assembly = compilerResults.CompiledAssembly; 
       result = !compilerResults.Errors.HasErrors; 
       if (!result) 
       { 
        Console.Out.WriteLine("Compiler Errors:"); 
        foreach (CompilerError error in compilerResults.Errors) 
        { 
         Console.Out.WriteLine("Position {0}.{1}: {2}", 
          error.Line, error.Column, error.ErrorText); 
        } 
       } 
      } 

      return result; 
     } 
    } 
} 

फ़ाइल अलग विधानसभा SerializerTest.cs में संकलित किया:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Xml.Serialization; 

namespace DebugSerializeCompiler 
{ 
    public class SerializerTest 
    { 
     public static void Run() 
     { 
      Console.WriteLine("Executing Run()"); 
      var family = new Family(); 
      var xmlSerializer = new XmlSerializer(typeof(Family)); 

      TextWriter sw = new StringWriter(); 
      try 
      { 
       if (sw == null) Console.WriteLine("sw == null"); 
       if (family == null) Console.WriteLine("family == null"); 
       if (xmlSerializer == null) Console.WriteLine("xmlSerializer == null"); 
       xmlSerializer.Serialize(sw, family); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Exception caught:"); 
       Console.WriteLine(e); 
      } 
      Console.WriteLine(sw); 
     } 
    } 

    [Serializable] 
    public class Family 
    { 
     public string LastName { get; set; } 

     public List<FamilyMember> FamilyMembers { get; set; } 
    } 

    [Serializable] 
    public class FamilyMember 
    { 
     public string FirstName { get; set; } 
    } 
} 

यह csproj विजुअल C# 2010 का उपयोग कर परियोजना को संकलित करने के लिए प्रयोग किया जाता फ़ाइल है एक्सप्रेस विंडोज 7 पर:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup> 
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> 
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform> 
    <ProductVersion>8.0.30703</ProductVersion> 
    <SchemaVersion>2.0</SchemaVersion> 
    <ProjectGuid>{7B8D2187-4C58-4310-AC69-9F87107C25AA}</ProjectGuid> 
    <OutputType>Exe</OutputType> 
    <AppDesignerFolder>Properties</AppDesignerFolder> 
    <RootNamespace>DebugSerializeCompiler</RootNamespace> 
    <AssemblyName>DebugSerializeCompiler</AssemblyName> 
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> 
    <TargetFrameworkProfile>Client</TargetFrameworkProfile> 
    <FileAlignment>512</FileAlignment> 
    </PropertyGroup> 
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> 
    <PlatformTarget>x86</PlatformTarget> 
    <DebugSymbols>true</DebugSymbols> 
    <DebugType>full</DebugType> 
    <Optimize>false</Optimize> 
    <OutputPath>bin\Debug\</OutputPath> 
    <DefineConstants>DEBUG;TRACE</DefineConstants> 
    <ErrorReport>prompt</ErrorReport> 
    <WarningLevel>4</WarningLevel> 
    </PropertyGroup> 
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> 
    <PlatformTarget>x86</PlatformTarget> 
    <DebugType>pdbonly</DebugType> 
    <Optimize>true</Optimize> 
    <OutputPath>bin\Release\</OutputPath> 
    <DefineConstants>TRACE</DefineConstants> 
    <ErrorReport>prompt</ErrorReport> 
    <WarningLevel>4</WarningLevel> 
    </PropertyGroup> 
    <ItemGroup> 
    <Reference Include="System" /> 
    <Reference Include="System.Core" /> 
    <Reference Include="Microsoft.CSharp" /> 
    <Reference Include="System.Data" /> 
    <Reference Include="System.Xml" /> 
    </ItemGroup> 
    <ItemGroup> 
    <Compile Include="Program.cs" /> 
    <Compile Include="Properties\AssemblyInfo.cs" /> 
    <Compile Include="SerializerTest.cs"> 
     <SubType>Code</SubType> 
    </Compile> 
    </ItemGroup> 
    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 
    <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
     Other similar extension points exist, see Microsoft.Common.targets. 
    <Target Name="BeforeBuild"> 
    </Target> 
    <Target Name="AfterBuild"> 
    </Target> 
    --> 
</Project> 
+0

तो कौन सा ऑब्जेक्ट शून्य है? –

+0

@Ramhound अच्छा सवाल है। निश्चित रूप से मेरी कोई भी वस्तु शून्य नहीं है। मैंने बस इसे स्पष्ट करने के लिए एक चेक जोड़ा। – PersonalNexus

+0

आप रोज़लिन पूर्वावलोकन का उपयोग करने का प्रयास कर सकते हैं और देख सकते हैं कि कोडडॉम की तुलना में आपके पास बेहतर भाग्य है या नहीं। ऐसे अन्य उपकरण भी हैं जो समान चीजें करते हैं, जैसे मोनो कंपाइलर एक सर्वर और एनआरफैक्ट्री के रूप में ... कोडेडॉम बहुत ज्यादा बेकार है। –

उत्तर

2

यह मेरे लिए ठीक काम करता है।

लेकिन अगर मुझे लगता है कि आपके लिए क्या चल रहा है, तो ऐसा होगा क्योंकि आप कक्षा को अपने मुख्य प्रोजेक्ट के साथ संकलित कर रहे हैं और गतिशील रूप से इसे संकलित कर रहे हैं, धारावाहिक इस बात से भ्रमित हो रहा है कि किस असेंबली का उपयोग करना है और असफल रहा है। आप AppDomain.CurrentDomain.AssemblyResolve पर किसी ईवेंट को अटैच करने का प्रयास कर सकते हैं और देख सकते हैं कि वहां कोई भी असेंबली हल करने में विफल रही है या नहीं।

+0

आप किस आईडीई और संस्करण का उपयोग कर रहे हैं? यह ढांचा संस्करण क्या है? मैं Win7 पर वीएस 2008 एसपी 1 का उपयोग कर रहा हूं और आपका कोड किसी भी समस्या के बिना संकलित चल रहा है। यह मेरे लिए डीबगर संलग्न के साथ या उसके बिना भी काम करता है। क्या आपके पास कोई एक्सटेंशन है, जैसे आर #? क्या आप .csproj फ़ाइल दिखा सकते हैं? इस परियोजना को संकलित करने के तरीके में आपके पास कुछ अजीब चल रहा हो सकता है। –

+0

यह है। 'AppDomain.CurrentAppDomain.AssemblyResolve' ईवेंट हैंडलर में मुझे फ्लाई पर संकलित असेंबली के लिए अनुरोध मिलता है, लेकिन केवल डीबगर के तहत चलते समय। जब मैं संकलन के बाद '_assembly' फ़ील्ड में असेंबली को सहेजता हूं और जब अनुरोध किया गया असेंबली का नाम इवेंट हैंडलर में संकलित असेंबली के नाम से मेल खाता है, तो यह डीबगर संलग्न के साथ भी काम करता है। मैं वास्तव में जानना चाहूंगा कि इससे कोई फर्क क्यों पड़ता है। – PersonalNexus

+0

यह .NET 4.0 है और मैंने इसे विजुअल स्टूडियो 2010 प्रीमियम के साथ-साथ विजुअल स्टूडियो 2010 एक्सप्रेस संस्करण (कोई एक्सटेंशन) के साथ मानक कंसोल एप्लिकेशन प्रोजेक्ट के साथ और किसी भी आईडीई या डीबगर सेटिंग्स में कोई बदलाव नहीं किया है। मैं प्रश्न में .csproj फ़ाइल शामिल करूंगा। – PersonalNexus

संबंधित मुद्दे