
Re-visiting the gmail official blog, I found that they have an update on Aug 26 saying this feature is only available in the US. Thus, this feature is not useful to me.
I have been using BIOSAgent since 2007 when I was working in a project that extensively dealt with system detection. It helped me to fix a lot BIOS issues by providing me every single piece of information stored in the BIOS. Sadly, this wonderful desktop, standalone BIOSAgent is no longer available for download now. The last version is 3.66. I don't have the last version but up to v3.61.
BIOSAgentPlus is the successor or the replacement. The current version I tested is 2.2010.1.8. Unlike BIOSAgent, BIOSAgentPlus requires Internet connection for data interpretation. It doesn't scan your system over the Internet; currently you still have to download an EXE file to do the scanning and then interpret the scanned data at their online server.
Basically, there are two ways to submit the scanned data:
If the scanned data is auto-fetched by your local copy of BIOSAgentPlus, the result page will display not only the information of the BIOS but also every driver of your system. Any new driver(s) available to your system will also be shown in that page. If you post the data yourself, the BIOS information will not be displayed but you are still able to view the information of your existing and new available drivers online. Thus, the manual method at this point is useless. After all, the data is actually interpreted by DriverAgent, which won't interpret BIOS data.
If you scan your system offline, BIOSAgentPlus will automatically open a text XML file for you. Do a search on <D:smbios> in the file and you should find all the BIOS data. On XP, this file is stored in the folder of %TEMP%\DriverAgent.
Regardless of which method you use to submit and interpret the scanned data, you can always be allowed to choose to "Save Scan Data" for future use. This simply saves the reference data in a HTML file. Next time, you double-click on it and the data will be fetched and viewed from their online server. Again, Internet connection is absolutely required. With this, the BIOS data is always interpreted and displayed in the page.
I personally don't like the BIOSAgentPlus because I am not interested in the driver information or its upgrade. I just want to instantly see what data was written in the BIOS. In addition, when I am doing this, most of time the Internet connection is not available or the system has not completely configured well yet. With BIOSAgentPlus, I have to do more steps to view the data or I interpret data myself. I really miss the nice and simple BIOSAgent.
As usual, the downloaded EXE file doesn't require to install; simply download and run it. When BIOSAgentPlus runs and performs the scanning, on XP, the BIOSAgentAgent icon will be displayed in your system tray.
Right click the icon, select "Work Offline" if the Internet connection is not available. If you need scan again, then click "Scan". Note that The Scan button will be grayed out while BIOSAgentPlus is scanning.
As soon as the scanning is done, a text file named DriverAgent.xml.txt will be opened for you. Follow the instruction in that file and submit its XML content to http://driveragent.com/manual.php. As discussed before, the BIOS information will not be interpreted when you manually submit data to DriverAgent.
MagicJack has done some upgrade within these two weeks that cause some users' contact list wiped forever (see their current announcement or the captured image). In addition, the MagicJack drives are no longer accessible after the softphone has been up and running; both drives occupied by MagicJack become "CD Drive" and "Removable Disk" while the softphone is in service.
Drives while softphone is loading | Drives after softphone is loaded | |
Accessible | Inaccessible |
I am lucky still to find my contacts list file in the device. Yours may still exist. See my how-to for details.
From now on, all the profile information including the contacts list and the call history will be stored in the MagicJack server. Thus, your softphone may indicate "Contacts list is empty" after the upgrade regardless of the file existence in your device. Currently there is no way to upload the list to the server but manually input yourself.
Next month I will go Hong Kong for visit. At the same time, I may go Shanghai for a few days if possible. I found that quite a lot of people now go by train instead of flight. Thus I started my research on train. There is a direct train traveling between Hong Kong and Shanghai. Each way operates every other day.
I am surprised that a lot of people emphasized in their blogs to look for the word Jiulong for buying return train ticket in China. Huh? Jiulong? Where is it? Should it be Hong Kong? Some place in Hong Kong? Or the train station in Hong kong?
The train station in Hong Kong to Shanghai is called Hung Hom Train Station and located in Kowloon, Hong Kong. There is no place or a train station in Hong Kong called Jiulong. Then where is Jiulong?
After having done some digging, I finally reach my conclusion. Jiulong is the direct translation from Mandarin pronunciation to English. It is actually referring to Kowloon, the official name in Hong Kong. Why did China make this new name to Kowloon, Hong Kong? Has Kowloon already had a name in English? It is extremely confusing. This makes me wonder that Hong Kong may have a new name in English soon. 50 years unchanged? Certainly something have been changed on their ways. Look! The name is one of the changes. Would Hong Kong be called Xiang Gang in English in the future or whatever name in Mandarin? Note that Xiang Gang is the Mandarin pronunciation in English for "Hong Kong" according to one of the online dictionaries. Please correct me if it is incorrect.
Will Hong Kong people accept this new name? Unfortunately, a lot of people don't even know.
Today is my lucky and happy day. I finally got certified with ASP.NET 3.5. I was preparing it for the past few months. Today I finally get an award of it.
My exam time was scheduled at 11:30AM today. I left and headed to the test center an hour ahead of my exam time. It was just about 10 minutes drive but I was almost late and missed the time because of the incorrect Google map. I kept calling the test center but I could not reach anyone. I was panic and even thought that I might be doomed today. The time was ticking and I had only 10 minutes left. Finally, my call got through and I arrived just right on time. Still, my feeling was not so good that I was afraid what happened before was to give me some sort of symbolic or indication that I could fail my exam. However, the result turns out fantastic (a perfect one) and it makes me keep smiling.
The actual exam time lasts 180 minutes (3 hours) for 45 questions. But my confirmation sheet (from Prometric registration) said 4 hours because the additional hour was used for reading instructions, answering questions for survey (compulsorily) and leaving comments to questions after test (voluntarily). When I started taking the exam, the time was set to 180 and then counted down. I spent about 2 hours and read twice. The full score is 1000 and the passing mark is 700.
In the past few months, one of my laptops running with windows XP responded very slowly to both double-click and right-click. Double-click to open a photo less than 1 KB takes more than a minute while the right-click sometimes might freeze the Windows Explorer. Everything works fine if I use the program to open it. This problem is not specific to any type of files.
Unlike others, this laptop didn't install many applications. It doesn't even have Microsoft Office on it. But it carries adobe reader, Nero burning software, AVG anti-virus, Spybot Seach & Destroy, and the default graphic card software by Intel. That's. It was used to be super fast.
Using ShellExView for diagnostics and disabling every single Context Menu Handler, Icon Handler and Property Sheet don't help. Finally the System File Checker (sfc) command fixed the problem.
sfc /scannow
Be sure to have your Windows installation CD ready before you issue the above command.
Now I enabled all the extensions that were disabled via ShellExView. Everything is back to normal now.
In this article, it mentions Context Menu handler for Intel® Graphics could be the possible culprit. But it isn't in my case. The problem I had was not only right-click but also double-click. Thus, if you have the similar trouble, you may have to trial-and-error to rule out the issue. Using ShellExView to find the root cause is extremely time-consuming because every change you make require a reboot in order to see the actual effect. Luckily I finally have my problem solved.
Oftentimes we encounter problems when we perform update using LoadDataRow or rollback data using RejectChanges after the Delete method. Why do the methods sometimes not do what we want?
Googling a solution for LoadDataRow, we may find that most people resolve the update performed by LoadDataRow must call DataTable.AcceptChanges first. Does this solution work for you 100%? There are still some unresolved posts left unanswered. They follow the solution to call AcceptChanges but the problem still exists. Why?
Deleting a DataRow and then immediately performing RejectAccepts to rollback cause us to receive System.Data.RowNotInTableException. What is it going on? Is the DataRow marked as Deleted? Why can't I rollback?
The above problems are related to either the RowState of a DataRow or if we set up the constraints on DataTable correctly.
Assuming there is no constraint problem, the DataRow must be either Unchanged or Modified
when we perform an update using the LoadDataRow method on an existing DataRow.
The same principle applies to the RejectChanges after calling
the Delete method. Apparently, the operations requires an Original version existed for
the DataRow. When the RowState of DataRow is Unchanged or Modified, an Original version
of the DataRow has been created/existed. Thus, any operations after it won't cause a problem.
If you receive a System.Data.ConstraintException in regard to
System.Data.UniqueConstraint.CheckConstraint, please ensure the primary key set up properly.
Most likely, setting the Unique property of a DataColumn without primary key to true will
cause this problem to occur.
If you receive a System.Data.ConstraintException in regard to
System.Data.DataTable.EnableConstraints, please ensure an Original version existed for the
DataRow. It means the RowState of the DataRow is still in the state of Added and you need to commit
changes first by calling the AcceptChanges method to update the state to Unchanged.
Similarly, if you receive a System.Data.RowNotInTableException when you try to roll back
the DataRow after having called the Delete method, a AcceptChanges call is required before
the Delete method. After AcceptChanges, an Original version of the DataRow is created and
the RowState of the DataRow is set to Unchanged. From this state onwards, any modification
including the LoadDataRow method, or calling the Delete method and then the RejectChanges
method can be performed.
Detached | The DataRow is created but it hasn't been added to a DataTable yet. Since it does not exist in a DataTable, no operations can be performed at the DataTable level. |
---|---|
Added | The DataRow is added to a DataTable but the DataTable has not accepted changes yet. At this stage, it requires AcceptChanges to create Original version for other update operations including rollback. |
Unchanged | The DataRow has not changed since the last AcceptChanges call. At this stage, an Original version of the DataRow has already existed. Thus, any operations can be performed without a problem. |
Modified | The DataRow has been modified since the last AcceptChanges call. Like Unchanged, an Original version of the DataRow has already existed in this stage. A DataRow with Modified row state can continously be modified but the RejectChanges will only roll the data back to the last AcceptChanges call. Any modification made in between is disgarded because the Original version of the DataRow is only pointing the copy when the last AcceptChanges is called. |
Deleted | The DataRow was deleted by using the Delete method of the DataRow only when the RowState of the DataRow is Unchanged or Modified. |
I also attach some test results I conducted for reference.
See The LoadDataRow and Delete Methods of DataTable for intention.
The following 3 tests [ Test 1 | Test 2 | Test 3 ] tell you about in which situation you can roll back your data and when you cannot.
This page is generated by the application developed in C# under Visual 2008 Profession SP + .NET 3.5 SP1 on Windows XP Professional SP3.
EmpId | FirstName | LastName | Salary | LastName and FirstName | RowState |
---|---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye | Added |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex | Added |
EmpId | FirstName | LastName | Salary | LastName and FirstName | RowState |
---|---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye | Added |
This row has been removed from a table and does not have any data. BeginEdit() will allow creation of new data in this row.
System.Data.RowNotInTableException
at System.Data.DataRow.GetDefaultRecord() at System.Data.DataColumn.CheckNullable(DataRow row) at System.Data.DataColumn.CheckColumnConstraint(DataRow row, DataRowAction action) at System.Data.DataTable.RaiseRowChanging(DataRowChangeEventArgs args, DataRow eRow, DataRowAction eAction, Boolean fireEvent) at System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Int32 position, Boolean fireEvent, Exception& deferredException) at System.Data.DataTable.SetNewRecord(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Boolean fireEvent) at System.Data.DataTable.RollbackRow(DataRow row) at System.Data.DataRow.RejectChanges() ...
EmpId | FirstName | LastName | Salary | LastName and FirstName | RowState |
---|---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye | Added |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex | Added |
EmpId | FirstName | LastName | Salary | LastName and FirstName | RowState |
---|---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye | Unchanged |
? | ? | ? | ? | ? | Deleted |
EmpId | FirstName | LastName | Salary | LastName and FirstName | RowState |
---|---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye | Unchanged |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex | Unchanged |
EmpId | FirstName | LastName | Salary | LastName and FirstName | RowState |
---|---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye | Added |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex | Added |
row.BeginEdit(); row["FirstName"] = "Susan";
EmpId | FirstName | LastName | Salary | LastName and FirstName | RowState |
---|---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye | Unchanged |
B223456789 | Susan | Bloomer | 12.00 | Bloomer, Rex | Unchanged |
row.EndEdit();
EmpId | FirstName | LastName | Salary | LastName and FirstName | RowState |
---|---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye | Unchanged |
B223456789 | Susan | Bloomer | 12.00 | Bloomer, Susan | Modified |
EmpId | FirstName | LastName | Salary | LastName and FirstName | RowState |
---|---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye | Unchanged |
? | ? | ? | ? | ? | Deleted |
EmpId | FirstName | LastName | Salary | LastName and FirstName | RowState |
---|---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye | Unchanged |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex | Unchanged |
See The LoadDataRow and Delete Methods of DataTable for intention.
employee.LoadDataRow( new object[] { "B223456789", "Denise", "Miller", 13.00 }, false); // don't AcceptChangesWhen primary key is applied, the following statement is used and it will be executed before the LoadDataRow method:
employee.PrimaryKey = new DataColumn[] {eid}; // eid is the EmpId column
ColumnName | EmpId | FirstName | LastName | Salary | LastName and FirstName ** |
---|---|---|---|---|---|
DataType | string | string | string | decimal | string |
MaxLength | 10 | 35 | -1 | -1 | 70 |
Unique | true | false | false | false | false |
AllowDBNull | false | false | false | true | true |
** The column of LastName and FirstName is defined as an expression column containing the values from the column of LastName and the column of FirstName.
Every test is based on this table with the initial sample data. The 2nd row is the target to update by using the LoadDataRow method. A grid shown in each test is represented the final result of the DataTable even though the update performed by the LoadDataRow method may fail. Execution messages about the RowState of the 2nd row and its versions are shown afterwards. For clarity, the initial state of the 2nd row is also attached to each test for reference.
The rest of the page is generated by the application developed in C# under Visual 2008 Profession SP + .NET 3.5 SP1 on Windows XP Professional SP3.
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex |
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex |
Column 'EmpId' is constrained to be unique. Value 'B223456789' is already present.
System.Data.ConstraintException
at System.Data.UniqueConstraint.CheckConstraint(DataRow row, DataRowAction action) at System.Data.DataTable.RaiseRowChanging(DataRowChangeEventArgs args, DataRow eRow, DataRowAction eAction, Boolean fireEvent) at System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Int32 position, Boolean fireEvent, Exception& deferredException) at System.Data.DataTable.InsertRow(DataRow row, Int32 proposedID, Int32 pos, Boolean fireEvent) at System.Data.DataRowCollection.Add(Object[] values) at System.Data.DataTable.UpdatingAdd(Object[] values) at System.Data.DataTable.LoadDataRow(Object[] values, Boolean fAcceptChanges) ...
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex |
Column 'EmpId' is constrained to be unique. Value 'B223456789' is already present.
System.Data.ConstraintException
at System.Data.UniqueConstraint.CheckConstraint(DataRow row, DataRowAction action) at System.Data.DataTable.RaiseRowChanging(DataRowChangeEventArgs args, DataRow eRow, DataRowAction eAction, Boolean fireEvent) at System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Int32 position, Boolean fireEvent, Exception& deferredException) at System.Data.DataTable.InsertRow(DataRow row, Int32 proposedID, Int32 pos, Boolean fireEvent) at System.Data.DataTable.UpdatingAdd(Object[] values) at System.Data.DataTable.LoadDataRow(Object[] values, Boolean fAcceptChanges) ...
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex |
Column 'EmpId' is constrained to be unique. Value 'B223456789' is already present.
System.Data.ConstraintException
at System.Data.UniqueConstraint.CheckConstraint(DataRow row, DataRowAction action) at System.Data.DataTable.RaiseRowChanging(DataRowChangeEventArgs args, DataRow eRow, DataRowAction eAction, Boolean fireEvent) at System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Int32 position, Boolean fireEvent, Exception& deferredException) at System.Data.DataTable.InsertRow(DataRow row, Int32 proposedID, Int32 pos, Boolean fireEvent) at System.Data.DataRowCollection.Add(Object[] values) at System.Data.DataTable.UpdatingAdd(Object[] values) at System.Data.DataTable.LoadDataRow(Object[] values, Boolean fAcceptChanges) ...
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Denise | Miller | 13.00 | Miller, Denise |
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex |
B223456789 | Denise | Miller | 13.00 | Miller, Denise |
BeginLoadData(): turn off notification/constraints/indexing.
Executing LoadDataRow(...)EndLoadData(): turn on validation, constraints, etc.
Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
System.Data.ConstraintException
at System.Data.DataTable.EnableConstraints() at System.Data.DataTable.set_EnforceConstraints(Boolean value) at System.Data.DataTable.EndLoadData() ...
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex |
B223456789 | Denise | Miller | 13.00 | Miller, Denise |
BeginLoadData(): turn off notification/constraints/indexing.
Executing LoadDataRow(...)EndLoadData(): turn on validation, constraints, etc.
Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
System.Data.ConstraintException
at System.Data.DataTable.EnableConstraints() at System.Data.DataTable.set_EnforceConstraints(Boolean value) at System.Data.DataTable.EndLoadData() ...
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Denise | Miller | 13.00 | Miller, Denise |
BeginLoadData(): turn off notification/constraints/indexing.
Executing LoadDataRow(...)EndLoadData(): turn on validation, constraints, etc.
[B223456789, Denise] RowState: ModifiedSee The LoadDataRow and Delete Methods of DataTable for intention.
employee.LoadDataRow( new object[] { "B223456789", "Denise", "Miller", 13.00 }, LoadOption.OverwriteChanges);When primary key is applied, the following statement is used and it will be executed before the LoadDataRow method:
employee.PrimaryKey = new DataColumn[] {eid}; // eid is the EmpId column
ColumnName | EmpId | FirstName | LastName | Salary | LastName and FirstName ** |
---|---|---|---|---|---|
DataType | string | string | string | decimal | string |
MaxLength | 10 | 35 | -1 | -1 | 70 |
Unique | true | false | false | false | false |
AllowDBNull | false | false | false | true | true |
** The column of LastName and FirstName is defined as an expression column containing the values from the column of LastName and the column of FirstName.
Every test is based on this table with the initial sample data. The 2nd row is the target to update by using the LoadDataRow method. A grid shown in each test is represented the final result of the DataTable even though the update performed by the LoadDataRow method may fail. Execution messages about the RowState of the 2nd row and its versions are shown afterwards. For clarity, the initial state of the 2nd row is also attached to each test for reference.
The rest of the page is generated by the application developed in C# under Visual 2008 Profession SP + .NET 3.5 SP1 on Windows XP Professional SP3.
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex |
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex |
Column 'EmpId' is constrained to be unique. Value 'B223456789' is already present.
System.Data.ConstraintException
at System.Data.UniqueConstraint.CheckConstraint(DataRow row, DataRowAction action) at System.Data.DataTable.RaiseRowChanging(DataRowChangeEventArgs args, DataRow eRow, DataRowAction eAction, Boolean fireEvent) at System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Int32 position, Boolean fireEvent, Exception& deferredException) at System.Data.DataTable.InsertRow(DataRow row, Int32 proposedID, Int32 pos, Boolean fireEvent) at System.Data.DataTable.LoadRow(Object[] values, LoadOption loadOption, Index searchIndex) at System.Data.DataTable.LoadDataRow(Object[] values, LoadOption loadOption) ...
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Denise | Miller | 13.00 | Miller, Denise |
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex |
Column 'EmpId' is constrained to be unique. Value 'B223456789' is already present.
System.Data.ConstraintException
at System.Data.UniqueConstraint.CheckConstraint(DataRow row, DataRowAction action) at System.Data.DataTable.RaiseRowChanging(DataRowChangeEventArgs args, DataRow eRow, DataRowAction eAction, Boolean fireEvent) at System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Int32 position, Boolean fireEvent, Exception& deferredException) at System.Data.DataTable.InsertRow(DataRow row, Int32 proposedID, Int32 pos, Boolean fireEvent) at System.Data.DataTable.LoadRow(Object[] values, LoadOption loadOption, Index searchIndex) at System.Data.DataTable.LoadDataRow(Object[] values, LoadOption loadOption) ...
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Denise | Miller | 13.00 | Miller, Denise |
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Rex | Bloomer | 12.00 | Bloomer, Rex |
B223456789 | Denise | Miller | 13.00 | Miller, Denise |
BeginLoadData(): turn off notification/constraints/indexing.
Executing LoadDataRow(...)EndLoadData(): turn on validation, constraints, etc.
Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
System.Data.ConstraintException
at System.Data.DataTable.EnableConstraints() at System.Data.DataTable.set_EnforceConstraints(Boolean value) at System.Data.DataTable.EndLoadData() ...
EmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Denise | Miller | 13.00 | Miller, Denise |
BeginLoadData(): turn off notification/constraints/indexing.
Executing LoadDataRow(...)EndLoadData(): turn on validation, constraints, etc.
[B223456789, Denise] RowState: UnchangedEmpId | FirstName | LastName | Salary | LastName and FirstName |
---|---|---|---|---|
A123456789 | Bettye | Williams | 11.00 | Williams, Bettye |
B223456789 | Denise | Miller | 13.00 | Miller, Denise |
BeginLoadData(): turn off notification/constraints/indexing.
Executing LoadDataRow(...)EndLoadData(): turn on validation, constraints, etc.
[B223456789, Denise] RowState: UnchangedThere are a few ways to extract a file extension from a file name. One of the simple ways is to use System.IO.Path.GetExtension() method by passing the file name as a parameter, e.g.,
System.IO.Path.GetExtension("abc.txt")
In this example, .txt is the extracted file extension and it always comes with a leading period (.). In order to fit our 1st requirement, we could remove the leading period from the resulted file extension. Unfortunately, the requirement binds us to use regular expression. Thus, the regular expression should look like the following (non-named capturing):
\.([^.]+)$
According to the 2nd requirement (the extension cannot contain spaces), the previous regular expression is revised and becomes:
\.([^(\s|.)]+)$
In C#, we can do the following to fulfill the #1 and the #2 requirements:
String pattern = @"\.([^(\s|.)]+)$"; String fileExt = null; Regex r = new Regex(pattern); Match m = r.Match(filename); if (m.Success) { fileExt = m.Groups[1].Value; }
As we can see, the captured text is always placed inside the group 1 (at index 1), not 0. What if we have many captured groups? It could be hard to remember which one is what. Luckily, .NET supports name capturing. It greatly helps in coding and back-reference. In this example, the requirement is simple and we don't have to use named capture. But to exercise this named capture feature, we could revise the regular expression a bit and then reference the name in our code. Let's say that the captured text name is called ext. The revised code snippet becomes:
String pattern = @"\.(?<ext>[^(\s|.)]+)$"; String fileExt = null; Regex r = new Regex(pattern); Match m = r.Match(filename); if (m.Success) { fileExt = m.Groups["ext"].Value; }
A part of the third requirement is to check the resulted file extension against our supported file extension list. We can continuously get help from regular expression. Let's define our pattern for matching. In C#, we can write this:
String SupportedImageExtPatterns = "^(BMP|GIF|PNG|TIFF|JPE?G)$";
To check the resulted file extension against the list, in C#, we can implement this way:
Match m1 = Regex.Match(fileExt, SupportedImageExtPatterns, RegexOptions.IgnoreCase); if (m1.Success) { ... }or using one single statement,
if (Regex.Match(fileExt, SupportedImageExtPatterns, RegexOptions.IgnoreCase).Success) { ... }
How to check the file is one of the supported image format? Since the file is uploaded via HTTP, the file could be anything. For this matter, we first need to confirm if the file is an image by referencing to the file's Stream object and then try to convert it to an image. If we get an ArgumentException, it is not an image. Let's say the file upload object is called FileUpload1. In C#, we can write the following to execute the idea.
System.Drawing.Image theImage = null; try { theImage = System.Drawing.Image.FromStream(FileUpload1.PostedFile.InputStream); } catch (System.ArgumentException) { // not an image ... }After we've confirmed that the file is an image, we can go ahead to check the image format against our list with the help of the Equals() method of System.Drawing.Imaging.ImageFormat. For convenience, I group all the required System.Drawing.Imaging.ImageFormat objects together in an array so that I can iterate through the array for checking.
System.Drawing.Imaging.ImageFormat[] SupportedImageFormats = { System.Drawing.Imaging.ImageFormat.Bmp, System.Drawing.Imaging.ImageFormat.Gif, System.Drawing.Imaging.ImageFormat.Png, System.Drawing.Imaging.ImageFormat.Tiff, System.Drawing.Imaging.ImageFormat.Jpeg };
System.Drawing.Imaging.ImageFormat[] SupportedImageFormats = { System.Drawing.Imaging.ImageFormat.Bmp, System.Drawing.Imaging.ImageFormat.Gif, System.Drawing.Imaging.ImageFormat.Png, System.Drawing.Imaging.ImageFormat.Tiff, System.Drawing.Imaging.ImageFormat.Jpeg }; System.Drawing.Image theImage = null; try { theImage = System.Drawing.Image.FromStream(FileUpload1.PostedFile.InputStream); for (int i=0; i < SupportedImageFormats.Length; i++) { if (theImage.RawFormat.Equals(SupportedImageFormats[i])) { ... break; } } ... } catch (System.ArgumentException) { // not an image ... }
As soon as we confirm that the file is an image and it is also one of our expected formats, we can simply use the FileUpload object SaveAs() method by passing the absolute pathname. Let's say the directory to save is called Uploads. The statement may look something like below:
FileUpload1.SaveAs(Server.MapPath("~/Uploads/") + FileUpload1.FileName);Up to here, our mission is accomplished from extracting the file extension, checking image format to saving the file. The complete code snippets are presented in the next section.
The followings are two pieces of code snippets summarized for the above discussions. The difference between these two pieces of code is: one is using non-named capture to extract the file extension while the other is named capture. Other than that, everything is identical.
// declare the pattern for Requirement #1 and #2 to capture the file extension. // the following pattern is using non-named capture. String pattern = @"\.([^(\s|.)]+)$"; String fileExt = null; Regex r = new Regex(pattern); Match m = r.Match(FileUpload1.PostedFile.FileName); if (m.Success) { // capture the file extension without the period // here we use non-named capture group fileExt = m.Groups[1].Value; // Requirement #4 - the supported file extensions String SupportedImageExtPatterns = "^(BMP|GIF|PNG|TIFF|JPE?G)$"; if (Regex.Match(fileExt, SupportedImageExtPatterns, RegexOptions.IgnoreCase).Success) { // Requirement #5 - the supported image formats System.Drawing.Imaging.ImageFormat[] SupportedImageFormats = { System.Drawing.Imaging.ImageFormat.Bmp, System.Drawing.Imaging.ImageFormat.Gif, System.Drawing.Imaging.ImageFormat.Png, System.Drawing.Imaging.ImageFormat.Tiff, System.Drawing.Imaging.ImageFormat.Jpeg }; System.Drawing.Image theImage = null; try { theImage = System.Drawing.Image.FromStream(FileUpload1.PostedFile.InputStream); for (int i=0; i < SupportedImageFormats.Length; i++) { if (theImage.RawFormat.Equals(SupportedImageFormats[i])) { // Requirement #3 - save the file only if it is our expected image format. FileUpload1.SaveAs(Server.MapPath("~/Uploads/") + FileUpload1.FileName); break; } } } catch (System.ArgumentException) { // not an image ... } } }
// declare the pattern for Requirement #1 and #2 to capture the file extension. // the following pattern is using named capture. String pattern = @"\.(?<ext>[^(\s|.)]+)$"; String fileExt = null; Regex r = new Regex(pattern); Match m = r.Match(FileUpload1.PostedFile.FileName); if (m.Success) { // capture the file extension without the period // here we use named capture group fileExt = m.Groups["ext"].Value; // Requirement #4 - the supported file extensions String SupportedImageExtPatterns = "^(BMP|GIF|PNG|TIFF|JPE?G)$"; if (Regex.Match(fileExt, SupportedImageExtPatterns, RegexOptions.IgnoreCase).Success) { // Requirement #5 - the supported image formats System.Drawing.Imaging.ImageFormat[] SupportedImageFormats = { System.Drawing.Imaging.ImageFormat.Bmp, System.Drawing.Imaging.ImageFormat.Gif, System.Drawing.Imaging.ImageFormat.Png, System.Drawing.Imaging.ImageFormat.Tiff, System.Drawing.Imaging.ImageFormat.Jpeg }; System.Drawing.Image theImage = null; try { theImage = System.Drawing.Image.FromStream(FileUpload1.PostedFile.InputStream); for (int i=0; i < SupportedImageFormats.Length; i++) { if (theImage.RawFormat.Equals(SupportedImageFormats[i])) { // Requirement #3 - save the file only if it is our expected image format. FileUpload1.SaveAs(Server.MapPath("~/Uploads/") + FileUpload1.FileName); break; } } } catch (System.ArgumentException) { // not an image ... } } }
Also see the update on Jan 5, 2011.
Facebook has been changing a lot since this March and they still keep changing. Have you ever noticed the above setting in the red box?
You can find this setting at your personal profile page. Go to your profile, locate the "Share" button. Right below it, click on "Settings," you will find the above settings circling by the red box.
If you change the setting for "Who can see posts made by friends?" to "Only Me," the check box for "Posting Ability" will be grayed out and become unchecked. It means no one or application can post anything to your wall. Unfortunately you won't notice this change unless you immediately refresh the page and then go back to the same location to check on it. Or you may know this problem when someone notifies you.
These above two settings are supposedly corresponding to the settings at your privacy settings page. Again, it is confusing. After the changes made from your profile page, if you go and check your privacy settings page, you will find this confusing settings as shown in the following picture.
The following information applies to version 5.1 up to the current latest version 5.6.8. It may apply to the future versions. However, if you're using the latest one (5.6.8), the GUI now provides a nice setting for you to change (Settings -> Preferences -> New Document/Default Directory). If you use the GUI to change the settings, the following manual method may not work. I don't know where another configuration files are stored.
Important: Don't use the same version of Notepad++ to edit any its configuration files. Otherwise, all your changes or modifications will be lost when you exit.
Note that I use Notepad++ zip version and do the manual installation instead of using the executable installer. Thus, your installed file structure may be different from mine if you're using installer.
<GUIConfig name="NewDocDefaultSettings" format="0" encoding="1" lang="0" openAnsiAsUTF8="no" />
<GUIConfig name="NewDocDefaultSettings" format="0" encoding="4" lang="0" openAnsiAsUTF8="no" />
0 | ANSI |
1 | UCS2 BIG |
2 | UCS2 SMALL |
3 | UTF 8 |
4 | UTF 8 without BOM |