Just a short, simple blog for Bob to share his thoughts.
31 May 2011 • by Bob • SharePoint
Sometime last year I wanted to set up a SharePoint 2007 website for my family members to exchange information. That being said, I was using a custom membership provider, and I ran into a few issues while I was setting things up. I had kept detailed notes while I was configuring my server and troubleshooting the problems that I encountered, and with that in mind, I thought that I would share my experiences. ;-]
My web server is only an older 32-bit Windows Server 2008 computer, so I couldn't install SharePoint 2010 (which is 64-bit only) and I had to install SharePoint 2007. Taking that into account, there were a few additional considerations that I had for my environment:
With my specific considerations in mind, I took a look at the following article to get started:
That being said, I did not use the following articles, even though they are related to my scenario and they looked interesting:
Here are the brief details on how I created my SharePoint website:
<Users> <User> <UserName>Alice</UserName> <Password>P@ssw0rd</Password> <EMail>alice@contoso.com</EMail> <Roles>Admins</Roles> </User> <User> <UserName>Bob</UserName> <Password>P@ssw0rd</Password> <EMail>bob@contoso.com</EMail> <Roles>Authors</Roles> </User> </Users>
There are a few additions that you have to make to your website's web.config file, as well as the SharePoint Central Administration web.config file for SharePoint 2007:
<system.web>
section of your website's web.config; in my example that file would be located at "C:\Inetpub\SharePointSite\wwwroot\web.config":
<!-- added on 05/31/2011 --> <membership defaultProvider="ReadOnlyXmlMembershipProvider"> <providers> <add name="ReadOnlyXmlMembershipProvider" type="ReadOnlyXmlMembershipProvider, ReadOnlyXmlMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=426f62526f636b73" description="Read-only XML membership provider" xmlFileName="~/App_Data/MyUsers.xml" /> </providers> </membership> <roleManager enabled="true" defaultProvider="ReadOnlyXmlRoleProvider"> <providers> <add name="ReadOnlyXmlRoleProvider" type="ReadOnlyXmlRoleProvider, ReadOnlyXmlRoleProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=426f62526f636b73" description="Read-only XML role provider" xmlFileName="~/App_Data/MyUsers.xml" /> </providers> </roleManager> <!--/added on 05/31/2011 -->
<system.web>
section of your SharePoint Central Administration web.config file; on my server that file is located at "C:\inetpub\wwwroot\wss\VirtualDirectories\6087\web.config":
<!-- added on 05/31/2011 --> <membership defaultProvider="ReadOnlyXmlMembershipProvider"> <providers> <add name="ReadOnlyXmlMembershipProvider" type="ReadOnlyXmlMembershipProvider, ReadOnlyXmlMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=426f62526f636b73" description="Read-only XML membership provider" xmlFileName="~/App_Data/MyUsers.xml" /> </providers> </membership> <!--/added on 05/31/2011 -->
SharePoint Central Administration needs to be able to find the MyUsers.xml file, so I created an App_Data folder under physical path of the SharePoint Central Administration website, and I added a symbolic link in that folder that pointed to the physical MyUsers.xml file. Here's how I did that:
cd C:\inetpub\wwwroot\wss\VirtualDirectories\6087
mklink MyUsers.xml C:\Inetpub\SharePointSite\wwwroot\App_Data\MyUsers.xml
Note: I could have copied the XML file, but I preferred to use the symbolic link instead of having to manage two copies of the file.
If you were installing a membership provider that can perform lookups, you could add an additional entry to your SharePoint Central Administration web.config file:
<PeoplePickerWildcards> <clear /> <add key="AspNetSqlMembershipProvider" value="%" /> <!-- added on 05/31/2011 --> <add key="ReadOnlyXmlMembershipProvider" value="%" /> <!--/added on 05/31/2011 --> </PeoplePickerWildcards>
Okay - I admit that I everything that I did so far was probably making things harder that they needed to be, but I love a good challenge. ;-]
That being said, I ran into some problems that I thought would be worth mentioning, just in case someone else ran into them.
When browsing to my SharePoint website, I received several HTTP 403 errors. I used Process Monitor to troubleshoot the problem, and I discovered that IUSR could not access the "bin" folder in my website. (I'm still not quite sure why it was trying.) To resolve these errors, I used the following steps:
cd C:\Inetpub\SharePointSite\wwwroot
icacls bin /grant IIS_IUSRS:r
In my situation the problem was for IUSR, but if you are using a different anonymous identity or your application pool is running as a unique identity then it might be a different user. In any case, Process Monitor will let you know who needs permissions.
Later I discovered the following blog post by John Powell:
In that blog, John suggests adding the following permissions for the "bin" folder:
icacls bin /grant users:r
I'm not sure if that's necessary, but it's worth pointing out.
When browsing to my SharePoint website, I received several HTTP 404.8 errors. Those errors mean that the built-in IIS 7 Request Filtering feature was blocking something, so I did the following:
</configuration>
tag:
<system.webServer> <!-- added on 05/31/2011 --> <security> <requestFiltering> <hiddenSegments> <clear /> <add segment="web.config" /> <add segment="bin" /> <add segment="App_code" /> <add segment="App_GlobalResources" /> <add segment="App_LocalResources" /> <add segment="App_WebReferences" /> <add segment="App_Data" /> <add segment="App_Browsers" /> </hiddenSegments> </requestFiltering> </security> <!--/added on 05/31/2011 --> </system.webServer>
Note: This removes all of the hidden segments from the global IIS 7 Request Filtering settings, which may be overkill. I have a lot of custom global request filtering settings, and I didn't want to go through each individual setting to see which setting was blocking files that I needed, so I used settings for my website that cleared the inherited request filtering settings and added the default settings.
When browsing to my SharePoint website, the information bar in Internet Explorer kept prompting me with the following message:
The Web site wants to run the following add-on: 'Name ActiveX Control' from 'Microsoft Corporation'. If you trust the Web site and the add-on and want to allow it to run, click here...
This message was highly frustrating, so I did some digging around the Internet and discovered that I could hack the INIT.JS file for SharePoint to suppress this message. Here's how I did that:
ProcessImn()
and ProcessImnMarkers()
functions, and I remarked out the contents. Here's what this looked like when I was done:
function ProcessImn() { // if (EnsureIMNControl() && IMNControlObj.PresenceEnabled) // { // imnElems=document.getElementsByName("imnmark"); // imnElemsCount=imnElems.length; // ProcessImnMarkers(); // } } function ProcessImnMarkers() { // for (i=0;i<imnMarkerBatchSize;++i) // { // if (imnCount==imnElemsCount) // return; // IMNRC(imnElems[imnCount].sip,imnElems[imnCount]); // imnCount++; // } // setTimeout("ProcessImnMarkers()",imnMarkerBatchDelay); }
I should note that this solution is unsupported; and a few months I hacked my INIT.JS file, Microsoft published the following Knowledge Base article with a couple of different methods:
That being said, I like my solution better. ;-]
Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/
31 May 2011 • by Bob • IIS, Scripting, SharePoint
I ran into an interesting situation recently - I host a website for a friend of mine, and he was shopping around for a new website template. He found one that he liked, but he didn't like the colors. In fact, he wanted the exact opposite of the colors in the website template, so he asked what I could do about it.
I looked at the website template, and thankfully it was using linked Cascading Style Sheets (CSS) files for all of the color definitions, so I told him that changing the colors would probably be a pretty easy thing to do. However, once I cracked open the CSS files from the website template, I found that they had hundreds of color definitions. Changing every color definition by hand would have taken hours, so I decided to write some Windows Script Host (WSH) code to do the work for me.
With the above scenario in mind, here's the script that I wrote to negatize every color in a CSS file - all that you need to do is replace the paths to the input and output files and run the script to create the negatized version of the input CSS file.
Option Explicit Const strInputFile = "c:\inetpub\wwwroot\style-dark.css" Const strOutputFile = "c:\inetpub\wwwroot\style-light.css" ' ------------------------------------------------------------ Dim objFSO Dim objInputFile Dim objOutputFile Dim strInputLine Dim strLeft, strMid, strRight, strArray Dim blnFound ' ------------------------------------------------------------ Const strTempRGB = "[|[TMPRGBSTR1NG]|]" Const strTempHEX = "[|[TMPHEXSTR1NG]|]" ' ------------------------------------------------------------ Set objFSO = CreateObject("scripting.filesystemobject") Set objInputFile = objFSO.OpenTextFile(strInputFile) Set objOutputFile = objFSO.CreateTextFile(strOutputFile) Do While Not objInputFile.AtEndOfStream strInputLine = objInputFile.ReadLine blnFound = True Do While blnFound If InStr(1,strInputLine,"rgb(",vbTextCompare) Then strLeft = Left(strInputLine,InStr(1,strInputLine,"rgb(",vbTextCompare)-1) strMid = Mid(strInputLine,InStr(1,strInputLine,"rgb(",vbTextCompare)+4) strRight = Mid(strMid,InStr(strMid,")")+1) strMid = Left(strMid,InStr(strMid,")")-1) strArray = Split(strMid,",") strMid = InvertOctet(CInt(strArray(0))) & _ "," & InvertOctet(CInt(strArray(1))) & _ "," & InvertOctet(CInt(strArray(2))) strInputLine = strLeft & strTempRGB & "(" & strMid & ")" & strRight Else blnFound = False End If Loop strInputLine = Replace(strInputLine,strTempRGB,"rgb") blnFound = True Do While blnFound If InStr(strInputLine,"#") Then strLeft = Left(strInputLine,InStr(strInputLine,"#")-1) strMid = Mid(strInputLine,InStr(strInputLine,"#")+1) If Len(strMid)>6 Then strRight = Mid(strMid,7) strMid = Left(strMid,6) ElseIf Len(strMid)>3 Then strRight = Mid(strMid,4) strMid = Left(strMid,3) Else strRight = "" End If If IsHexString(strMid) Then If Len(strMid) = 6 Then strMid = Right("0" & Hex(InvertOctet(CInt("&h" & Left(strMid,2)))),2) & _ Right("0" & Hex(InvertOctet(CInt("&h" & Mid(strMid,3,2)))),2) & _ Right("0" & Hex(InvertOctet(CInt("&h" & Right(strMid,2)))),2) Else strMid = Hex(InvertByte(CInt("&h" & Left(strMid,2)))) & _ Hex(InvertByte(CInt("&h" & Mid(strMid,3,2)))) & _ Hex(InvertByte(CInt("&h" & Right(strMid,2)))) End If End If strInputLine = strLeft & strTempHEX & strMid & strRight Else blnFound = False End If Loop strInputLine = Replace(strInputLine,strTempHEX,"#") objOutputFile.WriteLine strInputLine Loop ' ------------------------------------------------------------ Function IsHexString(ByVal tmpString) Dim blnHexString, intHexCount, intHexByte blnHexString = True If Len(tmpString)<>3 and Len(tmpString)<>6 Then blnHexString = False Else tmpString = UCase(tmpString) For intHexCount = 1 To Len(tmpString) intHexByte = Asc(Mid(tmpString,intHexCount,1)) If (intHexByte < 48 Or intHexByte > 57) And (intHexByte < 65 Or intHexByte > 70) Then blnHexString = False End If Next End If IsHexString = blnHexString End Function ' ------------------------------------------------------------ Function InvertByte(ByVal tmpByte) tmpByte = tmpByte And 15 tmpByte = 15 - tmpByte InvertByte = tmpByte End Function ' ------------------------------------------------------------ Function InvertOctet(ByVal tmpOctet) tmpOctet = tmpOctet And 255 tmpOctet = 255 - tmpOctet InvertOctet = tmpOctet End Function ' ------------------------------------------------------------
After I wrote the above script, I found myself using it for a bunch of different websites that I manage for other people. One of the websites that I host is based on SharePoint 2007, so I wondered how difficult it would be negatize a SharePoint 2007 theme. As it turns out, it's pretty easy. The following steps will walk you through the steps that are required to create a negatized version of the built-in "Classic" SharePoint 2007 theme.
(NOTE: The steps in this section do not work with SharePoint 2010 or office 14; SharePoint 2010 and Office 14 store their themes in a different format, so these steps will not work.)
<
SPThemes
>
collection:
<Templates> <TemplateID>classicnegative</TemplateID> <DisplayName>Classic Negative</DisplayName> <Description>Classic Negative</Description> <Thumbnail>images/thclassic.gif</Thumbnail> <Preview>images/thclassic.gif</Preview> </Templates>
That's all it takes to negate the colors that are defined in the CSS files for a SharePoint 2007 theme. (NOTE: This does not modify the colors of the images in the SharePoint theme; you will need a graphics program to update the colors in the images.)
Before I receive any comments, I am perfectly aware that "negatize" is not an actual word in the English language, but it seemed appropriate, and new words have to start somewhere.
Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/