ตัดผมในเขตทหาร

มีโอกาสได้ลงไปทำงานในพื้นที่ของทหาร จริง ๆ ก็ทำมาเกือบปีแล้ว แต่วันนี้ด้วยความรำคาญผมบนหัวตัวเองประกอบกับอยากลองว่าจะเป็นอย่างไร จึงได้มีโอกาสใช้บริการร้านสวัสดิการของทหารในพื้นที่ที่ไปทำงาน

Blog Tags: 

การเรียกดูค่าจาก Site Column ที่เป็นของ Parent Content Type อาจจะไม่ได้ค่าที่คาดหวัง

ผมสร้าง Content Type ซึ่งเป็นลูก Event และได้เพิ่ม Content Type นี้เข้าไปใน Calendar หลังจากนั้นจึงเพิ่มข้อมูลที่เป็น Content Type ประเภทนี้เข้าไป ในการใช้งานทั่วไปทุกอย่างก็ดูปรกติดี ข้อมูลของ Content Type นี้ถูกแสดงใน Calendar View ได้โดยสมบูรณ์ แต่เมื่อผลผูก Workflow เข้ากับ Content Type นี้ ผมจึงเริ่มพบปัญหาไม่คาดคิดขึ้น

สิ่งที่ได้ทดลองทำคือ ใช้ Log to History แล้วทำการเรียกดูค่าของ Current Item:Start Time (ซึ่งเป็น Site Column ที่มากับ Event) แต่สิ่งที่เราได้คือ 0001-01-01T00:00:00Z (ค่าวันที่น้อยที่สุด)

Blog Tags: 

Upgrade to drupal 7

หลังจากใช้เวลาอยู่หลายชั่วโมง เจ๊งแล้วเจ๊งอีก สุดท้ายผมก็ Upgrade เว็บไซต์นี้จาก drupal 5 ขึ้นมา drupal 7 จนได้ โชคดีที่เว็บไซต์นี้ไม่ได้มีการใช้งาน Module พิสดารมากมาย หลัก ๆ ก็มีแค่ Markdown, reCaptcha การย้ายจึงไม่โหดมากเท่าใดนัก

ถ้าว่าตามวิธีที่มีการแนะนำใน UPGRADE.TXT เขาจะบอกให้

  1. ทำการ Backup ทุกอย่าง (Database, File System) เพื่อที่จะให้สามารถกู้ย้อนกลับมาได้ (ซึ่งก็ได้กู้ย้อนกลับมาจริง ๆ แหละ)
  2. หลังจากนั้นก็สั่งให้ไซต์เป็น Offline
  3. แล้วจึงไล่ปิด Module ทุกตัวที่ไม่ใช่ของ drupal รวมถึงสลับธีมกลับเป็นธีมดั้งเดิมที่ drupal ให้มา
  4. จากนั้นก็ลบ drupal ตัวเก่าออกแล้ว แล้วค่อย ๆ ไล่ Upgrade โดยเอาไฟล์ของ drupal 6 ลงไปก่อน
  5. กู้คืน /files และ /sites/default ให้เรียบร้อย รวมถึงตั้งสิทธิ์ให้ other สามารถเขียนลง directory ดังกล่าว และไฟล์ settings.php ที่กู้กลับมาด้วย
  6. เรียก update.php ถ้าไม่มีอะไรผิดพลาด จาก drupal 5 ก็จะกลายเป็น drupal 6 โดยอาจจะมี warning ขึ้นนิดหน่อย ซึ่งก็ภาวนาว่าอย่าเป็นอะไรกับ Database เลย :)
  7. ตรวจสอบว่าเว็บ drupal 6 นั้นเปิดดูได้ (แน่นอนว่ามันไม่เหมือนเดิมเพราะยังไม่ได้เรียก Markdown กลับมา) ถ้าดูแล้วยังไม่มีปัญหาก็เตรียมตัวไปรุ่น 7 ได้เลยโดยย้อนกลับไปทำขั้นตอนตั้งแต่ข้อ 1 ใหม่อีกครั้ง
  8. ติดตั้ง Module และ Theme

ที่เป็นประเด็นจริง ๆ ก็คือ reCaptcha เนื่องจากต้องติดตั้ง Captcha เข้าไปก่อน แล้วตัว Captcha เองนั้นไม่สนับสนุนการ Upgrade ข้ามรุ่น จาก 5 ไป 7 โดยไม่ผ่าน 6 ก่อน (ซึ่งผมข้ามมา) ทางแก้คือ ไล่ลบ table ของ Captcha ในฐานข้อมูล (มี 2 ตาราง) แล้วไปลบแถวในตาราง system ที่อ้างถึง Captcha เพื่อให้สามารถติดตั้งได้

หลังจากนั้นก็ไปหาธีม Zen มาติดตั้ง แล้วก็ทำธีมย่อยออกมาเป็นดังที่เห็นนี่แหละ

Blog Tags: 

Secure Store Service isn't available in SharePoint Foundation 2013

UPDATE: Microsoft confirms that they will remove this feature from SharePoint Foundation. It is an expected behavior.

After a lot of searching, I figure out its root clause.

Using ILSpy to see inside method Microsoft.Office.SecureStoreService.Server.SecureStoreServiceApplicationProxy.Execute(), the first condition check is as follows:

if (Licensing.HasExpired)
{
    ULS.SendTraceTag(1731227190u, ULSCat.msoulscat_SPS_SecureStoreService, ULSTraceLevel.High, "The trial period for this product has expired or this feature is not supported in this SKU.");
    throw new ProductExpiredException(Resources.ResourceManager.GetString("Sss_InvalidSku"));
}

Digging deeper inside Microsoft.Office.Server.Administration.Licensing class, there is a boolean property HasExpired which returns result depending on following conditions:

get
{
    return Licensing.m_ExpirationFileTime != 9223372036854775807L && DateTime.UtcNow.ToFileTime() > Licensing.m_ExpirationFileTime;
}

Note: the number shown above is the constant long variable named LicensedExpirationFileTime.

The static field m_ExpirationFileTime is set by the static constructor of this class.

Licensing.m_ExpirationFileTime = -9223372036854775808L;
try
{
    ULS.SendTraceTag(1634366517u, ULSCat.msoulscat_OSRV_SetupUpgrade, ULSTraceLevel.High, "Initializing Licensing API. This trace forces the initialization of ULS");
    Licensing.m_ExpirationFileTime = Licensing.GetExpirationFileTimeFromRegistry();
}
catch (LicensingException ex)
{
    ULS.SendTraceTag(926447969u, ULSCat.msoulscat_OSRV_SetupUpgrade, ULSTraceLevel.High, "{0}", new object[]
    {
        ex.ToString()
    });
}

The GetExpirationFileTimeFromRegistry() method calls native method named GetExpirationTime() from OfficeServerSettings.dll which isn't bundled with SharePoint Foundation! (There is no %PROGRAMFILES%\Microsoft Office Server\15.0\Bin directory.) The following errors are shown in ULS.

[DATETIME]  psconfigui.exe (0x0764)                     0x0BF4  SharePoint Server               Setup and Upgrade               ajt5    High        Initializing Licensing API. This trace forces the initialization of ULS  
[DATETIME]  psconfigui.exe (0x0764)                     0x0BF4  SharePoint Server               Setup and Upgrade               78ya    High        Microsoft.Office.Server.Administration.LicensingException: An error was encountered getting expiration info. ---> System.DllNotFoundException: Unable to load DLL 'OfficeServerSettings.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)     at Microsoft.Office.Server.Administration.Licensing.NativeMethods.GetExpirationTime(Int64& expirationTime)     at Microsoft.Office.Server.Administration.Licensing.GetExpirationFileTimeFromRegistry()     --- End of inner exception stack trace ---     at Microsoft.Office.Server.Administration.Licensing.GetExpirationFileTimeFromRegistry()     at Microsoft.Office.Server.Administration.Licensing..cctor()   

If the library is supplied, we will need to see which registry key is checked which I won't do for sure. The easiest way to solve this problem is letting Microsoft remove the checking (the first code snippet) from method Microsoft.Office.SecureStoreService.Server.SecureStoreServiceApplicationProxy.Execute().

Finally, we should get SSS administration page on SharePoint Foundation!

Blog Tags: