빌드의 일부로 Xml 직렬화 어셈블리 생성
이 코드는 FileNotFoundException을 생성하지만 최종적으로는 문제없이 실행됩니다.
void ReadXml()
{
XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
//...
}
여기 예외가 있습니다.
'System' 유형의 첫 번째 기회 예외입니다.mscorlib.dll에서 'IO.FileNotFoundException'이(가) 발생했습니다.
추가 정보:'MyAssembly' 파일 또는 어셈블리를 로드할 수 없습니다.Xml Serializer, 버전=1.4.3190.15950, Culture=neutral, PublicKeyToken= null' 또는 해당 종속성 중 하나입니다.지정한 파일을 찾을 수 없습니다.
프레임워크가 발견되지 않으면 자동으로 직렬화 어셈블리를 생성하는 것으로 보입니다.sgen.exe를 사용하여 수동으로 생성할 수 있어 예외를 완화합니다.
시각 스튜디오에서 XML Serialization 어셈블리를 자동으로 생성하려면 어떻게 해야 합니까?
업데이트: 직렬화 어셈블리 생성:설정에서 아무 것도 하지 않는 것 같습니다.
마틴이 답변에서 설명한 것처럼 프로젝트 속성을 통해 직렬화 어셈블리의 생성을 켜는 것은 SGen 작업이 추가되고 있기 때문에 충분하지 않습니다./proxytypes
sgen으로 전환합니다.exe 명령행입니다.
Microsoft는 문서화된 MSBuild 속성을 가지고 있으며 이 속성을 사용하지 않도록 설정할 수 있습니다./proxytypes
switch를 실행하면 어셈블리에 프록시 유형이 없더라도 SGen Task에서 직렬화 어셈블리를 생성합니다.
SGenUse프록시 유형
SGen.exe에서 프록시 유형을 생성해야 하는지 여부를 나타내는 부울 값입니다.SGen 대상은 이 속성을 사용하여 UseProxyTypes 플래그를 설정합니다.이 속성은 true로 기본 설정되며 이를 변경할 UI가 없습니다.웹 서비스가 아닌 유형에 대한 직렬화 어셈블리를 생성하려면 이 속성을 프로젝트 파일에 추가하고 Microsoft를 가져오기 전에 false로 설정합니다.흔한.대상 또는 C#/VB.대상
문서에서 알 수 있듯이 프로젝트 파일을 수작업으로 수정해야 하지만 추가할 수 있습니다.SGenUseProxyTypes
생성이 가능하도록 구성에 속성을 지정합니다.프로젝트 파일 구성은 결국 다음과 같은 모양을(를)
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<!-- Snip... -->
<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
<SGenUseProxyTypes>false</SGenUseProxyTypes>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<!-- Snip... -->
<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
<SGenUseProxyTypes>false</SGenUseProxyTypes>
</PropertyGroup>
이것이 제가 제 안에 있는 MSBUILD 스크립트를 수정해서 할 수 있었던 방법입니다.CSPROJ 파일:
먼저, 당신의 것을 엽니다.프로젝트가 아닌 파일로 CSPROJ 파일.프로젝트 태그가 닫히기 직전에 주석이 달린 코드를 찾을 때까지 파일 맨 아래로 스크롤합니다.
<!-- 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>
-->
이제 AfterBuild 대상을 삽입하여 기존 XmlSerializer를 삭제하고 SGen을 우리 고유의 것으로 삭제합니다.
<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)">
<!-- Delete the file because I can't figure out how to force the SGen task. -->
<Delete
Files="$(TargetDir)$(TargetName).XmlSerializers.dll"
ContinueOnError="true" />
<SGen
BuildAssemblyName="$(TargetFileName)"
BuildAssemblyPath="$(OutputPath)"
References="@(ReferencePath)"
ShouldGenerateSerializer="true"
UseProxyTypes="false"
KeyContainer="$(KeyContainerName)"
KeyFile="$(KeyOriginatorFile)"
DelaySign="$(DelaySign)"
ToolPath="$(TargetFrameworkSDKToolsDirectory)"
Platform="$(Platform)">
<Output
TaskParameter="SerializationAssembly"
ItemName="SerializationAssembly" />
</SGen>
</Target>
저는 그것이 좋습니다.
이 질문에 대한 다른 답변에서는 프로젝트 속성->빌드->직렬화 어셈블리 생성 설정에 대해 이미 언급했지만, 기본적으로 프로젝트에 "XML 웹 서비스 프록시 유형"이 있는 경우에만 어셈블리를 생성합니다.
Visual Studio의 정확한 동작을 이해하는 가장 좋은 방법은 C:\ 내에서 Generate Serialization Assembly 대상을 조사하는 것입니다.WINDOWS\Microsoft.NET\Framework\v2.0.50727**Microsoft.Common.targets** 파일입니다.
Visual Studio Output 창에서 이 빌드 작업의 결과를 확인하고 Show output from: 드롭다운 상자에서 Build를 선택할 수 있습니다.당신은 뭔가를 볼 수 있을 겁니다.
C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\bin\sgen.exe/assembly:D:\Temp\LibraryA\obj\Debug\LibraryA.dll /proxytypes /reference:../compiler:/delaysign - 라이브러리 A -> D:\Temp\LibraryA\bin\Debug\Library A.dll
여기서 핵심은 /proxytype 스위치입니다.XML Serializer Generator Tool(Sgen.exe)의 다양한 스위치에 대해 읽을 수 있습니다.
MSBuild에 익숙한 경우 GenerateSerializationAssemblys 대상을 사용자 지정하여 SGen 작업이 참이 아닌 UseProxyTypes="false" 속성을 갖도록 할 수 있지만 Visual Studio/MSBuild 시스템 사용자 지정과 관련된 모든 책임을 져야 합니다.또는 빌드 프로세스를 확장하여 /proxytype 스위치 없이 수동으로 SGen을 호출할 수도 있습니다.
SGen에 대한 설명서를 읽어보면 Microsoft가 이 기능의 사용을 제한하고자 했다는 것을 알 수 있습니다.이 주제에 대한 잡음의 양을 고려할 때, Microsoft가 비주얼 스튜디오 경험을 문서화하는 데 큰 역할을 하지 못했다는 것은 분명합니다.이 문제에 대한 피드백 연결 항목도 있는데 반응이 좋지 않습니다.
새 sgen 작업 정의를 생성하면 파리가 깨집니다.필요한 변수를 설정하여 작업이 의도한 대로 작동되도록 합니다.어쨌든 마이크로소프트 문서에는 중요한 정보가 몇 가지 부족합니다.
직렬화 어셈블리를 생성하기 위한 단계
(http://msdn.microsoft.com/en-us/library/ff798449.aspx) 의 일부와 함께)
- Visual Studio 2010의 솔루션 탐색기에서 직렬화 어셈블리를 생성할 프로젝트를 마우스 오른쪽 버튼으로 누른 다음 프로젝트 언로드를 누르십시오.
- 솔루션 탐색기에서 직렬화 어셈블리를 생성할 프로젝트를 마우스 오른쪽 버튼으로 누른 다음 편집 .csproj를 누르십시오.
.csproj 파일에서, 그 직후에
<TargetFrameworkVersion>v?.?</TargetFrameworkVersion>
element, 다음 element를 추가합니다.<SGenUseProxyTypes>false</SGenUseProxyTypes>
<SGenPlatformTarget>$(Platform)</SGenPlatformTarget>
.csproj 파일에서, 각 플랫폼 구성에서
예.
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
다음 행을 추가합니다.
<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
.csproj 파일을 저장하고 닫습니다.
- 솔루션 탐색기에서 방금 편집한 프로젝트를 마우스 오른쪽 단추로 클릭한 다음 프로젝트 다시 로드를 클릭합니다.
이 절차에서는 출력 폴더에 .xmlSerializers.dll이라는 이름의 어셈블리를 추가로 생성합니다.솔루션과 함께 이 어셈블리를 배포해야 합니다.
설명.
프록시 유형에 대한 SGen은 기본적으로 "모든 CPU"에 대해 생성됩니다.프로젝트 파일에 해당 변수를 설정하지 않으면 이 문제가 발생합니다.
SGenPlatformTarget은 PlatformTarget과 일치해야 합니다.저는 이것이 프로젝트 템플릿의 버그라고 생각하는 경향이 있습니다.sgen target 플랫폼이 프로젝트 플랫폼과 다른 이유는 무엇입니까?그러면 런타임 예외가 발생합니다.
0x80131040:위치한 어셈블리의 매니페스트 정의가 어셈블리 참조와 일치하지 않습니다.
프로젝트 파일을 분석하여 msbuild 작업 정의를 찾을 수 있습니다.
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
여기서 MSBuildToolsPath는 사용자의<TargetFrameworkVersion>
http://msdn.microsoft.com/en-us/library/bb397428.aspx
TargetFrameworkVersion 4.0에 대한 SGen 작업 정의 내부를 확인합니다.
Windows 설치 경로\Microsoft.NET\Framework\v4.0.30319\Microsoft.CS샤프타겟
프로젝트 파일에서 자유롭게 설정할 수 있는 $(SGenPlatformTarget)과 같은 문서화되지 않은 변수를 보려면
<Target
Name="GenerateSerializationAssemblies"
Condition="'$(_SGenGenerateSerializationAssembliesConfig)' == 'On' or ('@(WebReferenceUrl)'!='' and '$(_SGenGenerateSerializationAssembliesConfig)' == 'Auto')"
DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource"
Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"
Outputs="$(IntermediateOutputPath)$(_SGenDllName)">
<SGen
BuildAssemblyName="$(TargetFileName)"
BuildAssemblyPath="$(IntermediateOutputPath)"
References="@(ReferencePath)"
ShouldGenerateSerializer="$(SGenShouldGenerateSerializer)"
UseProxyTypes="$(SGenUseProxyTypes)"
KeyContainer="$(KeyContainerName)"
KeyFile="$(KeyOriginatorFile)"
DelaySign="$(DelaySign)"
ToolPath="$(SGenToolPath)"
SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)"
EnvironmentVariables="$(SGenEnvironment)"
SerializationAssembly="$(IntermediateOutputPath)$(_SGenDllName)"
Platform="$(SGenPlatformTarget)"
Types="$(SGenSerializationTypes)">
<Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly"/>
</SGen>
</Target>
이전에 모든 것이 정상적으로 작동한 후에 다른 사람이 갑자기 이 문제에 직면한 경우:제 경우에는 옵션 메뉴(옵션 -> 디버깅)에서 "Enable Just My Code (Managed Only)" 확인란을 선택 해제하는 것과 관련이 있었습니다(설치 후 자동으로 꺼짐).NET Reflector).
편집: 물론 이 예외는 이전에도 발생했지만 "내 코드만 활성화"가 해제되면 디버깅 어시스턴트(활성화된 경우)가 이 시점에서 중지됩니다.
파티에 좀 늦었지만, 이전 답변은 같이 하기가 어려웠습니다.특히 비주얼 스튜디오는 프로젝트의 속성을 보려고 할 때마다 충돌합니다.이것은 csproj 파일을 읽는 방법을 더 이상 이해하지 못했기 때문이라고 생각합니다.그럼요...
빌드 후 이벤트 명령줄에 다음을 추가합니다.
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\sgen.exe" "$(TargetPath)" /force
이렇게 하면 디버그 또는 릴리스용 프로젝트를 빌드할 때마다 sgen.exe를 직접 사용하여 Xml Serialization 어셈블리를 재구성할 수 있습니다.
용액의 속성을 조사합니다.하단의 빌드 탭에는 "직렬화 어셈블리 생성"이라는 드롭다운이 있습니다.
Brain backup에서 제공하는 솔루션과 약간 다른 솔루션은 플랫폼을 사용해야 하는 위치를 직접 지정하는 것입니다.
<!-- Check the platform target value and if present use that for a correct *.XmlSerializer.dll platform setup (default is MSIL)-->
<PropertyGroup Condition=" '$(PlatformTarget)'=='' ">
<SGenPlatform>$(Platform)</SGenPlatform>
</PropertyGroup>
<PropertyGroup Condition=" '$(PlatformTarget)'!='' ">
<SGenPlatform>$(PlatformTarget)</SGenPlatform>
</PropertyGroup>
<!-- Delete the file because I can't figure out how to force the SGen task. -->
<Delete Files="$(TargetDir)$(TargetName).XmlSerializers.dll" ContinueOnError="true" />
<SGen
BuildAssemblyName="$(TargetFileName)"
BuildAssemblyPath="$(OutputPath)"
References="@(ReferencePath)"
ShouldGenerateSerializer="true"
UseProxyTypes="false"
KeyContainer="$(KeyContainerName)"
KeyFile="$(KeyOriginatorFile)"
DelaySign="$(DelaySign)"
ToolPath="$(SGenToolPath)"
SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)"
EnvironmentVariables="$(SGenEnvironment)"
Platform="$(SGenPlatform)">
<Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
</SGen>
누구든지 그렇게 하는 것에 관심이 있습니다.NET Core - MS 문서 https://learn.microsoft.com/en-us/dotnet/core/additional-tools/xml-serializer-generator 을 참조하십시오.
기본적으로, 당신의 프로젝트에 nuget 패키지 하나만 추가하면 됩니다.
언급URL : https://stackoverflow.com/questions/134224/generating-an-xml-serialization-assembly-as-part-of-my-build
'programing' 카테고리의 다른 글
Google CDN의 최신 jQuery 버전 (0) | 2023.11.06 |
---|---|
생성된 저장 프로시저 실패 (0) | 2023.11.06 |
Oracle: 조건을 포함한 전체 텍스트 검색 (0) | 2023.11.06 |
Wildfly 및 자동으로 데이터베이스에 다시 연결 (0) | 2023.11.06 |
javascript code 실행 전에 javascript 파일이 모두 로딩될 때까지 기다리는 것이 가능합니까? (0) | 2023.11.06 |