Get Build Date in .NET MAUI csproj - c#

I tried to get build date in the csproj of a .NET MAUI solution file like I did in a regular WPF Application:
1.0 $([System.DateTime]::Now.ToString())
But I cant compile it , I get an error NETSDK1005 ... project.assets.json
I tried it with the current VS2022 17.4.3 and also Preview 17.5.0 2.0
If it don't work with ApplicationDisplayVersion is there any other way to get the build date at runtime ?

You could use MSBuild property. Besides having only the assembly version we can have the version + time of the build. We could use SourceRevisionId tag to tell .NET compiler do this.
Add these following to yourappname.csproj file
<PropertyGroup>
<SourceRevisionId>build$([System.DateTime]::UtcNow.ToString("yyyyMMddHHmmss"))</SourceRevisionId>
</PropertyGroup>
Then you could retrieve the build date through AssemblyInformationalVersionAttribute using the following code:
private static DateTime GetBuildDate(Assembly assembly)
{
const string BuildVersionMetadataPrefix = "+build";
var attribute = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
if (attribute?.InformationalVersion != null)
{
var value = attribute.InformationalVersion;
var index = value.IndexOf(BuildVersionMetadataPrefix);
if (index > 0)
{
value = value.Substring(index + BuildVersionMetadataPrefix.Length);
if (DateTime.TryParseExact(value, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out var result))
{
return result;
}
}
}
return default;
}
Then you could get build date through the method
DateTime dt = GetBuildDate(Assembly.GetExecutingAssembly());
For more info, you could refer to Getting the date of build of a .NET assembly at runtime.
Hope it works for you.

Related

ArgumentException: Version string portion was too short or too long

I'm grabbing product versions from DB which stores as VARCHAR and has value something like this 2.6.12-build.222. I need to trim everything after - so the result is 2.6.12 below is the code how I'm doing this string operation and working perfectly fine, I'm getting trimmed version but I need to compare two versions for the further operations for that I'm using Version class but as soon as I pass my substring to Version class it's showing me this error-
ArgumentException: Version string portion was too short or too long.
All my versions are in 2.6.12 format
var resourceGuids = httpResp.Select(xl => xl.guid).ToList();
var existingBuilds = _DBcontext.Deployedproducts.Where(xl => resourceGuids.Contains(xl.Guid.ToString())).ToList();
var x = existingBuilds.FirstOrDefault(o => o.Guid == item.guid);
Version v = new Version(x.ProductVersion.Substring(0, x.ProductVersion.LastIndexOf("-") + 1).Replace(#"-",""));
if (item.Item1.version < v)
{
x.LatestMajorRelease = item.Item1.version.ToString();
}
If you can have values without a dash you have to check for that before doing the substring.
string version = x.ProductVersion;
int dashIndex = x.ProductVersion.IndexOf("-");
if(dashIndex > -1)
version = version.Substring(0, dashIndex);
Version v = new Version(version);
Note I used IndexOf just in case there's a second dash later on.
You could also do other checks like if dashIndex is 0 then this will result in an empty string as it's likely an invalid version to begin with.
In fact if dashIndex is less than 3 then it cannot be a valid version (as the version requires at least 2 parts like 1.1 or 2.3).

CultureName of System assembly in .NET

While writing some code handling assemblies in C# I noticed inconsistencies in field values of Assembly object (example of System assembly):
> typeof(string).Assembly.FullName
"mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
but when accessing CultureName field of AssemblyName object directly, its value is an empty string:
> typeof(string).Assembly.GetName().CultureName
""
When I run the same test on Linux (mono 3.99) I got another result:
> typeof(string).Assembly.GetName().CultureName
"neutral"
Why does .NET behaves that way? I couldn't find any information on msdn regarding default value of CultureName field in AssemblyName class or meaning of an
empty string. Does an empty string always refers to "neutral" culture name?
The CultureName property was introduced in .Net 4.5 and the value of that property for an Assembly with the neutral culture must be equal to an empty string like the name of the invariant culture because the CultureName uses theCultureInfo property (source):
public String CultureName
{
get
{
return (_CultureInfo == null) ? null : _CultureInfo.Name;
}
}
But in Mono the CultureName property has a different implementation (source). Why different? I think developers of Mono know the answer.
public string CultureName {
get {
if (cultureinfo == null)
return null;
if (cultureinfo.LCID == CultureInfo.InvariantCulture.LCID)
return "neutral";
return cultureinfo.Name;
}
}
So if you want to check that an AssemblyName has the neutral culture, use the code below:
if (object.Equals(assemblyName.CultureInfo, CultureInfo.InvariantCulture))
{ /* neutral culture */ }

ODP.NET: Oracle date formatting to "output-only" formats

I'd like to use Oracle date formatting in C#, such as in to_char(date, format), without database connection nor writing my own format interpreter.
Sample application (I'm using Oracle Data Provider for .NET):
namespace OracleDateToCharTest
{
using System;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
class Program
{
/// <param name="fmt"> Oracle-like format string. </param>
public static string OracleDateToChar(DateTime date, string fmt)
{
//// preparing format for ToString()
OracleGlobalization og = OracleGlobalization.GetThreadInfo();
string prevFormat = og.DateFormat;
og.DateFormat = fmt;
try
{
//// converting to OracleDate
OracleDate odacDate = new OracleDate(date);
//// setting format for ToString()
OracleGlobalization.SetThreadInfo(og);
return odacDate.ToString();
}
catch (OracleTypeException ex)
{
if (ex.Number == 1820)
{
//// described issue
}
throw;
}
finally
{
og.DateFormat = prevFormat;
OracleGlobalization.SetThreadInfo(og);
}
}
static void Main(string[] args)
{
var x = OracleDateToChar(DateTime.Now, "mm-dd-yyyy");
var y = OracleDateToChar(DateTime.Now, "mm-dd-yyyy HH24:Mi:ss");
var z = OracleDateToChar(DateTime.Now, "IW"); //// exception
}
}
}
It works well with formats like "mm-dd-yyyy", "mm-dd-yyyy HH24:Mi:ss", but unfortunately it doesn't work with "output-only" formats like "IW" (output-only formats are formats that you can specify in TO*_DATETIME funcitons according to Table 9-4 on http://docs.oracle.com/cd/B28359_01/olap.111/b28126/dml_commands_1029.htm).
When I call for example
OracleDateToChar(DateTime.Now, "IW")
I get ORA-01820 format code cannot appear in date input format exception in ToString() line.
I'd understand if I got this error in ToDate() method, but in ToString() it seems to be a bug in ODP.NET.
Question: Is there a way to implement OracleDateToChar method that can handle output-only formats? (assuming that calling select to_char(:date, :fmt) from nvl; from oracle database is not an option)
The point about that Oracle documentation is that it applies to DATE_FORMAT which is part of the Oracle language. Therefore you can only execute it as a PL/SQL statement which is why you cannot get it to work client side: IW is not a valid format mask for ODP.Net globalization as far as I know. In fact the ODP globalization DateFormat defaults to whatever you have in NLS_DATE_FORMAT locally which is a full date format string, whereas IW is for getting the week of the year rather than for formatting a date itself. As far as I know, nothing in the .Net framework will recognise that Oracle-specific string, so in order for it to work you would need to issue a command to Oracle and get the result back, as per the example on that page:
CONSIDER mydatetime
DATE_FORMAT MON-RRRR-DD-HH24
That seems like a lot of overkill to change a date format. There are some good alternative siggestions which are client-side .Net in this SO answer
Further Reading
The Oracle docs for the Oracle Date Structure (OracleDate) ToString() method notes that
The returned value is a string representation of the OracleDate in the
format specified by the thread's OracleGlobalization.DateFormat
property
(My emphasis). The definition for this can be found here. A useful list of allowed format strings for NLS_DATE_FORMAT, and therefore by extension OracleDate.ToString, can be found here.

program doesn't start under IIS

Sorry, if this question has already solved but... I have a little simple currency convertor under asp.net. My program reads xml file with currencies with XmlTextReader method. Then when I run my site under visual studio in debug or release mode it works perfectly, but when I run it just under IIS all parsed data are zero or non-decimal. If I don't use Decimal.TryParse(x, out y) it shows me error: "Input string was not in a correct format." But I don't understand why it shows me error only if I run it under IIS and doesn't show me it under VS. I think somethig wrong with permissions but I don't know where I can find the solution. Here the part of my code:
reader.MoveToAttribute(0);
string s1 = reader.Value;
reader.MoveToAttribute(1);
decimal d1 = 0;
Decimal.TryParse(reader.Value, out d1);
reader.MoveToAttribute(2);
decimal d2 = 0;
Decimal.TryParse(reader.Value, out d2);
valutaList.Add(new list { Valuta = s1, Pokupka = d1, Prodaga = d2 });
reader.MoveToElement();
later added:
my xml-file is in web. I partly solved task with globalization classes but I get numbers with point like ",". How can I change it to "."? I added this code:
Decimal.TryParse(reader.Value, System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.CultureInfo.CreateSpecificCulture("en-US"), out d1);

Is there a way to try to guess the date from a filename and, if unable, to gracefully fail?

I want to try to (programmatically) guess the date a file was created. It it is named BlaBla.2012-06-04.xlw, I can guess it was created June 4th, 2012.
However, if the file is named something else, like SitOnA.PotatoPanOtis.pal, I want to be able to simply give up (without the attempted conversion to a DateTime causing an exception) and present the user with a DateTimePicker.
Doable?
I've got this code:
String substr = SelectedFileName.Substring(DATE_BEGIN_POS, DATE_LENGTH);
return DateTime.Parse(substr);
I'm thinking something like this would make sense:
try
{
String substr = SelectedFileName.Substring(DATE_BEGIN_POS, DATE_LENGTH);
return DateTime.Parse(substr);
}
catch (ConversionException ce)
{
//Show form with DateTimePicker
}
UPDATE
It seems like something like this should work:
DateTime dt;
if (!(DateTime.TryParse(substr, out dt))) {
. . .
don't guess. Get it !
var creationTime = File.GetCreationTime(#"c:\myfile.txt");
Either you can ask directly for the creation time using the File.GetCreationTime or if you are trying to guess via the file name then you can use TryParse for the date and if doesn't work (method return false) then show the dialog.
Use RegEx to match the filename.
Regex r = new Regex("\d{4}-\d{2}-\d{2}");
if (r.Match(fileName).Success) {
//GUESS!
}

Categories