Balkongriller

SharePoint und Office 365 Blog

PDF Check Out funktioniert nicht

Hinterlasse einen Kommentar

Seit dem March 2013 Public Update für SharePoint wird beim Öffnen von Adobe Acrobat PDF Dateien kein Check-Out Dialog mehr angezeigt. Wenn man die PDF nur lesen will, ist das nicht schlimm. Wenn es aber darum geht, die PDF Dateien zu bearbeiten oder Annotationen zu machen, fehlt eine wichtige Funktion. Microsoft hat den Bug bestätigt – wann wir mit einer Lösung rechnen können, steht aber in den Sternen.

In einem Adobe Forum findet man einen Workaround um das Problem zu umgehen. Dabei wir der JSLink auf dem SharePoint Field gesetzt. (Hey Developers, eine gute Gelegenheit, diese tolle, aber ziemlich unbekannte Funktion von SharePoint näher kennen zu lernen).

Zuerst geht es darum, eine JS Datei (wir nennen sie PDFFIX.JS) auf SharePoint zu hinterlegen. Das kann entweder via Module einer SharePoint Farm Solution geschehen. Man kann die Datei aber auch einfach in die Style Library hochladen. Anbei der Code von PDFFIX.JS

(function () {
 if (typeof SPClientTemplates === 'undefined')
 return;

 var PdfCtx = {};
 PdfCtx.Templates = {};
 PdfCtx.Templates.Fields = { 'LinkFilename': { 'View': PdfClientLinkFilenameNoMenu } };
 SPClientTemplates.TemplateManager.RegisterTemplateOverrides(PdfCtx);
})();

function GetExtension(szHref) {
 var sz = new String(szHref);
 var re = /^.*\.([^\.]*)$/;
 return (sz.replace(re, "$1")).toLowerCase();
}

var stsOpen = null;

function IsPdfClientInstalled() {
 if (stsOpen == null) {
 if (Boolean(window.ActiveXObject)) {
 try {
 stsOpen = new ActiveXObject("PdfFile.OpenDocuments");
 }
 catch (e) {
 stsOpen = null;
 }
 }
 }
 return (stsOpen != null);
}

function OpenPdfInClient(pdfFileUrl) {
 var fRet = true;
 try {
 fRet = typeof stsOpen.ViewDocument2 != "undefined" && stsOpen.ViewDocument2(window, pdfFileUrl, '');
 }
 catch (e) {
 fRet = false;
 };

 if (event != null) {
 event.cancelBubble = true;
 event.returnValue = false;
 }
 return fRet;
}

function PdfNewGif(listItem, listSchema, ret) {
 if (listItem["Created_x0020_Date.ifnew"] == "1") {
 var spCommonSrc = GetThemedImageUrl("spcommon.png");
 ret.push("<span class=\"ms-newdocument-iconouter\"><img class=\"ms-newdocument-icon\" src=\"");
 ret.push(spCommonSrc);
 ret.push("\" alt=\"");
 ret.push(Strings.STS.L_SPClientNew);
 ret.push("\" title=\"");
 ret.push(Strings.STS.L_SPClientNew);
 ret.push("\" /></span>");
 }
}

function PdfClientLinkFilenameNoMenu(param1, param2, listItem, listSchema) {
 var ret = [];
 var fileUrl = listItem.FileRef;

 if (fileUrl != null && typeof fileUrl != 'undefined' && TrimSpaces(fileUrl) != "") {
 if (listItem.FSObjType == '1') {
 if (listSchema.IsDocLib == '1') {
 RenderDocFolderLink(ret, listItem.FileLeafRef, listItem, listSchema);
 }
 else {
 RenderListFolderLink(ret, listItem.FileLeafRef, listItem, listSchema);
 }
 }
 else {
 ret.push("<a class='ms-listlink' href=\"");
 ret.push(listItem.FileRef);
 ret.push("\" onmousedown=\"return VerifyHref(this,event,'");
 ret.push(listSchema.DefaultItemOpen);
 ret.push("','");
 ret.push(listItem["HTML_x0020_File_x0020_Type.File_x0020_Type.mapcon"]);
 ret.push("','");
 ret.push(listItem["serverurl.progid"]);
 ret.push("')\" onclick=\"");

 var appInstalled = IsPdfClientInstalled();
 var szExt = GetExtension(listItem.FileRef);
 if (appInstalled && szExt == 'pdf' && browseris.ie) {
 ret.push("return OpenPdfInClient('");
 ret.push(window.location.protocol + "//");
 ret.push(window.location.hostname);
 ret.push(listItem.FileRef);
 }
 else {
 ret.push("return DispEx(this,event,'TRUE','FALSE','");
 ret.push(listItem["File_x0020_Type.url"]);
 ret.push("','");
 ret.push(listItem["File_x0020_Type.progid"]);
 ret.push("','");
 ret.push(listSchema.DefaultItemOpen);
 ret.push("','");
 ret.push(listItem["HTML_x0020_File_x0020_Type.File_x0020_Type.mapcon"]);
 ret.push("','");
 ret.push(listItem["HTML_x0020_File_x0020_Type"]);
 ret.push("','");
 ret.push(listItem["serverurl.progid"]);
 ret.push("','");
 ret.push(Boolean(listItem["CheckoutUser"]) ? listItem["CheckoutUser"][0].id : '');
 ret.push("','");
 ret.push(listSchema.Userid);
 ret.push("','");
 ret.push(listSchema.ForceCheckout);
 ret.push("','");
 ret.push(listItem.IsCheckedoutToLocal);
 ret.push("','");
 ret.push(listItem.PermMask);
 }

 ret.push("')\">");

 var fileRef = listItem["FileLeafRef"];

 if (fileRef != null) {
 var index = fileRef.lastIndexOf('.');
 fileRef = index >= 0 ? fileRef.substring(0, index) : fileRef;
 }

 ret.push(fileRef);
 ret.push("</a>");

 PdfNewGif(listItem, listSchema, ret);
 }
 }
 else {
 ret.push("<nobr>");
 ret.push(listItem["FileLeafRef"]);
 ret.push("</nobr>");
 }

 return ret.join('');
}

Jetzt muss man die Eigenschaft JSLink auf dem SPField LinkName setzen. Am besten geht dies mit PowerShell. Man kann z.B. das Field im Rootweb verändern und setzt damit die Eigenschaft innerhalb der gesamten Site Collection. Nachdem man die Datei z.B. nach „/Style Library/scripts/pdffix.js“ kopiert hat, würde das PowerShell wie folgt lauten.

Add-PSSnapin "Microsoft.SharePoint.PowerShell"

$SPWebApp = Get-SPWebApplication "https://intranet"

foreach($SPSite in $SPWebApp.Sites)
{
 $web = $SPSite.RootWeb
 Write-Host $SPSite.RootWeb
 $field = $web.Fields.GetFieldByInternalName("LinkFilename")
 Write-Host $field.JSLink
 if ($field.JSLink -ne "/Style%20Library/scripts/PdfFix.js")
 {
 $field.JSLink = "/Style%20Library/scripts/PdfFix.js"
 $field.Update($true) #push change down to all lists
 }
}

Aber Achtung. Folgende Einschränkungen:

  • Wenn Microsoft den Bug gefixt hat, muss der Workaround wieder rückgängig gemacht werden. D.h. dokumentieren und die Beschreibung der Public und Cumulative Updates genau durchlesen.
  • Jedesmal wenn eine neue Site Collection erstellt wird, muss auf der neu erstellten Site Collection das PowerShell wieder ausgeführt werden.
  • Workaround ist immer ein anderer Name für Hack.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s