Comments
15 comments
-
Where did you set mandatorypath to?
-
I've tried:
- C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5
- C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1
If I set the mandatory path for the dll that get's merged it doesn't recognize the dll anymore so it has to be set on the main assembly. -
Ok, thanks.
This is basically an error in how we resolve the assembly- if you point the mandatorypath to:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib
That should now work as its the *real* assembly. -
Chris.Allen wrote:Ok, thanks.
This is basically an error in how we resolve the assembly- if you point the mandatorypath to:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib
That should now work as its the *real* assembly.
Unfortunately that doesn't make a difference. -
Can you open the mscorlib that you're pointing to in reflector and search for:
Name: System.Runtime.InteropServices.Marshal
If its not there- that at least explains why the error hasn't gone away and we'll have to work out how to point to the right mscorlib. If it is there, we need to work out how to get SA to find it.
Reflector is available as a free trial download from our website. -
The function is there but it still won't obfuscate, something that I notice is that even though I point it to the right path it keeps mentioning "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\mscorlib.dll" instead of the mandatorypath I supply
-
Can you paste in your full smartassembly project file please- I can test here with a simulation based on your project. I can debug with full source code.
-
I have made a test project with a single dll with a single class:using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ClassLibrary1
{
public class ExtendedTabControl : TabControl
{
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x1300 + 40)
{
Rect rc = (Rect)m.GetLParam(typeof(Rect));
rc.Left -= 4;
rc.Right += 4;
rc.Top -= 1;
rc.Bottom += 2;
Marshal.StructureToPtr(rc, m.LParam, true);
}
base.WndProc(ref m);
}
}
internal struct Rect
{
public int Left, Top, Right, Bottom;
}
}
With the corresponding saproject, I can supply the complete project if requested.<SmartAssemblyProject ProjectId="{99790642-89e1-4fc1-828e-b76c9e148872}" Version="2.0">
<MainAssemblyFileName>.\WindowsFormsApplication1\bin\Release\WindowsFormsApplication1.exe</MainAssemblyFileName>
<Configuration Name="Release">
<Options>
<ExceptionReporting Template="res:{SmartExceptions}.1033.dll" />
<FeatureUsageReporting Template="res:SmartUsageWithUIConsentFirstRun1033.dll" />
<StringsEncoding Compress="1" Encode="1" UseImprovedEncoding="1" />
<StrongNameSigning />
<OtherOptimizations SealClasses="1" />
<Obfuscation ChangeMethodParent="1" FieldsNameMangling="3" NameMangling="3" />
<OtherProtections SuppressIldasm="1" />
<Debugging />
</Options>
<ApplicationName />
<Destination DestinationFileName=".\WindowsFormsApplication1.exe" />
<Assemblies>
<Assembly AssemblyName="WindowsFormsApplication1, Culture=neutral, PublicKeyToken=null">
<Merging>
<ResourcesCompression />
<MemberRefsProxy Proxy="1" />
<Pruning Prune="1">
<Exclusion />
</Pruning>
<Obfuscation Obfuscate="1">
<Exclusion />
</Obfuscation>
<ControlFlow Obfuscate="1" ObfuscationLevel="4" />
</Merging>
<Embedding />
</Assembly>
<Assembly AssemblyName="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<Merging />
</Assembly>
<Assembly AssemblyName="mscorlib, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<Merging />
</Assembly>
<Assembly AssemblyName="System.Drawing, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Merging />
</Assembly>
<Assembly AssemblyName="System.Security, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Merging />
</Assembly>
<Assembly AssemblyName="System, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<Merging />
</Assembly>
<Assembly AssemblyName="Accessibility, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Merging />
</Assembly>
<Assembly AssemblyName="System.Configuration, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Merging />
</Assembly>
<Assembly AssemblyName="System.Xml, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<Merging />
</Assembly>
<Assembly AssemblyName="System.Deployment, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Merging />
</Assembly>
<Assembly AssemblyName="System.Core, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<Merging />
</Assembly>
<Assembly AssemblyName="System.Runtime.Serialization.Formatters.Soap, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Merging />
</Assembly>
<Assembly AssemblyName="System.Data.SqlXml, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<Merging />
</Assembly>
<Assembly AssemblyName="System.Numerics, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<Merging />
</Assembly>
<Assembly AssemblyName="SmartAssembly.StringsEncoding, Culture=neutral, PublicKeyToken=7f465a1c156d4d57">
<Merging>
<Pruning>
<Exclusion />
</Pruning>
<Obfuscation>
<Exclusion />
</Obfuscation>
</Merging>
</Assembly>
<Assembly AssemblyName="SmartAssembly.Zip, Culture=neutral, PublicKeyToken=7f465a1c156d4d57">
<Merging>
<Pruning>
<Exclusion />
</Pruning>
<Obfuscation>
<Exclusion />
</Obfuscation>
</Merging>
</Assembly>
<Assembly AssemblyName="SmartAssembly.HouseOfCards, Culture=neutral, PublicKeyToken=7f465a1c156d4d57">
<Merging>
<Obfuscation>
<Exclusion />
</Obfuscation>
</Merging>
</Assembly>
<Assembly AssemblyName="ClassLibrary1, Culture=neutral, PublicKeyToken=null">
<Merging Merge="1">
<Pruning Prune="1">
<Exclusion />
</Pruning>
<Obfuscation Obfuscate="1">
<Exclusion />
</Obfuscation>
<ControlFlow Obfuscate="1" ObfuscationLevel="4" />
<MemberRefsProxy Proxy="1" />
<ResourcesCompression />
</Merging>
<Embedding />
</Assembly>
</Assemblies>
</Configuration>
</SmartAssemblyProject> -
Please change the line:
<Assembly AssemblyName="mscorlib, Culture=neutral, PublicKeyToken=b77a5c561934e089">
to:
<Assembly AssemblyName="mscorlib, Culture=neutral, PublicKeyToken=b77a5c561934e089" mandatorypath="C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib "> -
Chris.Allen wrote:Please change the line:
<Assembly AssemblyName="mscorlib, Culture=neutral, PublicKeyToken=b77a5c561934e089">
to:
<Assembly AssemblyName="mscorlib, Culture=neutral, PublicKeyToken=b77a5c561934e089" mandatorypath="C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib ">
Still the same error. -
Righto- thanks. So we can narrow this down to assembly resolution which is always the most common problem with the product. Is your SA in debug mode? If not, below is the smartassemlby.exe.config file for setting it in debug mode. This will create smartassembly.log in current directory assuming the process has write permissions. The logfile will tell us exactly where SA is picking up its mscorlib from. If it doesn't match the correct version, we'll need to update the path; if it does, we're looking at some caching problem (SA does cache references sometimes).
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net, Version=1.2.11.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a"/>
</configSections>
<startup>
<supportedRuntime version="v2.0.50727" sku="client"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/>
</startup>
<log4net>
<appender name="TraceLogger" type="log4net.Appender.FileAppender">
<file value="SmartAssembly.log" />
<appendToFile value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-7level %logger: %message%newline%exception" />
</layout>
</appender>
<root>
<level value="TRACE"/>
<appender-ref ref="TraceLogger" />
</root>
</log4net>
</configuration> -
Good news, finally. I have a solution. I apologise how long it took (its a two-part solution which partly explains the complexity).
1.MandatoryPath="C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll"
It seems necessary to point to the full physical location of the real mscorlib. This can be found using, for example, Reflector (open it up in, for example, C:\Windows\Microsoft.NET\Framework\v4.0.30319\) and look at the bottom left window- reflector tells you the full physical location)
2. Smartassembly has a tendency to cache the settings file so one workaround I use is to copy the full install path:
C:\Program Files\Red Gate\SmartAssembly 6\*.*
and put it somewhere convenient, such as your desktop, the just run it form this new path- it re-reads all files.
This has been tested extensively. If you still get problems, please let me know which step and send new smartassembly debug log. -
Chris.Allen wrote:Good news, finally. I have a solution. I apologise how long it took (its a two-part solution which partly explains the complexity).
1.MandatoryPath="C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll"
It seems necessary to point to the full physical location of the real mscorlib. This can be found using, for example, Reflector (open it up in, for example, C:\Windows\Microsoft.NET\Framework\v4.0.30319\) and look at the bottom left window- reflector tells you the full physical location)
2. Smartassembly has a tendency to cache the settings file so one workaround I use is to copy the full install path:
C:\Program Files\Red Gate\SmartAssembly 6\*.*
and put it somewhere convenient, such as your desktop, the just run it form this new path- it re-reads all files.
This has been tested extensively. If you still get problems, please let me know which step and send new smartassembly debug log.
This solution works until the application references mscorlib 2 and 4 if you reference an dotnet 2 dll. Unfortunately I can't get a debug for some reason. -
I encountered the same problem. I upgraded from .NET 4.0 to .NET 4.5.2. Even with the MandatoryPath set, I can't get it to work. The reason is that some assembly is referring to .NET 2.0:
2014-10-16 16:09:02,642 DEBUG SmartAssembly.AssemblyReader: Resolved assembly {mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e} to C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.5mscorlib.dll 2014-10-16 16:09:08,401 DEBUG SmartAssembly.AssemblyReader: Using {mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089} in preference to {mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089} [mscorlib]System.Runtime.InteropServices.Marshal::StructureToPtr System.Void(!!0, System.IntPtr, System.Boolean) The most likely cause is that SmartAssembly has used a different version of a dependency from the version used by EXAPTplus.Core.dll. If the details below are wrong, please use the MandatoryPath attribute in the .saproj file to ensure that the correct version of the dependency is found. Assembly that should contain the missing symbol: C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.5mscorlib.dll SmartAssembly.InformationException: SmartAssembly has encountered an invalid symbol: [mscorlib]System.Runtime.InteropServices.Marshal::StructureToPtr System.Void(!!0, System.IntPtr, System.Boolean) The most likely cause is that SmartAssembly has used a different version of a dependency from the version used by EXAPTplus.Core.dll. If the details below are wrong, please use the MandatoryPath attribute in the .saproj file to ensure that the correct version of the dependency is found. Assembly that should contain the missing symbol: C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.5mscorlib.dll
In the .saproj:<Assembly AssemblyName="mscorlib, Culture=neutral, PublicKeyToken=b77a5c561934e089" MandatoryPath="C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll" > <Merging /> </Assembly>
-
After lots of updating and testing, I finally figured out the problem: The .NET 2.0 assembly used a different key to sign the assembly, so the MandatoryPath doesn't work.
With the following change I get it to compile:<Assembly AssemblyName="mscorlib, Culture=neutral, PublicKeyToken=b77a5c561934e089" MandatoryPath="C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll" /> <Assembly AssemblyName="mscorlib, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" MandatoryPath="C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll" />
However, I now get the following warning:One or more of the merged assemblies uses internal members of unmerged assemblies via InternalsVisibleToAttribute. Your assembly may not work.
However, so far I have not noticed any problems.
Add comment
Please sign in to leave a comment.
Setting MandatoryPath doesn't help, the following (tabcontrol extend) code is involved:
Setting the dll back to dotnet 4.5.0 is a temporary solution