Fix Error : “Could not find a part of the path” While Publishing ASP.NET Core MVC Application To the Target Platform of Windows 7 x64/x86

Reason :

I’m working on a ASP.Net Core MVC application and I Published one of my ASP.Net Core MVC app into a Server which is running Windows Server 2008 R2.

But when I released the application live, it didn’t work on the server but it works fine on my local machine. My Local machine has Windows 10.

Then I looked for a solution and I got the reason. The reason Is I have published the app for the target platform of Windows 10. But the Server that the site has hosted has Windows Server 2008 R2 (Windows 7 Configurations)

Then what I had to do I was : Publish the app for the target platform of windows 7 (Windows Server 2008 R2).

Then I added target platforms to to the project.json file in my .Net Core MVC app. I published it again.

But I wasn’t published and it gave me an error..

Could not find a part of the path ‘F:\Projects\TestWebCore\src\TestWebCore\bin\Release\netcoreapp1.0\win7-x64\TestWebCore.dll’.

Then I looked for a solution and I found it is an error in tooling.

http://stackoverflow.com/questions/39023224/error-could-not-find-a-part-of-the-path-while-publishing-net-core-application

Solution :

The Solution is we have to publish the .Net Core applicaion using command prompt. 

I did it and my app was published successfully.

 

Here I’ll show you how the error occurred and How I did fix it.

First I’ll create a sample .Net Core MVC app with a .Net Core Portable Class Library(PCL).

You can See by Clicking..

How to Create a ASP.Net Core MVC app

Here is the project I have created..

The solution consists of one ASP.Net Core MVC project and a .Net Core PCL project.

1-project-flow

Image 1 : Solution Structure

Then I have changed the Index.cshtml file and added a simple html content to show you ..

2-change-index-page

Image 2 : Sample HTML content in Index.html file

Lets run the app to see how it looks like.

The app will run with the localhost and you could see the content I have added to the html body. I have used a Bootstrap template to the project. So you can see it is responsive.

3-index-page

Image 3 : Run The app in localhost

So Its running well and and the next step is Publish the app.

Publish The app

Then you try to publish an app for the first time, you will see a window like below..

5-publish-without-target-framework

Image 4 : Default Publish Window

Here you can see only one menu which is “Profile”. You can’t publish the app without selecting a profile. So we have to create a publish profile.

for that click on “Custom” button and you will see a dialague box to enter the publish profile name.

6-create-a-publish-profile

Image 5 : Create a Publish Profile

I’ll create it as “MyPublishProfile”. And click “OK”. Then the profile will be created and you will see new menus in the left hand side now.

7-selet-profile-menu

Image 6 : New menus will appear when Publish Profile created.

Then go to connection menu and select a folder to publish the web application. And Select the publish method as “File system”.

9-select-a-publish-location

Image 7 : Connection menu(Select Target Publish Folder)

Then go to the settings menu and you can select the target frameworks to publish the app.

8-target-runtme-any-settings

Image 8 : Default Settings Menu.

But according to above image, you can’t see a Target Runtime. 

By default it has set to “Any“. 

So I’m adding some target runtimes to project to show how the error is happening.

We have to add those settings to the project.json file in the web application project.

To see How to add Target Runtimes to project.json  Click Here…

If you have already added target  Runtimes, Now we are ready to publish the app.

So Right Click and Select Publish in the context menu and the publish window will open.

Publish to the Target Runtime of Windows 10

Then Click “Settings” and Select “Win10-x64” from the drop down list.

5-select-target-platform-10

Image 9 : Select Windows 10 as Target Runtime

Then Click Preview menu and verify is the details correct before publish your app.

6-conform-details-before-publish

Image 10 : Verify Publish information before publish the app

Then Click “Publish” and the application will publish to the selected folder. You will see publish details output window.

7-success-win-10

Image 11 : App has publish successfully for the Target Runtime of  Windows 10 x64

Then check the selected publish folder and you will see compiled files has published to the folder.

The “TestWebCore” app has publish to the target runtime of “Windows 10 64bit” successfully.

How The Error Occurred…

Publish to the Target Runtime of Windows 7

This is same as we published the app for Windows 10. But the only difference is we have to change the target runtime to “Win7-x64

11-publishing-to-win-764

Image 12 : Select Windows 7 x64 as Target Runtime

Then Click “Publish”.

When I did it, I got below error.

Could not find a part of the path ‘F:\Projects\TestWebCore\src\TestWebCore\bin\Release\netcoreapp1.0\win7-x64\TestWebCore.dll’.

12-error

Image 13 : Error Publishing app to Windows 7

How to Fix the Error

To publish without an error, what I did is ..

Run the Publish command in Command Prompt.

So Here is the way I did ..

13-publish-command

Image 14 : Run Publish command in Command Line

When you press “Enter” when type the publish command, you will see the application publish successfully.

14-published-to-win7-64

Image 15 : Successfully Published to Windows 7 x64

You can see the published files in the publish folder.

This Error is not happening

References…

To Learn More about Target Runtimes/Frameworks Click…

Publish Commands for .Net Core in Command Line Click…

How to Publish Self Contained Application…

Thanks !

Advertisements

How to add Target Runtimes to project.json in ASP.Net Core Project

To See how to create a .Net core app, Click here …

First Open the project and you can see there is a JSON file called “project.json”

3-app-created

Then click it and you will see the JSON content in that file.

The default JSON content like below.


{
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.1",
"type": "platform"
},
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.1",
"Microsoft.AspNetCore.Razor.Tools": {
"version": "1.0.0-preview2-final",
"type": "build"
},
"Microsoft.AspNetCore.Routing": "1.0.1",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0"
},

"tools": {
"BundlerMinifier.Core": "2.0.238",
"Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final",
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
},

"frameworks": {
"netcoreapp1.0": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
]
}
},

"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},

"runtimeOptions": {
"configProperties": {
"System.GC.Server": true
}
},

"publishOptions": {
"include": [
"wwwroot",
"**/*.cshtml",
"appsettings.json",
"web.config"
]
},

"scripts": {
"prepublish": [ "bower install", "dotnet bundle" ],
"postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
}
}

When we collapse the JSON content, we can see what are the main properties of the file..

12-default-project-json-file

So according to above image, there is no property to declare Target Runtimes.

So We have to add them manually according to our requirement.  I’m using windows based machines, so I’ll add windows operating systems as target runtimes.

13-add-runtimes-to-project-json


"runtimes": {
"win10-x64": {},
"win81-x64": {},
"win8-x64": {},
"win7-x64": {},
"win7-x86": {}
}

When you add this code, you could see the NuGet package references are restoring automatically in the right hand side .

14-restoring-packages

After It has completed, you are ready to publish the app.

Then Right click on the project and click “Publish”.

You will see the Publish window. And Go to the settings menu and you will see those runtimes has added to the target runtimes drop down list.

15-target-runtimes-in-publish

Important.

If you want to delete old published files when you are publishing a new version, Check the

“Delete all existing files prior to publish” check box..

16-delete-existing-files

Thanks !

How To Create .Net Core MVC Project

Open The Visual Studio 2015

Then File->New Project

->Select .Net Core

-> Select ASP.Net Core Web Application

-> And Add a name to the project (I have added “MyCoreApp2”)

1-create-project

Then Click “OK” Button And It will go to another window to select the project template.

Select “Web Application” and click OK.

2-select-web-application

Then Your Project will be created.

3-app-created

You will see the references are restoring and after it completed, Press F5. Then your new project will run with the default template.

4-default-app-runs

 

 

 

Create a File/Directory Transferring App in C#

Reason :

One of a application I’m developing generates many PDF files daily. So we delete them normally once a week or another time. But it is difficult to search files which has generated in a particular date or date range and copy them or delete them to another place. We had to do it manually.

Solution:

SO I created a small app to do it quickly. And I created a small app to show you how to create a example app to copy and delete directories/files from one place to another.

Steps :

1 .Create User Interface.

Here is the user interface I created..

2 drop folder open dialague

Image 1 : UI

We have to select folder path to the app. So I added two folder browse dialogues to select browse folders. You can select “Folder browser dialogue” control form tool box and drag and drop it into above form.

1 folder open dialague

Image 2 : Folder browse control

Then you can see those dialogue controls in bottom panel.

2. We have to Add function to “Source” button and “Destination” button to browse and select source folder path and destination folder path.

3 select directories with delete option

Image 3 : Source and Destination selecting


private void btnSource_Click(object sender, EventArgs e)
 {
 DialogResult result = folderBrowserDialogSourceDir.ShowDialog();
 if (result == DialogResult.OK)
 {
 textBox1.Text = this.folderBrowserDialogSourceDir.SelectedPath;
 }

}

private void btnDestination_Click(object sender, EventArgs e)
 {
 DialogResult result = folderBrowserDialogDestinationDir.ShowDialog();
 if (result == DialogResult.OK)
 {
 textBox2.Text = this.folderBrowserDialogDestinationDir.SelectedPath;
 }
 }

Then when you click one of “Source” or “Destination” buttons, a browser window will popup and you can select any folder.

3 select directories

Image 4 : Folder browser dialague

3. User can check the “Delete after transferring”  check box if he want to delete files from source folder after copy them to destination.

4.Next Add functions to “Transfer files” button  to transfer files when Click it. So I use “Button click” event.

Here is the code in this event.


private void btnTransfer_Click(object sender, EventArgs e)
 {
 try
 {
 string pathDestinationFolder = string.Format(@"{0}", textBox2.Text);

string pathSource = string.Format(@"{0}", textBox1.Text);

if (!string.IsNullOrWhiteSpace(pathSource) && !string.IsNullOrWhiteSpace(pathDestinationFolder))
 {
 DateTime selectedDate = Convert.ToDateTime(dpEffiectiveDate.Text);
 DirectoryCopy(pathSource, pathDestinationFolder, true, selectedDate);

if (chkDelete.Checked)
 {
 DeleteDirectories(pathSource, selectedDate);
 }

lblDirectoriesFound.Text = foundDirectories.ToString();
 lblTransferedFilesCount.Text = createdDirectories.ToString();
 lblDeleted.Text = deletedDirectories.ToString();
 lblNotTransfered.Text = (foundDirectories - createdDirectories).ToString();
 }
 else { MessageBox.Show("Source and destination is required", "Notification", MessageBoxButtons.OK, MessageBoxIcon.Information); }
 }
 catch (Exception ex)
 {
 MessageBox.Show(MethodBase.GetCurrentMethod() + " -> " + ex.Message);
 }
 }

I have extracted the function to copy directories and files to destination to a method “DirectoryCopy”.


private void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs, DateTime selectedDate)
 {
 try
 {
 #region check exists and create is not exists
 // Get the sub directories for the specified directory.
 DirectoryInfo dir = new DirectoryInfo(sourceDirName);
 DirectoryInfo[] dirs = dir.GetDirectories();

if (!dir.Exists)
 {
 throw new DirectoryNotFoundException(
 "Source directory does not exist or could not be found: "
 + sourceDirName);
 }

// If the destination directory doesn't exist, create it.
 if (!Directory.Exists(destDirName))
 {
 Directory.CreateDirectory(destDirName);
 createdDirectories = createdDirectories + 1;
 dirList.Add(destDirName);
 listViewDirectories.Items.Add("Created Directory -> " + destDirName);
 }

// Get the files in the directory and copy them to the new location.
 FileInfo[] files = dir.GetFiles();
 foreach (FileInfo file in files)
 {
 string temppath = Path.Combine(destDirName, file.Name);
 if (File.Exists(temppath))
 { }
 else
 {
 file.CopyTo(temppath, false);
 listViewDirectories.Items.Add("Coppied file -> " + temppath);
 }
 }
 #endregion
 // If copying subdirectories, copy them and their contents to new location.
 if (copySubDirs)
 {
 foreach (DirectoryInfo subdir in dirs)
 {
 if (subdir.CreationTime.Date == selectedDate.Date)
 {
 foundDirectories = foundDirectories + 1;
 string temppath = Path.Combine(destDirName, subdir.Name);
 DirectoryCopy(subdir.FullName, temppath, copySubDirs, selectedDate);
 }
 }
 }
 }
 catch (Exception ex)
 {
 MessageBox.Show(MethodBase.GetCurrentMethod()+" -> "+ ex.Message);
 }

}

“DirectoryCopy” Method is a recursive function.

Recursive function is a method which calls itself.

for more information go to =>Recursive function

7 use recursive function

Image 5 : Recursive function

The reason is some directories has one or more sub directories. So we have to go through all of them. So we have to loop through all directories in a same war. For that we have to use a Recursive function.

In “DirectoryCopy” method we have to use “FileInfo” class and “Directory“. SO we have to import System.IO namespace.


using System.IO;

[/code</blockquote>
In this method first we are checking directories in the source directory and we can watch information of source directory when debugging it.
<pre>

DirectoryInfo dir = new DirectoryInfo(sourceDirName);

4 file info creation date

Image 6 : File info -> Quick watch

According to my requirement  I get folders and files by its creation date. So I have to use "FileInfo" class to get values.

Then we have to get sub directories in the folder. For that I use GetDirectories() method.


DirectoryInfo[] dirs = dir.GetDirectories();

when debugging the code we can check whether it has sub directories or not.

5 sub directories

Image 7 : Directory info

  • According to above "older is exists and if it is not existing, Then I'm reading a folder to copy files.
  • And then read File information of containing files of resource folder and if its date is my selected date, then copy those files to selected destination.
  • Then show copied files and created folders in the list-box.

After copy files, In  Transfer button click event, then I check the "chkDelete" check box and if it is checked, Then program delete folders from source folder.

DeleteDirectories() is a recursive function too.


private void DeleteDirectories(string pathSource, DateTime selectedDate)
 {
 try
 {
 // Get the subdirectories for the specified directory.
 DirectoryInfo dirs = new DirectoryInfo(pathSource);
 DirectoryInfo[] dirList2 = dirs.GetDirectories();
 foreach (DirectoryInfo subdir in dirList2)
 {
 string subDirname = subdir.FullName;
 if (subdir.CreationTime.Date == selectedDate.Date)
 {
 deletedDirectories = deletedDirectories + 1;
 Directory.Delete(subDirname, true);
 listViewDirectories.Items.Add("Deleted Directory ->" + subDirname);
 }
 else
 {
 DeleteDirectories(subDirname, selectedDate);
 }
 }
 }
 catch (Exception ex)
 {
 MessageBox.Show(MethodBase.GetCurrentMethod() + " -> " + ex.Message);
 }
 }

Then we can see copied files , created directories and deleted directories in the list box.

8 final info

Image 8 : Final Result

And another thing is if an error occurred, System will shows the error message with the Method name. To get the method name that I used ..


MethodBase.GetCurrentMethod()

to use the MethodBase class we have to import ...


using System.Reflection;

To download the code go to Download.

Thanks !

Multiple substitutions specified in non-positional format; did you mean to add the formatted=”false” attribute?

Reason

My Xamarin project uses multiple languages and their translations are stored in Resource/.resx files. When I build the project in VS 2015 the android project not built successfully and it gave me an error…

Error

Multiple substitutions specified in non-positional format;
did you mean to add the formatted=”false” attribute?
Mobility_App.Droid F:\Mobility_App.Droid\Resources\Values-fr\AppResources.xml

1 error

Image 1 : Error

Reason

I search the error and I found the issue occurred because some <string> tags consists of percentage(%) symbol.

2 reason

Image 2 : Reason % symbol

Solution

To fix this error we have to add a attribute “Formatted” to <string> tags which are consists of ‘%’ symbols. and Set “Formatted” attribute’s value to “false”.

3 solution

Image 3 : add <string formatted=”false”>

Now the issue has fixed and to ensure, then rebuild the project and you can see the solution is success.

4 success

Image 4 : Successfully Build

Thanks you !

Convert from Multilingual App Toolkit v3.0 to v4.0 and Fix Error “The Multilingual App Toolkit v4.0 is not compatible with previous versions of the toolkit”

Reason

I used Multilingual App Toolkit 3.0 for my Xamarin application in Visual Studio 2013 in Windows 8.1. Then I moved to a new machine with windows 10 and I installed Visual Studio 2015. Then I opened that Xamarin project in VS 2015 and when I was building the project it gave me an error.

mla error 1

Image 1 : Error

Error

The imported project “C:\Program Files (x86)\MSBuild\Microsoft\Multilingual App Toolkit\Microsoft.Multilingual.ResxResources.targets” was not found.

Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

Mobility_App.Android

F:\ProjectsBuddhima\mobile\Mobility\Mobility App\Mobility_App.csproj

Reason

Then I searched solutions for the error and according to the error, my new machine has not installed Multilingual App Toolkit.

Solution and Next steps

So I installed Multilingual App Toolkit v.4.0 which is compatible with Visual Studio 2015.

You can download from

https://visualstudiogallery.msdn.microsoft.com/6dab9154-a7e1-46e4-bbfa-18b5e81df520

mla error 2

Image 2 : Download Multilingual App Toolkit v4.0

Then the installer will download to your machine and you have to install it manually.

After I installed Multilingual App toolkit 4.0 I built the project again and I got another error.

Multilingual App Toolkit v4.0 upgrade blocked

The Multilingual App Toolkit v4.0 is not compatible with previous versions of the toolkit

mla error 7

Image 3 : Multilingual app Toolkit is blocked

According to above error message, I browsed the link in the http://aka.ms/mat4faq

According to their technical references I will describe steps to convert from v3 to v4.

  1. First take a backup of existing project.
  2. Then we have to open the project which has Multilingual App toolkit v3.
  3. Then we have to disable app toolkit for projects. Go to tools and click “Disable Multilingual App Toolkit”.

    1 disable MLA tool kit

    Image 4 : Disable MLA Toolkit

  4. Then Copy current .xlf files to another location as a backup and delete all .xlf files in the project.

    2 remove xlf files

    Image 5 : Remove current XLF files

  5. Then rebuild the project.

 

Sometimes these steps are not enough to fully disable toe Multilingual App toolkit. So we have to disable it using config file manually.

Here are steps to remove them manually.

1.Right click the config file in the project and open it.
2.Search the label “MultilingualAppToolkit” in the config file.

12 multi languala app label

Image 6 : Delete property group from config file

3.Then delete above <PropertyGroup> which contains <MultilingualAppToolkitVirsion> tag.
4.Then we have to search again “MultilingualAppToolkit” label. And you will see <import> element.

13 delete multi languala import label

Image 7 : Delete <import> tag which contains MLA label

And also we have to delete the <Import> tag which contains “MultilingualAppToolkit”.

 

5.Then rebuild the project.

Now we have removed configurations of Multilingual App Toolkit from our project and we are ready to add v4.0 configurations.

Then we have to enable Multilingual App Toolkit from Toolbox.

1 Enable mltk

Image 8 : Enable MLA Toolkit

When we enable the Multilingual App Toolkit v4.0, we are ready to recycle Transitions from v3.0 project’s .xlf files.

Below I have added steps for that.

1.  Please check that the Multilingual App Toolkit v4.0 is enabled.

2. Then click on the project and select Multilingual App Toolkit=> Add transition languages

3 add multilangual languages

Image 9 : Multilingual App Toolkit ->  Add Transition languages

3. We can see language list in a window like below. Select languages that previously we have added to the project.

4 select languages

Image 10 : Select Languages

When click “OK”. New xlf files will be added to our project in a folder called “MultilingualResources”.  Below image shows it.

5 added xlf files

Image 11 : Added XLF files for selected languages

4. Then click on “MultilingualAppResources” folder and click .. Multilingual App Toolkit=> Import / recycling translations

6 import recycling transactions

Image 12 : Multilingual App Toolkit -> Import/Recycle Transitions

Then you will see below window.

7 import recycling transactions

Image 13 : Import Transition window

5. Click “Add button” and then select v3 xlf files from the location that we have copied from previous project.

8 select old v3 files

Image 14 : Select and Add  XML files in v3 project.

6. Then Select xlf files that we copied from the temporary location and Click “Open”. Then selected xlf files will be added to import resources form.

9 seletec xlf v3 files

Image 15 : Added XLF files

7. And an Important thing is we have to check the “Enable resource recycling” check box. And then click the import button.

10 enable recycling and import

Image 16 : Enable resource recycling and Import

8. Then rebuild the project.

11 success

Image 17 : Successfully Built project

Then we can see those .xlf files has been added to project and the project has built successfully.

Thank you !

Add Attributes to Resource(.resx) file from Excel file in C#

SUBJECT…

Today I’m going to create a windows form app to write items to application resource (.resx) file using data in a excel file.

REASON…

The reason I decided to develop this kind of app is, I’m working on a Xamarin project and it supports for English, French and Dutch. So I had to add translations for both two languages for English.

In Visual Studio we can Add Recourse key and value attributes manually using resx file. I’ll show you how we can do it manually.

3 add attributes manually 3

Image 1 : Add attributes manually to Resource file

What I had to do is copy Name and keys from above excel file and paste in to Name field and Key field one by one.

But it is not easy when there are thousands of Names and translations (keys). Because it’ll waste time.

MY SOLUTION…

So I decided to develop a small app to write resource attributes using a excel file to resx files.

I have two resource files for French and Dutch and you can see them under project resource folder in below image.

2 project style

Image 2 : Application design and class structure

Then I created a small windows form with two buttons for French and Dutch and a List view.

Now I’ll describe the coding part for above functionality.

First I have added resource file paths as attributes to App.config file.


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <appSettings>
    <add key="resPathFr" value="F:\My softwares\Excel to RESX\TranslationMobile\Translation\Properties\AppResources.fr.resx"/>
    <add key="resPathNl" value="F:\My softwares\Excel to RESX\TranslationMobile\Translation\Properties\AppResources.nl.resx"/>
  </appSettings>
</configuration>

Then Add the Excel file “Book1.xlsx” to Startup path  “//bin”.

Here is the format of the excel file I’m going to use..

1 Excel file

Image 3 : The Excel file which contains Translations

According to this excel file, Keys are in “ID” column which is column “A”. And English definitions are in column “B”, French/FR definitions are in column “D” and Dutch/NL definitions are in column “F”.

And These keys and definitions are stored in “Sheet1”.

Then I will add useful namespaces that we have to use in Form1.cs class additionally to default namespaces .


using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using System.Resources;
using System.Configuration;

We have to Add Office.Interop.Excel namespace from references like below image

4 add excel namespace

Image 4 : import Excel resource from references

Then I’ll add another class called “ResourcesFr” with two property to store Key, Value collection. But you can use a Dictionary<string,string> instead of using a Generic collection to store Keys and Values. Because we are using only two properties to store data.


public class ResourcesFr
 {
 public string Key { get; set; }
 public string Value { get; set; }
 }

Then we can start coding in Form1.

I’ll add five properties in Form one for Excel Application,Workbook, Sheet, Key/value list and another one for missing values.


namespace Translation
{
 public partial class Form1 : Form
 {
 public Form1()
 {
 InitializeComponent();
 }

List<ResourcesFr> keyList = new List<ResourcesFr>();

Excel.Application xlApp;
 Excel.Workbook xlWorkBook;
 Excel.Worksheet xlWorkSheet;
 object misValue = System.Reflection.Missing.Value;

}

}

Then Double Click the “Dutch button” in the Form1 and it’ll create a Button_Click event.


private void btnDutch_Click(object sender, EventArgs e)
{

}

In this event we can add code for read the excel file and populate key,value information to the keyList property that we declared in the top of the Form1 class.


        ///<summary>
        /// Add Dutch Translations
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDutch_Click(object sender, EventArgs e)
        {
            xlApp = new Excel.Application();
            // path of the Excel file
            string path = (Application.StartupPath + "\\Book1.xlsx");
            // Get Excel file to  xlWorkBook property
            xlWorkBook = xlApp.Workbooks.Open(path);
            // Get "Sheet1" as xlWorkSheet : you can see it in excel sheet image
            xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

            // In the excel sheet we have 322 rows, So I added go through the loop untill 322
            for (int i = 1; i < 322; i++)
            {
                ResourcesFr fr = new ResourcesFr();
                string s = "";
                string s2 = "";
                s = string.Format("A"); // The Key(ID) is in Column A
                s2 = string.Format("F"); // The Value(Text (NL)) is in Column F
                if (xlWorkSheet.Cells[i, s].Value != null)
                {
                    // Get Key
                    fr.Key = xlWorkSheet.Cells[i, s].Value.ToString();
                    //Get Value
                    fr.Value = (xlWorkSheet.Cells[i, s2].Value != null) ? xlWorkSheet.Cells[i, s2].Value.ToString() : "";
                    // Add Key and Value to List<ResourcesFr> keyList
                    keyList.Add(fr);
                }
            }
            // CLose the Excel workbook
            xlWorkBook.Close(true, misValue, misValue);
            // Exit form Excel
            xlApp.Quit();

            // Clean the memory
            ReleaseObject(xlWorkSheet);
            ReleaseObject(xlWorkBook);
            ReleaseObject(xlApp);

            AddMemoLine("Dutch");
            int c = 0;
            foreach (var f in keyList)
            {
                // Insert or Update values
                AddOrUpdateResource(f.Key, f.Value, "NL");
                c++;
                // write in List view
                AddMemoLine(string.Format("Key : {0},       Value : {1}", f.Key, f.Value));
            }
            MessageBox.Show("Dutch resx properties has updated");
        }

ReleaseObject() Method does clean the Garbage collection and get the unused memory.


private void ReleaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show(&quot;Unable to release the Object &quot; + ex.ToString());
}
finally
{
GC.Collect();
}
}

AddOrUpdate() Method does Insert new record to resource file if it is not existing or update the existing record if it is existing.


        ///
<summary>
        /// update resource file
        /// </summary>

        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="lang"></param>
        public void AddOrUpdateResource(string key, string value, string lang)
        {
            try
            {
                // Get Resource File Path
                string resPath = string.Empty;
                if (lang == "FR")
                {
                    resPath = ConfigurationManager.AppSettings["resPathFr"];
                }
                else if (lang == "NL")
                {
                    resPath = ConfigurationManager.AppSettings["resPathNl"];
                }
                else { }
                if (!string.IsNullOrWhiteSpace(resPath))
                {
                    var resx = new List<DictionaryEntry>();
                    using (var reader = new ResXResourceReader(resPath))
                    {
                        resx = reader.Cast<DictionaryEntry>().ToList();

                        // Check if the key is existing
                        var existingResource = resx.Where(r => r.Key.ToString() == key).FirstOrDefault();

                        // Insert new Record if the key is not existing
                        if (existingResource.Key == null && existingResource.Value == null) // NEW!
                        {
                            resx.Add(new DictionaryEntry() { Key = key, Value = value });
                        }
                        else // MODIFIED RESOURCE!
                        {
                            var modifiedResx = new DictionaryEntry() { Key = existingResource.Key, Value = value };
                            resx.Remove(existingResource);  // REMOVING RESOURCE!
                            resx.Add(modifiedResx);  // AND THEN ADDING RESOURCE!
                        }
                    }

                    // Write resources to resx file
                    using (var writer = new ResXResourceWriter(resPath))
                    {
                        resx.ForEach(r =>
                        {
                       // Again Adding all resource to generate with final items
                       writer.AddResource(r.Key.ToString(), r.Value.ToString());
                        });
                        writer.Generate();
                    }
                }

            }
            catch (Exception ex)
            {
                AddMemoLine(string.Format("Key : {0},  Value : {1},  Lang{2}  Throws an error {3}  ", key,value, lang,ex.Message));
            }
        }

And MemoLine() Method does insert an  item to list view.. Then user can see what is happening now..


        ///
<summary>
        /// Insert a record to List view..
        /// </summary>

        /// <param name="data"></param>
        private void AddMemoLine(string data)
        {
            txtResultList.AppendText(data);
            txtResultList.AppendText(Environment.NewLine);
        }

Then run the program and Click the “Dutch” button and you will see update/Inserted records in few seconds.

5 final result

Image 5 : Adding Attributes to resource file

Then close the program and Open the resource file Resource.nl.resx and you will see all records in the excel sheet has transferred to the resx file.

6 resx resource file updated

Added attributes to Resources.nl.resx

You can do the Same thing to “French button”. And You can download the full project using below link.

Download the project file

Thanks !

Buddhima Kudagama

kgbuddhima@gmail.com