I am on a special project that requires I do a deep dive into SharePoint and fast. I told my director that I would be blogging as I learn, if only to force me to repeat everything I learn so it all sticks!
I have been using SharePoint since its inception and have done a bit of development, primarily consuming SharePoint web services to integrate list data with other system. Aside from one experiment webpart, I haven’t done much else. I have a lot to learn.
So, I am starting this Learning SharePoint series today.
My first task, after reading over 100 articles last week and yesterday, is to build a web part. There are tools in Visual Studio and elsewhere that automate much of the construction and deployment, but using these tools in the beginning means I never really understand the internals. I am building a web part from scratch and deploying it manually.
My reading has taught me that the right way to deploy a web part is to deploy it to the Bin directory and setup CAS, but for getting started, I am using the “Ghetto Deploying” method, as Corey Roth calls it. A Ghetto Deploy is a GAC deployment. Later in the post, I will talk about doing deployment using a SharePoint solution.
I created my basic web part class library, created a .webpart file, and compiled the project. Great, no problems. I use a handy post-build event to register the build output in the GAC:
"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\gacutil.exe" /f /i $(TargetPath)
I could use IISRESET to purge the webpart, but that is a bit brutal. Instead, I use another handy utility called “iisap.vbs” to simply recycle the SharePoint app pool from the post-build event. That looks like this:
cscript.exe c:\windows\system32\iisapp.vbs /a "SharePoint - 80" /r
Next, I have to add the webpart assembly to the safe control list in web.config.
I got hung up here for about ten minutes.
I got that resolved by namespacing the webpart type correctly. Here is the final entry in web.config
2: Assembly="Mcs.Epm.Ipm.WebParts.IdeaBrowser, Version=22.214.171.124, Culture=neutral, PublicKeyToken=24e5f12c55dad2a2"
5: Safe="True" />
Remember, attribute names are CASE SENSITIVE.
I am able to preview the webpart in the gallery:
Debugging webparts is easy enough; just attach to the correct instance of w3wp.exe. I am going to write a better macro which attaches to the correct instance, but for now I am using Steve Connell’s macro to attach to all instances:
1: Sub AttachTo_ASPNETWP()
3: Dim attached As Boolean = False
4: Dim proc As EnvDTE.Process
5: Dim processToAttachTo As String
7: ' name of the process to attach to
8: processToAttachTo = "w3wp.exe"
10: ' iterate through all processes running on the local machine
11: For Each proc In DTE.Debugger.LocalProcesses
12: ' if the last [X] characters of the process name = name of the process...
14: If (Right(proc.Name, Len(processToAttachTo)) = processToAttachTo) Then
15: ' appach to the process
17: ' set a flag that we've attached to the process & exit the for loop
18: attached = True
19: End If
22: ' if macro didn't find process running, notify user
23: If attached = False Then
24: MsgBox(processToAttachTo & " is not running")
25: End If
26: End Sub
This has been written about a ton, so I am not going to repeat the instructions I found here.
After going through this manually a few times, I started to automate the process
I created four batch files, the first is build.bat:
1: call deletesolution.bat
2: call createsolution.bat
3: call deploysolution.bat
4: copy "C:\MCS EPM Global Practice\Projects\Internal\Innovation Process Management\Web Parts\Idea Browser\Idea Browser\bin\Debug\Mcs.Epm.Ipm.WebParts.IdeaBrowser.pdb" "C:\Inetpub\wwwroot\wss\VirtualDirectories\80\bin\Mcs.Epm.Ipm.WebParts.IdeaBrowser.pdb"
The deletesolution.bat file looks like this:
1: @SET STSADM="c:\program files\common files\microsoft shared\web server extensions\12\bin\stsadm.exe"
3: %STSADM% -o retractsolution -name Ipm.IdeaBrowser.wsp -immediate -allcontenturls
4: %STSADM% -o execadmsvcjobs
5: %STSADM% -o deletesolution -name Ipm.IdeaBrowser.wsp
And createsolution.bat file looks like this:
1: @echo off
2: if EXIST package\Ipm.IdeaBrowser.wsp del package\Ipm.IdeaBrowser.wsp
4: makecab /f cab.ddf
And finally, the deploysolution.bat file looks like this:
3: %STSADM% -o addsolution -filename package\Ipm.IdeaBrowser.wsp
4: %STSADM% -o deploysolution -name Ipm.IdeaBrowser.wsp -immediate -url "http://portal.fabrikam.com/" -allowCasPolicies
5: %STSADM% -o execadmsvcjobs
The output looks like this:
1: ------ Rebuild All started: Project: Idea Browser, Configuration: Debug Any CPU ------
2: C:\WINDOWS\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\Microsoft.SharePoint.dll" /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Web.dll /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /debug+ /debug:full /filealign:512 /keyfile:key.snk /optimize- /out:obj\Debug\Mcs.Epm.Ipm.WebParts.IdeaBrowser.dll /target:library IdeaBrowser.cs Properties\AssemblyInfo.cs
4: Compile complete -- 0 errors, 0 warnings
5: Idea Browser -> C:\MCS EPM Global Practice\Projects\Internal\Innovation Process Management\Web Parts\Idea Browser\Idea Browser\bin\Debug\Mcs.Epm.Ipm.WebParts.IdeaBrowser.dll
6: cd C:\MCS EPM Global Practice\Projects\Internal\Innovation Process Management\Web Parts\Idea Browser\
7: call build.bat
8: call cscript.exe c:\windows\system32\iisapp.vbs /a "SharePoint - 80" /r
11: Timer job successfully created.
14: Executing .
15: Executing solution-deployment-ipm.ideabrowser.wsp-0.
16: Operation completed successfully.
19: Operation completed successfully.
21: Microsoft (R) Cabinet Maker - Version 5.2.3790.0
22: Copyright (c) Microsoft Corporation. All rights reserved..
24: Parsing directives
25: Parsing directives (cab.ddf: 1 lines)
26: 20,103 bytes in 6 files
27: Executing directives
28: 0.00% - manifest.xml (1 of 6)
29: 0.00% - Mcs.Epm.Ipm.WebParts.IdeaBrowser.dll (2 of 6)
30: 0.00% - Mcs.Epm.Ipm.WebParts.IdeaBrowser.pdb (3 of 6)
31: 0.00% - Ipm.IdeaBrowser\Elements.xml (4 of 6)
32: 0.00% - Ipm.IdeaBrowser\Feature.xml (5 of 6)
33: 0.00% - IdeaBrowser.webpart (6 of 6)
34: 100.00% - IdeaBrowser.webpart (6 of 6)
35: 0.00% [flushing current folder]
36: 93.01% [flushing current folder]
37: 5.88% [flushing current folder]
38: 100.00% [flushing current folder]
39: Total files: 6
40: Bytes before: 20,103
41: Bytes after: 4,153
42: After/Before: 20.66% compression
43: Time: 0.04 seconds ( 0 hr 0 min 0.04 sec)
44: Throughput: 490.80 Kb/second
46: Operation completed successfully.
49: Timer job successfully created.
52: Executing .
53: Executing solution-deployment-ipm.ideabrowser.wsp-0.
54: Operation completed successfully.
56: Microsoft (R) Windows Script Host Version 5.6
57: Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
59: Connecting to server ...Done.
60: Application pool 'SharePoint - 80' recycled successfully.
61: ========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
So, at the end of build, I have my webpart deployed and read for debugging.