RSS

How do I - Fix SharePoint ULS Logs not being written?


From time to time, you will run into a situation where you're looking for ULS logs in their regular place i.e. %CommonProgramFiles%\Microsoft Shared\Web Server Extensions\15\LOGS\ but there aren't any log files being written.  Most of the time, the problem is simply that an admin might have changed the logging location.
  1. Ensure you're checking the correct logging location.
  2. Navigate to Central Admin >>> Monitoring >>> Configure Diagnostic Logging
  3. Check the Path value.  You can copy the value and paste it into your Windows Explorer address bar for quick access to the logging location.
If the logging location is correct, but you're still not getting logs on the server, check the Trace service.
  1. Open the Service console from the server where the logs aren't being written.
  2. Scroll down and check that the "SharePoint Tracing Service" is running.
  3. If the service is running, you may want to restart it for good measure.
  4. Most likely it's NOT running though.  If it's not, start the service.
  5. If the service does not use Local System for the account, but instead uses a domain account, it's likely that the password might have changed recently.  Obtain the new password and reset the credentials for the service and then restart the service.
If that isn't the issue, there's sometimes some access issue with the logging location at the time the service started up.  You could try toggling the logging location path value.
  1. Navigate to Central Admin >>> Monitoring >>> Configure Diagnostic Logging
  2. Check the Path value.  Change it to a folder that does exist.
  3. Click OK.
  4. Navigate back to the "Configure Diagnostic Logging" page.
  5. Change the Path value back to %CommonProgramFiles%\Microsoft Shared\Web Server Extensions\15\LOGS\ and click OK.
I'll continually add more steps as I uncover more reasons logging doesn't work in SharePoint. ;-)

Later
C

How do I - Manually force SharePoint patches or CU installations to complete using PSConfig.exe


SharePoint patching has always been a sore subject.  The installation of Cumulative Updates can leave your environment in a non functional state which is why Microsoft always recommend that you only install CUs if you are absolutely sure that the CU actually fixes something that is broken within your environment.  As with all other installation recommendations, it's always recommended that patches and CUs follow a proper change management path of DEV >>> QA >>> PROD in order to ensure minimal impact to production systems.

My standing recommendation to all my clients is as follows:


  1. Do NOT install any CU until it's been in the wild for at least a month.  There has been many retractions and re-publishings of CUs over the course of history and unfortunately, Microsoft's track records with CU regressions is not stellar.  The last thing you need to to install a CU that breaks your production environment.  By waiting a month, any obvious issues with the CU would become known before you apply it to your environment.
  2. Install the target patch or CU into DEV first.  Let it simmer in this environment for 2 weeks.  Ensure that you have the ability to roll back the CU through VM snapshots.  Since most DEV environments are virtual these days, this isn't really a problem.  If ANY issue is reported by developers in the DEV environment, investigate it and do NOT proceed to step 3 until you're sure the problem was not caused by the CU.  If the CU is the cause of the problem, simply roll back to your previous snapshot. Be sure this policy is well published and communicated, especially within your developer community as developers would lose any code that resided on the DEV farm without being checked into source control, when you conduct the rollback.  But that never happens, right?  Developers always check their code into source control, right? ;-)
  3. Once the CU passed the DEV test, it's time to move it to your QA environment for validation against what should be in PROD.  Again, the assumption here is that your QA environment is a true representation of the PROD environment.  If the CU breaks anything in QA, simply stop the process and do NOT proceed to step 4.  As with step 2 above, if your QA environment is also virtual (most are these days) then you can simply roll it back as well when problems are encountered.  Leave the CU in the QA environment for at least 2 weeks to simmer before advancing to step 4.
  4. Finally deploy the CU to your PROD environment.  Since there is no uninstall for CUs, and given that a lot of PROD SQL Servers are still physical, once you get to this point, there's no going back.  If some regression issues are discovered after you've installed to PROD, you're at the mercy of Microsoft releasing a patch to resolve the issue.  It is best to open a support ticket as soon as possible to help them determine how widespread and serious the regression is. 
Now in each of the install steps above, you'll sometimes find that running PSConfig.exe or the Configuration Wizard after completing the CU/Patch installation, would fail or get stuck.  This leaves you in no man's land and has to be resolved in order to complete the installation/upgrade.

NOTE:  A CU/PATCH INSTALLATION IS NOT COMPLETE UNLESS YOU HAVE A SUCCESSFUL RUN OF PSCONFIG ALL ALL YOUR SERVERS IN TURN!!!

When this happens, you can manually run PSConfig to force the completion as follows:

  1. Run the SharePoint Management Shell as admin.  (Right click icon, Run as Administrator)
  2. There should be a path to BIN already defined in the management shell, but if you get a command not found error when you enter PSConfig, you could manually change directory to C:\Program Files\Common Files\Microsoft Shared\web server extensions\14\BIN
  3. Execute psconfig.exe -cmd upgrade -inplace b2b -force -cmd applicationcontent -install -cmd installfeatures

If PSConfig fails on step 9 or 10, proceed as follows:

  1. Edit C:\ProgramData\Microsoft\SharePoint\Config\GUID\cache.ini
  2. Reset value to 1
  3. From the SharePoint Management Shell, execute stsadm -o execadmsvcjobs
  4. From the SharePoint Management Shell, execute psconfig.exe -cmd upgrade -inplace b2b -wait -force
This should complete your update successfully.

REMEMBER THAT YOU HAVE TO DO THE ABOVE PSCONFIG FOR EACH AND EVERY SERVER IN YOUR SHAREPOINT FARM.  START WITH THE CENTRAL ADMIN SERVER AND THEN PROCEED WITH EACH SERVER IN TURN ONCE THE PREVIOUS SERVER COMPLETED.

It is said that you don't HAVE to run PSConfig in a single threaded fashion as stated above, but from personal experience, whenever I've had issues with CU installations, it was because PSConfig was run concurrently on multiple servers in the farm, but I'd recommend you let your own personal experience be the judge.

Enjoy
C




How do I - Update the SharePoint Search Service Application Default Content Access account credentials using Powershell


When corporate security policy require that account passwords be updated, the Default Content Access Account used for the Search Service Application needs to be manually updated as well.  If your Search Service is in a funky state, this might not be possible using the browser UI.  When this happens, you'll need to resort to Powershell to save the day using the following script:

$userid = "domain\search_account";
$password = "account_password";
$ssa = Get-SPEnterpriseSearchServiceApplication "Search Service Application";
$sac = New-Object Microsoft.Office.Server.Search.Administration.Content($ssa);
$sac.SetDefaultGatheringAccount($userid, (ConvertTo-SecureString $password -AsPlainText -force));

Enjoy
C

SharePoint PowerShell error - The local farm is not accessible - Cmdlets with FeatureDependencyId are not registered


When you're new to a SharePoint farm, you may try to open the SharePoint Management Shell expecting to work in PowerShell.  Even though your account may be a local administrator on the server as well as a member of the SharePoint Farm Administrators group in Central Admin, you may still receive this error message:

The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered.




The issue is related to access to the configuration database for SharePoint.  What you need to do is grant access to the user in question, to the configuration database in SQL Server.  This can be done with the following two PowerShell commands:


$db = Get-SPDatabase | where {$_.Type -eq "Configuration Database"}
Add-SPShellAdmin "domain\username" -database $db

We begin by using the Get-SPDatabase cmdlet to get a reference to the SharePoint databases.  When you execute Get-SPDatabase by itself, it will provide you a listing of all SharePoint databases in the farm.  By filtering the type of database to only "Configuration Database" via the where clause, we are able to return on the configuration database in the farm.
Using the returned reference from this, we can use the Add-SPShellAdmin cmdlet to grant the user in question access to the configuration database.

Happy SharePointing!
C

image

How do I - Sort a list of custom class objects in descending order in C#?


Suppose we have a custom class defined thus:

    class CustomClass
{
public string String1 { get; set; }
public string String2 { get; set; }
public string String3 { get; set; }
public int Int1 { get; set; }
public int Int2 { get; set; }

public CustomClass()
{
String1 = "";
String2 = "";
String3 = "";
Int1 = 0;
Int2 = 0;
}

public int Calculate()
{
return Int1 + Int2;
}
}


As we can see, the class initializes it's variables and has a Calculate() method that simply returns the added value of the two int variables of the class.  Now suppose we have a list of these class objects in our app with varying values thus:



    CustomClass MyClass = new CustomClass();
MyClass.Int1 = 10;
MyClass.Int2 = 5;
CustomClass My2ndClass = new CustomClass();
My2ndClass.Int1 = 7;
CustomClass My3rdClass = new CustomClass();

List<CustomClass> lst = new List<CustomClass>();
lst.Add(My2ndClass);
lst.Add(MyClass);
lst.Add(My3rdClass);



We now have a list containing 3 of our custom class objects.  The first object in the list has an Int1 value of 10.  The second has an Int1 value of 5 and the third, given the class' initialization method, will have an Int1 value of 0.  Given the order that we added the class objects to our list, the list, when looking at the Int1 field would look thus:



7, 10, 0



How do we go about sorting this list by any one of the variable fields of the custom class, say Int1 in our case?



The built in support for Linq in Visual C# and the .NET Framework, actually makes this very easy.  Using a Lambda expression, the task becomes a one liner thus:



    lst = lst.OrderByDescending(x => x.Int1).ToList();



We start with the OrderByDescending() method and then pass the Lambda expression to reference back to the object itself.  The x => part of the expression tells C# to reference back to the calling object which in our case is lst.  C# will reference back to lst as x which is where the x.Int1 then instructs the OrderByDescending method to use the Int1 field as the value by which to sort, in descending order, the x object which translates to lst. 



By appending the ToList() method to the back of the statement, C# will take the sorted result and generate a new List<> object which we simply assign back to the original lst variable. If we needed to sort in ascending order we would use the OrderBy() method instead thus making the statement:



    lst = lst.OrderBy(x => x.Int1).ToList();




Enjoy

C



image

0 comments

Posted in

I am humbled to be honored again


I am humbled to be honored as a Microsoft MVP for SharePoint Server, for the 9th time.  The MVP community is a great group of people that I'm proud to be associated with.

How do I – Play the TNG Red Alert (or any audio file for that matter) in my WinForms C# app


Out of the box, C# and .NET supports the playing of any .WAV file.  The code is pretty straight forward.  We simply need to reference the system media class to create a SoundPlayer{} object thus:

System.Media.SoundPlayer p = new System.Media.SoundPlayer(@"C:\Media\MySoundEffect.wav");





Once we have the object, we simply invoke the Play() method thus:



p.Play();





So in two simple lines of code, we are able to play any .wav file from our application.  There are some more embedded problems that may not immediately be obvious.  Allow me to explain.



Suppose I'm trying to add the Star Trek TNG Red Alert sound to my app for an emergency notification.  I begin by locating the sound in question.  A quick web search takes me to the http://www.trekcore.com/audio/ site where the Red Alert section has several samples to choose from.  Once I locate the sound sample that I wish to use, I click the link and download the file.



image



PROBLEM #1:  The file is in the .mp3 audio format.  Attempting to use it in the instantiation of the SoundPlayer() method fails with the message that only .wav files are supported.



RESOLUTION

We could use a custom media player class, or we could just let the internet do some work for us.  A quick search pointed me to the http://media.io/ online audio conversion web site.  The simple interface couldn't be cleaner or more straight forward:



image



Simply take the .mp3 file we previously downloaded and upload and convert it on this site.  Now we finally have a .wav file that we can use in our project.  Now we would like the alert sound to be played 3 times and a popup window present the error notification.  That's easy, right?  We simply use a for() loop that looks like this:



for (int i = 0; i <= 2; i++)
{
System.Media.SoundPlayer p = new System.Media.SoundPlayer(@"TNG-Red-Alert.wav");
p.Play();


}


MessageBox.Show("There is an error!", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); 





We compile and run the app and expect the alert sound to play 3 times… only… it doesn't.  So why doesn't it play our audio?  It seems the problem is related to the fact that the asynchronous .Play() method, being spun from the current executing thread, does not have enough time to execute before the modal .Show() method is executed.  As you know, the MessageBox.Show() method will block the existing thread from executing any further until user action is taken on the window.  As such, the Play() method is queued really quickly given present computer CPU speeds, and once the.Show() method is invoked, it aborts the asynchronous threads to the .Play() method.  To solve the problem we have to allow the .Play() method some time to begin execution.  The easiest way to do that is to simply .Sleep() the current thread.  By injecting this line of code:



System.Threading.Thread.Sleep(1500);





right after the .Play() call, the currently executing thread will pause for 1.5 seconds.  Depending on what audio you're playing, you can tweak this value (in milliseconds) to match accordingly.



At this point, the alert message and audio work correctly… but the OCD in me still isn't happy with the effect we get.  When the error condition is generated, the audio alert is played three times, per our code, and then the error alert is popped up.  The problem I have with that is that the audio warning gets my attention, but then I have to wait for it to finish playing three times before the error message with useful information pops up.  That should be easy to fix, right?  Why not just simply move the .Show() method call to before the for() loop containing the .Play() call?



Unfortunately, this doesn't work as you'd expect.  Because of the fact that the .Show() call actually freezes the current thread, the message box is displayed and then awaits user interaction before it allows the audio code to execute.  What we need is for the .Show() code to be spun off in another thread so as to allow the audio alert to play while the message is displayed.  To do this, we create a new method thus:



public void ShowAlert()
{
System.Threading.Thread t = new System.Threading.Thread(() =>
{
MessageBox.Show("There is an error!", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
});
t.Start();
}





Once we have the message box contained in a separate thread, we simply make that call prior to playing our audio thus:



ShowAlert();
for (int i = 0; i <= 2; i++)
{
System.Media.SoundPlayer p = new System.Media.SoundPlayer(@"TNG-Red-Alert.wav");
p.Play();
System.Threading.Thread.Sleep(1500);
}





Once the user interacts with the message box, the thread (t) will terminate gracefully.  In the mean time our main app is free to continue execution of our loop to play the alert sound.





Enjoy


C



image

How do I – Play the TNG Red Alert (or any audio file for that matter) in my WinForms C# app


Out of the box, C# and .NET supports the playing of any .WAV file.  The code is pretty straight forward.  We simply need to reference the system media class to create a SoundPlayer{} object thus:

System.Media.SoundPlayer p = new System.Media.SoundPlayer(@"C:\Media\MySoundEffect.wav");





Once we have the object, we simply invoke the Play() method thus:



p.Play();





So in two simple lines of code, we are able to play any .wav file from our application.  There are some more embedded problems that may not immediately be obvious.  Allow me to explain.



Suppose I'm trying to add the Star Trek TNG Red Alert sound to my app for an emergency notification.  I begin by locating the sound in question.  A quick web search takes me to the http://www.trekcore.com/audio/ site where the Red Alert section has several samples to choose from.  Once I locate the sound sample that I wish to use, I click the link and download the file.



image



PROBLEM #1:  The file is in the .mp3 audio format.  Attempting to use it in the instantiation of the SoundPlayer() method fails with the message that only .wav files are supported.



RESOLUTION

We could use a custom media player class, or we could just let the internet do some work for us.  A quick search pointed me to the http://media.io/ online audio conversion web site.  The simple interface couldn't be cleaner or more straight forward:



image



Simply take the .mp3 file we previously downloaded and upload and convert it on this site.  Now we finally have a .wav file that we can use in our project.  Now we would like the alert sound to be played 3 times and a popup window present the error notification.  That's easy, right?  We simply use a for() loop that looks like this:



for (int i = 0; i <= 2; i++)
{
System.Media.SoundPlayer p = new System.Media.SoundPlayer(@"TNG-Red-Alert.wav");
p.Play();


}


MessageBox.Show("There is an error!", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); 





We compile and run the app and expect the alert sound to play 3 times… only… it doesn't.  So why doesn't it play our audio?  It seems the problem is related to the fact that the asynchronous .Play() method, being spun from the current executing thread, does not have enough time to execute before the modal .Show() method is executed.  As you know, the MessageBox.Show() method will block the existing thread from executing any further until user action is taken on the window.  As such, the Play() method is queued really quickly given present computer CPU speeds, and once the.Show() method is invoked, it aborts the asynchronous threads to the .Play() method.  To solve the problem we have to allow the .Play() method some time to begin execution.  The easiest way to do that is to simply .Sleep() the current thread.  By injecting this line of code:



System.Threading.Thread.Sleep(1500);





right after the .Play() call, the currently executing thread will pause for 1.5 seconds.  Depending on what audio you're playing, you can tweak this value (in milliseconds) to match accordingly.



At this point, the alert message and audio work correctly… but the OCD in me still isn't happy with the effect we get.  When the error condition is generated, the audio alert is played three times, per our code, and then the error alert is popped up.  The problem I have with that is that the audio warning gets my attention, but then I have to wait for it to finish playing three times before the error message with useful information pops up.  That should be easy to fix, right?  Why not just simply move the .Show() method call to before the for() loop containing the .Play() call?



Unfortunately, this doesn't work as you'd expect.  Because of the fact that the .Show() call actually freezes the current thread, the message box is displayed and then awaits user interaction before it allows the audio code to execute.  What we need is for the .Show() code to be spun off in another thread so as to allow the audio alert to play while the message is displayed.  To do this, we create a new method thus:



public void ShowAlert()
{
System.Threading.Thread t = new System.Threading.Thread(() =>
{
MessageBox.Show("There is an error!", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
});
t.Start();
}





Once we have the message box contained in a separate thread, we simply make that call prior to playing our audio thus:



ShowAlert();
for (int i = 0; i <= 2; i++)
{
System.Media.SoundPlayer p = new System.Media.SoundPlayer(@"TNG-Red-Alert.wav");
p.Play();
System.Threading.Thread.Sleep(1500);
}





Once the user interacts with the message box, the thread (t) will terminate gracefully.  In the mean time our main app is free to continue execution of our loop to play the alert sound.





Enjoy


C



image

0 comments

Posted in

For all the audio aficionados


A very interesting Kickstarter campaign for a portable DAC.

http://www.kickstarter.com/projects/gavn8r/geek-a-new-usb-awesomifier-for-headphones/description

0 comments

Posted in

Fixing Visual Studio 2012 defaults


One of the biggest pet peeves I experienced when switching to Visual Studio 2012 was the fact that the default command buttons were changed.  In going for a cleaner look, many of the main command buttons most developers use most frequently, was removed from the toolbar interface and buried in the menu structure instead.
Personally, the buttons I find myself using most frequently are the Navigate Backwards and Navigate Forwards (image ), Comment Selected Lines and Uncomment Selected Lines (image ) and lastly Increase Line Indent and Decrease Line Indent (image ).
The Navigate functions are still there, but the Comment and Indent functions are buried deep within the Edit/Advanced menu.  While it’s true that the Comment functions do have hot keys attached to them, I hardly consider Ctrl+K,Ctrl+C for a single click to be useful to most developers save the few that know the hotkeys by heart.
As for the Indent commands, they don’t have any hotkeys and you’d have to click through Edit/Advanced/Indent to get the action.  Though small annoyances, these can be addressed by simply adding the commands back to the command bar.  Here’s how to do just that:
  1. Click Tools on the menu bar.
  2. image
  3. On the popup menu, click "Customize".
  4. After the Customize dialog window opens, click over to the "Commands" tab.
  5. Select the "Toolbar" radio button.
  6. In the dropdown to the right of the Toolbar radio button, select the "Standard" toolbar to work with.
  7. The toolbar's controls will be previewed in the bottom left of the dialog window.
  8. To the right of the preview, click the "Add Command" button.
  9. image
  10. In the Add Command dialog window that opens up, select the "Edit" category to the left.
  11. On the right, scroll down through the commands and locate the "Line Indent" command.
  12. Select the command and click the "OK" button.
  13. image
  14. The command will be added to the top of the Controls preview.
  15. image
  16. Repeat steps 8 through 12 for the "Line Unindent", "Selection Comment" and "Selection Uncomment" commands as well.  The interface doesn't allow multi-select, though that would be nice touch in a future update.
  17. Once you have all the commands, use the "Move Up" and "Move Down" buttons to the right to arrange the commands in the order you wish them to appear on the toolbar.
  18. image
  19. When you're happy with the arrangement, click the "Close" button.  Your new toolbar should now reflect your favorite buttons again. :-)
  20. image

Happy coding!
C
image

How do I – Scroll the Telerik RadGridView to the top after a data refresh?


What seems like a very simple thing to do, and quite frankly it should be, turned out to be a little more tricky than I thought.

Setting the Scene
The app has a RadGridView control that displays information from a SQL database.  The data is presented to the control via a simple Linq2SQL DataSet.  Given that the RadGridView control has a .CurrentRow property which is updatable, logic dictates that a simple statement such as this:

   1:  grdContentSources.CurrentRow = grdContentSources.Rows[0];
 



would take care of moving the cursor to the top after the data refresh.  Alas, it doesn’t.  Next I experimented with disconnecting the data source, filling the table adapter and then reconnecting the data source to the grid, but that didn’t work either.  Internet searches, especially the very helpful Telerik support site, indicated that we should be using the .IsCurrent() method of the row instead.  So this should solve the problem, right?


   1:  grdContentSources.Rows[0].IsCurrent = true;




Unfortunately, that didn’t solve the problem either.  Then I found an obscure comment from “Jack”, and Admin on the Telerik team, that pointed me towards the .ChildRows collection for sorted data instead.  Since I did have some sorting on the grid, I tried it and it worked!  Here’s the complete code:


   1:  Cursor.Current = Cursors.WaitCursor;
   2:  this.crawlManDBDataSet.vwContentSourceCrawlHistory.Clear();
   3:  this.vwContentSourceCrawlHistoryTableAdapter.Fill(
   4:    this.crawlManDBDataSet.vwContentSourceCrawlHistory);
   5:  grdContentSources.ChildRows[0].IsCurrent = true;
   6:  Cursor.Current = Cursors.Default;


Since the operation takes some time, in line 1 we set the cursor to the hour glass.  In line 2 we clear the source table for the grid.  In line 3 we refill the table to get refreshed data.  This reflects back onto the grid as it triggers a .Changed() event to refresh the grid view.


Line 5 is where the magic happens as we simply set the .IsCurrent property of the .ChildRows[0] row to be true.  Using zero takes the grid back to the top.  We could set this to any value within the range of the grid e.g. we could have used:


   1:  grdContentSources.ChildRows[
   2:    grdContentSources.ChildRows.Count - 1].IsCurrent = true;




in order to scroll the grid to the bottom instead.


Enjoy
C


image