I'm trying to implement java autocomplete in one of my ScintillaNET projects and am having an issue. I've been following all the steps required
Ensure that ScintillaNET (and required .dlls) are located in my PATH variable.
Added the CustomLocation and Language params values to my editor
Below is my code for review, and I have ensured that I have the params set correctly...I'm just lost.
Scintilla sciEditor = (Scintilla)selectedTab.Controls["sciEditor"];
using (StreamReader sr = new StreamReader(fileName))
{
String line = sr.ReadToEnd();
sciEditor.Text = line;
}
if (ext == "java")
{
sciEditor.ConfigurationManager.Language = "java";
sciEditor.ConfigurationManager.CustomLocation = #"C:\java.xml";
sciEditor.CharAdded += new EventHandler<CharAddedEventArgs>(sciEditor_CharAdded);
}
So you can see I read the text into the Scintilla editor, and if the files ext is java (which I parse above this block, and get valid answer), then I set the editors languaget to java, and set my custom location to a java.xml file
<?xml version="1.0" encoding="utf-8"?>
<ScintillaNET>
<Language Name="java">
<AutoComplete FillUpCharacters=".([" SingleLineAccept="True" IsCaseSensitive="False">
<List>
abstract assert boolean break byte case catch char class continue default do double else enum extends
final finally float for if import int interface long native new package private protected public return
short static strictfp super switch synchronized this throw throws transient try void volatile while
</List>
</AutoComplete>
<Indentation TabWidth="4" SmartIndentType="cpp" />
<Lexer LexerName="java" LineCommentPrefix="//" StreamCommentPrefix="/* " StreamCommentSuffix=" */" >
<Keywords List="0" Inherit="False">
abstract assert break case catch continue default do else extends final finally for if import interface
native new package private protected public return strictfp super switch synchronized this throw throws
transient try volatile while
</Keywords>
<Keywords List="1" Inherit="False">
boolean byte char class double enum float int long short static
</Keywords>
</Lexer>
</Language>
</ScintillaNET>
And whenever I deploy (and have the .xml in my C:\ folder (or deployed beside my executable) it doesn't apply any styling (and the autocomplete is empty). Besides downloading and recompiling my own, I have no idea what's wrong.
Same issue happened to me today and I got banned for asking such a question.
Shame on ScintillaNET developer(s).
Trying to define myself a custom language, but, ended up you can't do it.
So, what I did is I used pre-built language as a NAME, and then extended that LANGUAGE instead of defining my own, which ScintillaNET cant find. Hopefully you understand, it took me four days to figure it, such a stupid shit. Thanks to Charles:) - dreamincode.net for a hint, as my head is blown atm.
Related
Intro
I am looking for more customized solution for translating my app. I will be using Humanizer and Smart.Format after obtaining entries. The problem is to define keys to obtain them in the first place.
Requirements
The requirements are:
Language keys must be defined in-code, preferably near place where they are used
Language keys must contain default-English values
All language keys must be listed (XML, CSV, JSON, anything) after building the app suite
Language entries must be provided from external source (like JSON file), without the need for any kind of recompilation
The app may contain multiple executables, shared libraries, etc. all of them in form of C# apps
Discarded solutions
First, the things I discarded:
Built-in C# Resources.dll; They violate (1) and (4)
External file with keys. Violates (1)
My idea for handling the problem
Now, my idea for the solution looks that way (and is inspired by C++ GetText)
There is a template class which contains keys:
private sealed class Module1Keys : LocalizationKeys<Module1Keys>
{
public static readonly LocalizationKey HelloWorld = DefineKey("/foo", "Hello World!");
public static readonly LocalizationKey HelloWorld2 = DefineKey("/bar", "Hello World2!");
}
And the class LocalizationKeys contains a static method that will actually register keys in simple collection
public abstract class LocalizationKeys<T> where T : LocalizationKeys<T>
{
protected static LocalizationKey DefineKey(string path, string english)
{
var ret = new LocalizationKey(typeof(T), path, english);
// Following registers localization key in runtime:
Localization.Instance.RegisterLocalizableKey(ret);
return ret;
}
}
Problem
The only thing left to handle in this approach is to list localizable keys during build... which is where I had hit the wall. It is very easy to list them during runtime, but I cannot run the code on build time (particularly it may be built as shared library).
Maybe I am overthinking myself and there is better, more clean solution - I don't need to stick with this solution, but Googling around has not yielded anything better...
Nailed it. In GetText times we have to resort to manually parse code.
... but now, with CSharp, we have a Roslyn, with CodeAnalysis API.
Solution
Wire up custom Console build tool that includes Microsoft.CodeAnalysis NuGet and have code like:
var model = compilation.GetSemanticModel(tree);
var methods = root.DescendantNodes().OfType<InvocationExpressionSyntax>();
foreach(var method in methods)
{
if(model.GetSymbolInfo(method).Symbol is IMethodSymbol symbol &&
symbol.ContainingNamespace.Name == "MyProject" &&
symbol.ContainingType.Name == "LocalizationKeys" &&
symbol.Name == "DefineKey")
{
var key = method.ArgumentList.Arguments.FirstOrDefault();
var eng = method.ArgumentList.Arguments.Skip(1).FirstOrDefault();
if(key.Expression is LiteralExpressionSyntax literalKey &&
eng.Expression is LiteralExpressionSyntax literalEng)
{
// "/foo" -> "Hello World!"
// "/bar" -> "Hello World2!"
Console.WriteLine(literalKey + " -> " + literalEng);
}
else
{
// Bonus: detect violation of key definition rule. It is not a literal!
}
}
}
Compile this Console tool as executable and add it as post-build step. Profit.
I need to make sure that the file given by the user is converted to the .txt file if contains text, before any further processing.
At the moment I have a switch statement checking for the specific formats and converting from those to the .txt format.
switch (extension)
{
case ".pdf":
//Convert from .pdf to .txt file
break;
case ".doc":
//Convert from .doc to .txt file
break;
default:
Console.WriteLine("The file could not be converted!");
break;
}
The problem is, I'd need something more generic to check if the given file is .txt or if it's not but could be converted, to do so.
Following L.B's advice I am going to reincarnate this.
Using the Tika Java Library In Your .Net Application With IKVM
This may sound scary and heretical but did you know it is possible to leverage Java libraries from .Net applications with no TCP sockets or web services getting caught in the crossfire? Let me introduce you to IKVM, which is frankly magic:
IKVM.NET is an implementation of Java for Mono and the Microsoft .NET Framework. It includes the following components:
A Java Virtual Machine implemented in .NET
A .NET implementation of the Java class libraries
Tools that enable Java and .NET interoperability
Using IKVM we have been able to successfully integrate our Dovetail Seeker search application with the Tika text extraction library implemented in Java. With Tika we can easily pull text out of rich documents from many supported formats. Why Tika? Because there is nothing comparable in the .Net world as Tika.
This post will review how we integrated with Tika. If you like code you can find this example in a repo up on Github.
Compiling a Jar Into An Assembly
First thing, we need to get our hands on the latest version of Tika. I downloaded and built the Tika source using Maven as instructed. The result of this was a few jar files. The one we are interested in is tika-app-x.x.jar which has everything we need bundled into one useful container.
Next up we need to convert this jar we’ve built to a .Net assembly. Do this using ikvmc.exe.
tika\build>ikvmc.exe -target:library tika-app-0.7.jar
Unfortunately, you will see tons of troublesome looking warnings but the end result is a .Net assembly wrapping the Java jar which you can reference in your projects.
Using Tika From .Net
IKVM is pretty transparent. You simply reference the the Tika app assembly and your .Net code is talking to Java types. It is a bit weird at first as you have Java versions of types and .Net versions. Next you’ll want to make sure that all the dependent IKVM runtime assemblies are included with your project. Using Reflector I found that the Tika app assembly referenced a lot of IKVM assemblies which do not appear to be used. I had to figure out through trial and error which assemblies where not being touched by the rich document extractions being done. If need be you could simple include all of the referenced IKVM assemblies with your application. Below I have done the work for you and eliminated all references to all the IKVM assemblies which appear to be in play.
16 assemblies down to 5. A much smaller deployment.
Using Tika
To do some text extraction we’ll ask Tika, very nicely, to parse the files we throw at it. For my purposes this involved having Tika automatically determine how to parse the stream and extract the text and metadata about the document.
public TextExtractionResult Extract(string filePath)
{
var parser = new AutoDetectParser();
var metadata = new Metadata();
var parseContext = new ParseContext();
java.lang.Class parserClass = parser.GetType();
parseContext.set(parserClass, parser);
try
{
var file = new File(filePath);
var url = file.toURI().toURL();
using (var inputStream = MetadataHelper.getInputStream(url, metadata))
{
parser.parse(inputStream, getTransformerHandler(), metadata, parseContext);
inputStream.close();
}
return assembleExtractionResult(_outputWriter.toString(), metadata);
}
catch (Exception ex)
{
throw new ApplicationException("Extraction of text from the file '{0}' failed.".ToFormat(filePath), ex);
}
}
One Important Cavet
Java has a concept called a ClassLoader which has something to do with how Java types are found and loaded. There is probably a better way around this but for some reason if you do not implement a custom ClassLoader and also set an application setting cueing the IKVM runtime about which .Net type to use as the ClassLoader.
public class MySystemClassLoader : ClassLoader
{
public MySystemClassLoader(ClassLoader parent)
: base(new AppDomainAssemblyClassLoader(typeof(MySystemClassLoader).Assembly))
{
}
}
Here is an example app.config telling IKVM where the ClassLoader is found.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ikvm:java.system.class.loader" value="TikaOnDotNet.MySystemClassLoader, TikaOnDotNet" />
</appSettings>
</configuration>
This step is very important. If IKVM cannot find a class loader, for some horrible reason, Tika will work fine but extract only empty documents with no metadata. The main reason this is troubling is that no exception is raised. For this reason we actually have a validation step in our application ensuring that the app setting is present and that it resolves to a valid type.
Demo
Here is a test demonstrating an extraction and the result.
[Test]
public void should_extract_from_pdf()
{
var textExtractionResult = new TextExtractor().Extract("Tika.pdf");
textExtractionResult.Text.ShouldContain("pack of pickled almonds");
Console.WriteLine(textExtractionResult);
}
Put simply rich documents like this go in.
And a TextExtractionResult comes out:
public class TextExtractionResult
{
public string Text { get; set; }
public string ContentType { get; set; }
public IDictionary<string, string> Metadata { get; set; }
//toString() override
}
Here is the raw output from Tika:
Conclusion
I hope this helps boost your confidence that you can use Java libraries in your .Net code and I hope my example repo will be of assistance if you need to do some work with Tika on the .Net platform. Enjoy.
Info to set this up:
Use Nuget to look up TikaOnDotnet and install both TikaOnDotnet & TikaOnDotnet.TextExtractor to your project. Here's the code to test it out on a Winform App:
public partial class Form1 : Form
{
private System.Windows.Forms.TextBox textBox1;
private TextExtractor _textExtractor;
public Form1()
{
InitializeComponent();
_textExtractor = new TextExtractor();
textBox1 = new System.Windows.Forms.TextBox();
textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
textBox1.Multiline = true;
textBox1.Name = "textBox1";
textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
textBox1.AllowDrop = true;
textBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.textBox1_DragDrop);
textBox1.DragOver += new System.Windows.Forms.DragEventHandler(this.textBox1_DragOver);
Controls.Add(this.textBox1);
Name = "Drag/Drop any file on to the TextBox";
ClientSize = new System.Drawing.Size(867, 523);
}
private void textBox1_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (files != null && files.Length != 0)
{
TextExtractionResult textExtractionResult = _textExtractor.Extract(files[0]);
textBox1.Text = textExtractionResult.Text;
}
}
}
Edit: The original blog page has moved to but there is no 302 perm redirect http://clarify.dovetailsoftware.com/kmiller/2010/07/02/using-the-tika-java-library-in-your-net-application-with-ikvm/
I'm trying to update the label/publisher field using Taglib-sharp, but I can't see it anywhere in its Object Hierarchy using Object Browser.
I've searched through google and the documentation and it looks like it's a field that's not catered for.
Before I look for alternatives (can any one suggest any?) that can edit those field, I thought I'd have one last crack and ask within the StackOverflow community who is familiar with TagLib-sharp that had a more informed opinion?
Thanks in Advance,
Francis
Update : I've investigated other libraries such as mpg123 & UltraID3Lib but they seem to have the same limitations.
Well, Daniel Fuchs answer didn't work for me. But, it was a beginning.
The step by step to add a field in the TagLib-sharp code is:
Download Source
Open the File TagLib/Tag.cs and insert the following code (I inserted it below PerformersSort, line 250):
public virtual string Publisher
{
get { return ""; }
set { }
}
Open the File TagLib/Id3v2/Tag.cs and insert the following code (I inserted it below PerformersSort, line 1292):
public override string Publisher
{
get { return GetTextAsString(FrameType.TPUB); }
set { SetTextFrame(FrameType.TPUB, value); }
}
Open the File TagLib/Id3v2/FrameTypes.cs and insert the following code (I inserted it below TPOS, line 71):
public static readonly ReadOnlyByteVector TPUB = "TPUB";
Now comes the "Aha" thing. Open the File TagLib/CombinedTag.cs and insert the following code (I inserted it below PerformersSort, line 318):
public override string Publisher
{
get
{
foreach (Tag tag in tags)
{
if (tag == null)
continue;
string value = tag.Publisher;
if (value != null)
return value;
}
return null;
}
set
{
foreach (Tag tag in tags)
if (tag != null)
tag.Publisher = value;
}
}
Finally, compile the code.
IMPORTANT: I had problems compiling the code, as well. You must download the SharpZipLib dll (.NET 2.0) and include this dll in the taglib project. Also, I needed to install NUnit, which I made with Nuget. At last, I commented the GDK lib and all its errors inside the test code, since in production it won't be used.
Well TagLib# is not able to to read the publisher tag. Even the newest version (2.1.0.0) as of now won't be able to do that. As an alternative you can add this functionality yourself using the source code of TagLib#, which is freely available.
To do so, open the file TagLib/Id3v2/FrameTypes.cs and add the following line somewhere:
public static readonly ReadOnlyByteVector TPUB = "TPUB"; // Publisher field
And in the file TagLib/Id3v2/Tag.cs:
public string Publisher {
get {return GetTextAsString (FrameType.TPUB);}
set {SetTextFrame (FrameType.TPUB, value);}
}
You can then access the Publisher field using something like this
TagLib.File tf = TagLib.File.Create(...); // open file
tf.Tag.Publisher = "Label XY"; // write new Publisher
tf.Save(); // save tags
Please note, that this is an ugly hack but will work for MP3 files.
I'm not used to TagLib#, but I'm using TagLib in a Qt project, where I retrieve this information inspecting TagLib::File::properties.
Take a look at the documentation, it is just a string map with every property and values.
Hope TagLib# has this method.
Update 2019-12-30:
It looks like the main taglib project has included the publisher field, so you should just use the latest version instead. I've updated to the latest TagLib from my fork and can attest that it works as expected.
Tip : If you want to change the framework version that TagLib compiles to (at time of writing it defaults to 462 and .NET STD 2.0), you need to change the Directory.Build.Props file located in the Solutions folder.
<Project>
<PropertyGroup>
<ReleaseVersion>2.2.0.0-beta</ReleaseVersion>
<RepositoryUrl>https://github.com/mono/taglib-sharp</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<TaglibSharpTargetFramework>net472;netstandard2.0</TaglibSharpTargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
</Project>
I've pasted my version above which shows that I've changed it to compile to .NET 4.7.2 instead.
I have a simple c++ Application. This Application is just printing text out.
I have also a c# .dll NET 3.5 which parses complex xml files, extracts values and saves them into a List. Its like 2 Classes with 4 methods. They open a file, parse the xml and store it into a List. When the c# .dll is done, it has a List with 10000 values;
Since i do not want to write the complex parsing XML in c++, i would like to use my c# xml parsing .dll.
Is it possible for me, to call my c# .dll from inside my c++ application, let the c# .dll parse a specified xml file, and return that created List, with the parsed xml values, to my c++ application?
In my c++ application i would proceed to modify the data within the returned list.
edit: i would be using vc++ (Microsoft Visual Studio 2010)
edit2: the vc++ app would be an expension/plug-in to another bigger Application. I would register the plug-in to that bigger application, and every time i press the icon in the menu, my vc++ application would be started
edit3: Has anyone experience with such a task? I kinda need a clear yes or no if it is possible.
edit4: i do want to avoid reading files that have been written by my .net .dll. I want my c++ app to send a string to my .net .dll and receive back a list/array object. Or is this a bad idea and i should do the xml parsing in c++ itself?
Yes, you can do it, but its kinda hard. One way to do it is to use C++ to load up CLR and execute your function, something like this:
code inspired by Blizzhackers.cc
void StartNET()
{
DWORD result;
ICLRRuntimeHost* pCLR = NULL;
CorBindToRuntimeEx(NULL, L"wks", NULL, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pCLR);
pCLR->Start();
pCLR->ExecuteInDefaultAppDomain(L"C:\\myNET.dll", L"myNet.Program", L"Main", L"arg", &result);
pCLR->Stop();
}
This C++ code will execute the int Main(string arg) function from namespace myNet and class Program, by that I mean:
myNET.dll:
namespace myNet
{
class Program
{
int Main(string arg)
{
//and here you can run your XML parser:
List<string> myList = XMLParse();
FileStream fs = new Filestream("xmllist.txt");
StreamWriter sw = new StreamWriter(fs);
foreach(string s in myList)
sw.WriteLine(s);
sw.Close();
fs.Close();
return 1;
}
List<string> XMLParse()
{
//Your code here
return aList;
}
}
}
And after this you could use c++ to get the files from xmllist.txt, something like:
vector<char[]> getList()
{
vector<char[]> *myVector = new vector<char>;
ifstream cin("xmllist.txt");
while(!cin.eof())
{
char line[100];
cin >> line;
myVector.push(line);
}
cin.close();
return myVector;
}
I don't know if this last function works, but you get the general idea.
I created a managed/unmanaged dll in C++ some time ago. (Note though that C++.net has not the easiest syntax.)
Actually, I do not know where to start now, maybe this has the information http://channel9.msdn.com/Forums/TechOff/101918-Mixing-Managed-and-Unmanaged-C-in-a-DLL . It certainly was well possible with.. VS 2005? With that, you can have both managed an unmanaged code in one binary/assembly, and thus call the C# dll.
Apart from that, you can wrap your C# objects as COM objects. http://msdn.microsoft.com/en-us/library/ms404285.aspx . Then you can use COM interop.
In each case, marshalling the input/output would require some trial and error - it is not that obvious if you have never done it before.
Actually, this link should cover it all: http://msdn.microsoft.com/en-us/library/ms973872.aspx .
I have a requirement to install multiple web setup projects (using VS2005 and ASP.Net/C#) into the same virtual folder. The projects share some assembly references (the file systems are all structured to use the same 'bin' folder), making deployment of changes to those assemblies problematic since the MS installer will only overwrite assemblies if the currently installed version is older than the one in the MSI.
I'm not suggesting that the pessimistic installation scheme is wrong - only that it creates a problem in the environment I've been given to work with. Since there are a sizable number of common assemblies and a significant number of developers who might change a common assembly but forget to update its version number, trying to manage versioning manually will eventually lead to massive confusion at install time.
On the flip side of this issue, it's also important not to spontaneously update version numbers and replace all common assemblies with every install, since that could (temporarily at least) obscure cases where actual changes were made.
That said, what I'm looking for is a means to update assembly version information (preferably using MSBuild) only in cases where the assembly constituents (code modules, resources etc) has/have actually changed.
I've found a few references that are at least partially pertinent here (AssemblyInfo task on MSDN) and here (looks similar to what I need, but more than two years old and without a clear solution).
My team also uses TFS version control, so an automated solution should probably include a means by which the AssebmlyInfo can be checked out/in during the build.
Any help would be much appreciated.
Thanks in advance.
I cannot answer all your questions, as I don't have experience with TFS.
But I can recommend a better approach to use for updating your AssemblyInfo.cs files than using the AssemblyInfo task. That task appears to just recreate a standard AssemblyInfo file from scratch, and loses any custom portions you may have added.
For that reason, I suggest you look into the FileUpdate task, from the MSBuild Community Tasks project. It can look for specific content in a file and replace it, like this:
<FileUpdate
Files="$(WebDir)\Properties\AssemblyInfo.cs"
Regex="(\d+)\.(\d+)\.(\d+)\.(\d+)"
ReplacementText="$(Major).$(ServicePack).$(Build).$(Revision)"
Condition="'$(Configuration)' == 'Release'"
/>
There are several ways you can control the incrementing of the build number. Because I only want the build number to increment if the build is completely successful, I use a 2-step method:
read a number from a text file (the only thing in the file is the number) and add 1 without changing the file;
as a final step in the build process, if everything succeeded, save the incremented number back to the text file.
There are tasks such as ReadLinesFromFile, that can help you with this, but I found it easiest to write a small custom task:
using System;
using System.IO;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace CredibleCustomBuildTasks
{
public class IncrementTask : Task
{
[Required]
public bool SaveChange { get; set; }
[Required]
public string IncrementFileName { get; set; }
[Output]
public int Increment { get; set; }
public override bool Execute()
{
if (File.Exists(IncrementFileName))
{
string lines = File.ReadAllText(IncrementFileName);
int result;
if(Int32.TryParse(lines, out result))
{
Increment = result + 1;
}
else
{
Log.LogError("Unable to parse integer in '{0}' (contents of {1})");
return false;
}
}
else
{
Increment = 1;
}
if (SaveChange)
{
File.Delete(IncrementFileName);
File.WriteAllText(IncrementFileName, Increment.ToString());
}
return true;
}
}
}
I use this before the FileUpdateTask to get the next build number:
<IncrementTask
IncrementFileName="$(BuildNumberFile)"
SaveChange="false">
<Output TaskParameter="Increment" PropertyName="Build" />
</IncrementTask>
and as my final step (before notifying others) in the build:
<IncrementTask
IncrementFileName="$(BuildNumberFile)"
SaveChange="true"
Condition="'$(Configuration)' == 'Release'" />
Your other question of how to update the version number only when source code has changed is highly dependent on your how your build process interacts with your source control. Normally, checking in source file changes should initiate a Continuous Integration build. That is the one to use to update the relevant version number.
I have written one custome task you can refer the code below. It will create an utility to which you can pass assemblyinfo path Major,minor and build number. you can modify it to get revision number. Since in my case this task was done by developer i used to search it and again replace whole string.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
namespace UpdateVersion
{
class SetVersion
{
static void Main(string[] args)
{
String FilePath = args[0];
String MajVersion=args[1];
String MinVersion = args[2];
String BuildNumber = args[3];
string RevisionNumber = null;
StreamReader Reader = File.OpenText(FilePath);
string contents = Reader.ReadToEnd();
Reader.Close();
MatchCollection match = Regex.Matches(contents, #"\[assembly: AssemblyVersion\("".*""\)\]", RegexOptions.IgnoreCase);
if (match[0].Value != null)
{
string strRevisionNumber = match[0].Value;
RevisionNumber = strRevisionNumber.Substring(strRevisionNumber.LastIndexOf(".") + 1, (strRevisionNumber.LastIndexOf("\"")-1) - strRevisionNumber.LastIndexOf("."));
String replaceWithText = String.Format("[assembly: AssemblyVersion(\"{0}.{1}.{2}.{3}\")]", MajVersion, MinVersion, BuildNumber, RevisionNumber);
string newText = Regex.Replace(contents, #"\[assembly: AssemblyVersion\("".*""\)\]", replaceWithText);
StreamWriter writer = new StreamWriter(FilePath, false);
writer.Write(newText);
writer.Close();
}
else
{
Console.WriteLine("No matching values found");
}
}
}
}
I hate to say this but it seems that you may be doing it wrongly. Is much easier if you do generate the assembly versions on the fly instead of trying to patch them.
Take a look at https://sbarnea.com/articles/easy-windows-build-versioning/
Why I do think you are doing it wrong?
* A build should not modify the version number
* if you build the same changeset twice you should get the same build numbers
* if you put build number inside what microsoft calls build number (proper naming would be PATCH level) you will eventually reach the 65535 limitation.