Get assembly version in PCL - .net-assembly

I have the following line of code in .NET 4.5 that I am trying to build as Portable Class Library. It's purpose is to get assembly version:
this.GetType().Assembly.GetName().Version.Major;
The problem is that Assembly.GetName() is not available in PCL. Is there a way to get assembly version in PCL?
I know it is possible to parse Assembly.FullName, but I want a better solution.

public static string Version
{
get
{
var assembly = typeof(MyType).GetTypeInfo().Assembly;
// In some PCL profiles the above line is: var assembly = typeof(MyType).Assembly;
var assemblyName = new AssemblyName(assembly.FullName);
return assemblyName.Version.Major + "." + assemblyName.Version.Minor;
}
}

I now use the following:
[assembly: AssemblyTitle(AssemblyInfo.AssemblyTitle)]
[assembly: AssemblyProduct(AssemblyInfo.AssemblyProduct)]
[assembly: AssemblyVersion(AssemblyInfo.AssemblyVersion)]
[assembly: AssemblyFileVersion(AssemblyInfo.AssemblyFileVersion)]
[assembly: AssemblyInformationalVersion(AssemblyInfo.AssemblyInformationalVersion)]
internal class AssemblyInfo
{
public const string AssemblyTitle = "...";
public const string AssemblyProduct = "...";
public const string AssemblyVersion = "1.0.0.0";
public const string AssemblyFileVersion = "1.0.0.0";
public const string AssemblyInformationalVersion = "1.0.0.0-dev";
}
This allows me to reference any of the constants within the assembly without using reflection, e.g. AssemblyInfo.AssemblyProduct.

You are targeting a Silverlight-based platform (Silverlight 4 or higher, Windows Phone before version 8). Those platforms didnt' support the GetName() method. For those platforms, you can define an extension method like this:
public static class AssemblyExtensions
{
public static AssemblyName GetName(this Assembly assembly)
{
return new AssemblyName(assembly.FullName);
}
}

Related

Can you link a .so in dotnet?

I have a .NET core project that uses a .so file. I use [DllImport()] to import it. My problem is that this .so has a dependency libtomcrypt.so so it can not locate some symbols(undefined symbol: cipher_descriptor).
I tried importing my .so in C and it works fine if I specify the linker variable -ltomcrypt.
Adding a reference to libtomcrypt.so in the .NET core project did not help because it is a native .so.
Is there any way to link libtomcrypt.so to dotnet?
Try to load your library with NativeLibrary first.
static class Library
{
const string MyLibrary = "mylibrary";
static Library()
{
NativeLibrary.SetDllImportResolver(typeof(Library).Assembly, ImportResolver);
}
private static IntPtr ImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
IntPtr libHandle = IntPtr.Zero;
if (libraryName == MyLibrary)
{
// Try using the system library 'libmylibrary.so.5'
NativeLibrary.TryLoad("libmylibrary.so.5", assembly, DllImportSearchPath.System32, out libHandle);
}
return libHandle;
}
[DllImport(MyLibrary)]
public static extern int foo();
}
Interacting with native libraries in .NET Core 3.0

C#4.0 using static

I was given the following task and I am hoping that someone will be able to guide me in the right direction. Currently, we have code compiling in C#6. Due to varying reasons, some of my fellow coworkers are running C#4 and are unable to upgrade to C#6. I have to slightly alter the code so that it compiles for my coworkers.
In c#6, we have the following code:
using System;
using static SecGlobal.Constants;
with SecGlobal.Constants being:
namespace SecGlobal
{
public static class Constants
{
public const string CONST_DB_SERVER = "server name";
public const string CONST_MAIN_TIME_ZONE = "Eastern Standard Time";
... etc
}
}
The issue I run into is that the feature "using static" is not available in C#4. Are there any alternatives?
Just replace constant references with a fully qualified name. For instance,
using System;
using static SecGlobal.Constants;
...
string s = CONST_DB_SERVER;
...
Becoming
using System;
...
string s = SecGlobal.Constants.CONST_DB_SERVER;

Identifier 'Submission#0' is not CLS-compliant in Azure functions

I hope somebody could help me on this one. I am implementing an Azure Function where I am trying to serialise an XML message into .Net object. This is the code that I am currently using:
public static void Run(string input, TraceWriter log)
{
    System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(App));
    // more code here....
}
public class App
{
    public string DataB { get; set; }
}
However, I always got this error:
2017-01-17T12:21:35.173 Exception while executing function: Functions.ManualXmlToJson. mscorlib: Exception has been thrown by the target of an invocation. System.Xml: Identifier 'Submission#0' is not CLS-compliant.
Parameter name: ident.
I have tried with XmlAttributes, without them. I added the buildOptions:warningsAsErrors as false in project.json file but nothing happens. And to be honest, I ran out of ideas because this code is actually working in an App Console.
I guess is some parameter of something, I would really appreciate if somebody can suggest me how to fix it.
Thanks!
Your best option here will be to factor the class you're attempting to serialize into a separate class library and reference that from your function.
If you implement your App class above in a different assembly, your function code would look like the following:
#r "<yourassemblyname>.dll"
using System;
using <YourClassNamespace>;
public static void Run(string input, TraceWriter log)
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(App));
}
The code above assumes a private assembly reference, where you upload your assembly to a bin folder, inside of your function folder.
You can find more about external references here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp#referencing-external-assemblies
I'm opening an issue to address the CLS compliant name so this is not as confusing:
https://github.com/Azure/azure-webjobs-sdk-script/issues/1123
Another option worth trying (which would minimize the changes you'd need to make to your code) is to use the DataContractSerializer instead. You can find more information here.
Here is a quick sample of a function using the DataContractSerializer (with your type above):
#r "System.Runtime.Serialization"
using System;
using System.Xml;
using System.Runtime.Serialization;
public static void Run(string input, TraceWriter log)
{
string xml = WriteObject(new App { DataB = "Test"});
log.Info(xml);
}
[DataContract(Name = "App")]
public class App
{
[DataMember]
public string DataB { get; set; }
}
public static string WriteObject(App app)
{
using (var output = new StringWriter())
using (var writer = new XmlTextWriter(output) { Formatting = Formatting.Indented })
{
var serializer = new DataContractSerializer(typeof(App));
serializer.WriteObject(writer, app);
return output.GetStringBuilder().ToString();
}
}

Get a module's version number in Orchard CMS 1.8+ using code

On occasion, I like to log a module's version number. How do I get a module's version number within code (programmatically)?
In the same way you request IOrchardServices in your controller's constructor, you can request IExtensionManager. Then, using the GetExtension method with the name of the module (as indicated in module.txt id), it returns an ExtensionDescriptor that exposes the Version property, among other useful properties.
You can see an example of using IExtensionManager in the RecipeHarvester source code.
If you need to access a module from anywhere in the code, you would need to initialize an ExtensionManager first. To do that, you will need the current workContext. This is the way I did that.
public class Extensioner
{
public IExtensionManager _manager { get; set; }
public Extensioner()
{
var httpContextAccessor = System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver.GetService(
typeof(IHttpContextAccessor)) as IHttpContextAccessor;
var workContext = WorkContextExtensions.GetWorkContext(httpContextAccessor.Current().Request.RequestContext);
_manager = workContext.Resolve<IExtensionManager>();
}
public string getModuleVersion(string moduleName)
{
var _ver = "unknown";
if (_manager != null)
{
_ver = _manager.GetExtension(moduleName).Version;
}
return _ver;
}
}
The page which showed me the way:
https://disqus.com/home/discussion/skywalkersoftwaredevelopment/orchard_webapi_global_actionfilters_and_dependency_injection/
And some theory:
https://orcharddojo.net/orchard-resources/Library/Wiki/WorkContext

VSIX Extension uses 3rd party DLLs unable to load one of the dependency

I am developing an extension to VS2013. Since it will be installed through MSI, I am changing the base directory to installation folder using ProvideBindingPath attribute to package class. But the 3rd party dll reference which will be loaded in runtime is not picking dll from the probed path. Its always looking into Visual studio devenv.exe folder. Is there any way to force the dll to look into my installation folder.
using MD=Microsoft.VisualStudio.Modeling.Shell;
MD.ProvideBindingPath(SubPath = #"")]
public sealed class AutomationCommandPanePackage : Package
{
public AutomationCommandPanePackage()
{
string installationPath = HelperMethods.GetInstallationPath();
if (string.IsNullOrEmpty(HelperMethods.GetInstallationPath())) return;
// Change default config file at runtime.
using (AutomationConfigurationManager.Change(installationPath, "AutomationPro.config"))
{
// Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
}
Assembly a = Assembly.GetExecutingAssembly();
Type type = a.GetType("AutomationCommandPanePackage", true);
System.Reflection.MemberInfo info = type;
var attributes = info.GetCustomAttributes(true);
foreach (var attrib in attributes)
{
if (attrib is MD.ProvideBindingPathAttribute)
{
((MD.ProvideBindingPathAttribute)attrib).SubPath = installationPath;
break;
}
}
I have been able to successfully load third party (telerik) assemblies in my extension using below code.
Register to AssemblyResolve event in your Package class constructor
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
Then in handler load packages as below:
string path = Assembly.GetExecutingAssembly().Location;
path = Path.GetDirectoryName(path);
if (args.Name.ToLower().Contains("telerik.windows.controls.gridview"))
{
path = Path.Combine(path, "telerik.windows.controls.gridview.dll");
Assembly ret = Assembly.LoadFrom(path);
return ret;
}
I have not had any issues with the above approach.
I resolved issue using
LoadLibrary() from
System.Runtime.InteropServices;
since my dll to be loaded is a COM iterop dll.
public static class win32
{
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); [DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
}
in package.cs I loaded assembly like this
win32.LoadLibrary(Path.Combine(installationPath, "apidsp_windows.dll"));

Resources