2013-12-11 74 views
1

在我的構建定義中,我需要一個所有編譯程序集的列表。這很簡單:如何排除本機DLL?

<CompiledAssemblies Include="$(OutDir)\MyCompany.*.dll" /> 

現在,如果我需要排除某些dll文件,我只想補充一個Exclude屬性。但我想更進一步:

如何從上面的CompiledAssemblies上排除所有原生 dll?

+0

您可能正在構建程序集,因此您將成爲知道的人。但是,[.NET程序集](http://msdn.microsoft.com/zh-cn/library/zst29sk2(v = vs.110).aspx)是一組帶有清單的文件,通常至少有一個。 NET模塊。通常,這就是全部文件。但是,將依賴的本地dll捆綁到依賴於它們的程序集中有時很方便。對於一般的解決方案,您必須列出所有文件作爲排除對象,枚舉所有清單並從排除列表中刪除引用的文件。 –

+0

我有一個只適用於.NET程序集的混淆步驟。捆綁原生DLL聽起來很有趣。 – l33t

回答

1

原理並不困難:列表上的批處理,找出哪些dll是本地的,並創建一個只有那些列表的新列表。

一個簡單的方法來檢查一個DLL是否是一個正確的程序集正在運行corflags:如果它返回0,它是一個程序集。或MSBuild的代碼(輸出redierected到NUL其他的MSBuild會以紅色顯示錯誤):

<ItemGroup> 
    <AllDlls Include="$(OutDir)\MyCompany.*.dll"/> 
</ItemGroup> 

<Target Name="RunCorFlags"> 
    <Exec Command="corflags.exe %(AllDlls.Identity) &gt; NUL" IgnoreExitCode="true"> 
    <Output TaskParameter="ExitCode" ItemName="CorFlagsErrorCode"/> 
    </Exec> 
</Target> 

所以,現在我們只需要排除這些dll針對CorFlagsErrorCode爲1。這應該是很容易的,但我的ATM由於CorFlagsErrorCode將包含1和0的列表,所以不管有多少條目在批處理時,它都只會運行兩次,因爲批處理會跳過重複的項目。不管怎麼樣,CodeTaskFactory也提供了一個解決方案:

<Target Name="GetAssemblies" DependsOnTargets="RunCorFlags"> 
    <GetAssembliesOnly Dlls="@(AllDlls)" CorFlagsErr="@(CorFlagsErrorCode)"> 
    <Output TaskParameter="Assemblies" ItemName="CompiledAssemblies"/> 
    </GetAssembliesOnly> 
    <Message Text="CompiledAssemblies = %(CompiledAssemblies.Identity)"/> 
</Target> 

<UsingTask TaskName="GetAssembliesOnly" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" > 
    <ParameterGroup> 
    <Dlls Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem[]"/> 
    <CorFlagsErr Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem[]"/> 
    <Assemblies Output="true" ParameterType="Microsoft.Build.Framework.ITaskItem[]"/> 
    </ParameterGroup> 
    <Task> 
    <Code Type="Fragment" Language="cs"> 
     <![CDATA[ 
var temp = new List<ITaskItem>(); 
for(int i = 0 ; i < Dlls.Length ; ++i) 
    if(CorFlagsErr[ i ].ItemSpec == "0") 
    temp.Add(Dlls[ i ]); 
Assemblies = temp.ToArray(); 
     ]]> 
    </Code> 
    </Task> 
</UsingTask> 
+0

優秀!謝謝! – l33t