I have been dealing a lot with documents. I have a fun project dealing with WPF documents that I hope to blog more on soon. Anyway, the last few days I have noticed that every document I open is locked. In order to do anything, even cut-and-paste, I need to go to Tools –> Unprotect Document. Then I am good to go.
After about 4 days of just ignoring it I decided I needed to figure out what was wrong. None of the documents were intended to be protected, I could even create a new sample document, save it, then re-open it and find it now locked. That last test is what brought me to the realization: normal.dot was not so normal anymore.
normal.dot is the base template file that Word uses for all of its documents. If it gets corrupted or otherwise gets something stuck in it’s teensy little binary brain, it will affect every document you create or even just open to read. So, if you have this issue, or something else weird that is happening to all of your Word documents, try this:
Find the normal.dot template file location
Thankfully Word helps with this: go to the Tools –> Options. Select the File Locations tab. Select the User Templates item in the list. Click Modify and a file browser will open to your templates directory.
Rename the file
You can, I am sure, just delete the old normal.dot file, but I always feel safer renaming it something like this:
Open Word
This prompts Word to create a new normal.dot with all the default settings since it can’t find the old one.
Hope your problem went away.
If your particular flavor of weirdness goes away at this point then the template was your problem. If not … well not so much. Keep looking.
Hope this helps
Found this a while back and to search for it all over again to set up a new IDE. That’s one time too many.
How to change your default xaml file editor in Visual Studio and save yourself lots o’ pain.
http://weblogs.asp.net/fmarguerie/archive/2009/01/29/life-changer-xaml-tip-for-visual-studio.aspx
Fowler’s first law of distributed object design: “Don’t distribute your objects”
Just because we have created better, more efficient, more secure, or even “sexy” ways of distributing our applications that doesn’t make it right in and of itself. WCF, a formidable follow up to Web Services, has given us the tools we need to enable cross machine, cross application, inter-enterprise communication when we need to do it. The fact of the matter is that we don’t need to do it as often as we think we do.
It is amazing how many application design efforts just assume a WCF service layer out of the box for no other reason than a desire to be "Service Oriented". Admittedly, there are viable reasons to have a multi-tier application. One common situation is a web application that needs to talk to a database that it cannot see directly, it needs to go thru an application server to get there. Once we proven to ourselves that we have to have a distributed architecture and we have no way to avoid it, then solving the problem that, to many, seems like a no-brainer, can get our code in the weeds in hurry if we don't understand the price that must be paid to have a true service layer. In Fowler's Errant Objects Article for Dr Dobbs he states what our willingness to distribute our application should be: "If you’re sensible, you’ll fight like a cornered rat'. I think that pretty much sums it up.
Well, like it or not, we will need to solve this problem more often than not, so how do we go about doing it well? A new book by Dino Esposito digs into just this question in great detail and I think it is one of the better attempts to clarify a subject that is misunderstood more often than not. I really like how he takes a Fowler's Enterprise Application Architectures and applies them to design decisions in a pragmatic, non-religious way.
I am still not sold on how best to solve the service layer problem in an application that doesn't need to be service oriented but needs to be distributed. Any suggestions?
Once again I need to call out to an external web service from behind a proxy. Last time it was installing WATIR. This time it is just straight up .NET code, but somehow this configuration feels like something I have to learn over each time I see it, so I am going to burn it into my blog.
I am working through some hands on labs configuring the Unity Inversion Of Control Container. The labs come with a sample Stocks Ticker application which calls out to an external web service to get its updates. So when running behind a proxy that requires authentication, by default, what you will see when running this application is:
So I open up the MoneyCentralStockQuoteService.vb file, which defines the class that is calling the service, and find this constructor:
Public Sub New(ByVal implementation As MoneyCentralRemote)
Me.implementation = implementation
Me.Logger = New NullLogger
End Sub
My first attempt to resolve the issue is this, setting up a manual proxy reference (an instance of WebProxy), which requires that I not only tell the proxy to use the default credentials but also provide the ISA server’s address.
Public Sub New(ByVal implementation As MoneyCentralRemote)
Me.implementation = implementation
'wire up proxy information here
Dim proxy As New Net.WebProxy("http://servername:8080")
proxy.UseDefaultCredentials = True
Me.implementation.Proxy = proxy
Me.Logger = New NullLogger
End Sub
This works and I can start working with the sample application:
However, hard-coding the server name seems less than terrific. I then remember that I can also configure the proxy settings in the app.config file like below, which also works.
<system.net>
<defaultProxy useDefaultCredentials="true" />
</system.net>
What this approach reminds me of is that I shouldn’t have to hard-code my proxy server address. If the application can load up the correct default proxy information based on a config file setting it should be able to do so in code as well. There must be a way to wire into this default functionality in code. So, back to the syntax drawing board ... and I end up with this, somewhat cleaner option, that gets a reference to the default WebProxy by way of the WebRequest class:
Public Sub New(ByVal implementation As MoneyCentralRemote)
Me.implementation = implementation
'set up proxy information here
implementation.Proxy = System.Net.WebRequest.DefaultWebProxy
implementation.Proxy.Credentials = Net.CredentialCache.DefaultCredentials
Me.Logger = New NullLogger
End Sub
Of the three approaches, I strongly favor setting up the proxy settings in the configuration file, as it is specific to the environment. Are there any options that I missed?
I really like being familiar with command line tools, however, in reality I often find myself searching on line for some command I know I used before but just can't seem to remember. In a past life (read "job") I was able to turn around and ask a fellow lead dev who seemed to have The Hitchhiker's Guide to the Galaxy and Window's command line syntax burned into his psyche in no particular order of precedence. We called him "Inspector Gadget" because, when you were looking for the odd utility, tool or command, he was your man. Alas, today I had to resort to Google (MS employees here read "Live Search") Here are a few reminders I needed today and some new stuff I learned. Hopefully I'll remember to look here next time.
Ping - Pretty basic stuff
What I did learn, though, is that you can alter the timeout wait period using the -w [milliseconds to wait] flag.
So, if you think that a longer timeout may help diagnose a slow connection you can stretch the wait to 10 seconds like so:
Ping 1.1.1.1 -w 10000
Tracert - up just a notch from ping
I am not a network guy by any means, but if I see slow times between two servers I want to see what lies between.
You can set the same -w flag on tracert that you can on ping and lengthen the timeout if you think that may alter your results
You can also limit the number of hops with the -h flag. With a lengthened timeout, say 10 seconds, and the default 30 hops, you won't be going anywhere for a while if the trace is timing out. So to lengthen the timeout but limit the hops to 10:
tracert 1.1.1.1 -w 10000 -h 10
Printing out the results
I remembered the ">" flag to direct output to a text file like so:
Ping >mylog.txt 1.1.1.1
What I learned that was new (to me) was that I could also append to an existing file with the ">>" flag to build up a running diagnostics log as I went. So to add a tracert to the ping results I could execute this command.
tracert >>mylog.txt 1.1.1.1
Some good command line syntax references
http://commandwindows.com/command1.htm
http://www.ss64.com/nt/
Discussed variable naming conventions with a fellow developer yesterday, particularly variables that are instances of UI control (e.g. textbox, label, button) Now, the new direction away from Hungarian Notation and toward longer, more readable and, therefore, more meaningful and maintainable field names would seem to spell the end of some old friends such as: cmdSubmit, btnRun and lblMaxAge.
So, when thinking about naming conventions moving forward here are the three options I argue back and forth with myself, with varying results….
1 - Follow the new "readable" naming conventions (this is the one I settle on most often)
Combine the purpose of the control with the control type in one readable name.
e.g. SubmitButton, AgeText, AgeLabel etc
This approach, while my favorite from a straight-up conventions point of view, does have one side-effect that may not be desirable. In the VS IDE your drop down of all the controls on the form will no longer be ordered by control type as it may have been in the old days of yore (Hungarian notation)
2 - Use the old style on controls as an "exception" to the new rule to preserve IDE experience
One reason I see mentioned to use Hungarian notation still for controls is, in fact, is to have them sorted by control type in the IDE drop down. This can be helpful if you have a large form with many controls and forgot what you named something.
3 - Opt for readable names but reverse the order of the words to favor IDE discovery.
A blend of the two previous suggestions results in this option. Preserve the readability of the full words naming convention but reverse the order. Somewhat less readable but now sorted by control type in the IDE.
e.g. ButtonSubmit, TextAge, LabelAge etc.
So, which would you choose?
Recently I had the chance to examine, in detail, each of the code analysis rules built into Visual Studio 2008. These are, almost exactly, the same rules you will get in FxCop 1.36. In fact, as you consider working MS code analysis into your development lifecycle, you have three options:
- Use the built-in code analysis in Visual Studio on the development machines
- Use FxCop as part of the continuous integration/build process
- Use both
Using the built-in analysis is bit less flexible than FxCop. The extensibility that makes FxCop so useful is not officially supported in the built-in tool. However, creating custom rules and adding them to the rules that VS makes available thru the IDE seems to work just fine, it's just "not supported". Seems like it will be in a future version. The built-in tool is configured by per-project settings in VS. So, while you could define a corporate project template in VS easily enough, the built-in solution becomes more of a suggestion and each project can drift from the start point. To define a corporate standard that can be enforced in the check-in/build process the FxCop stand-alone executable seems like it would better fit the bill. I am actually thinking that both, applied with a good measure of understanding, patience and determination, could really help a shop kick up the quality of its code over time.
These rules are all based on the Framework Design Guidelines published by MS and now available in book form. (that's is not a pay-per-click link, go ahead click it all day if you want). As such you will find that rules are definitely slanted toward code that is meant to be consumed by other developers. In that role applying naming conventions and showing consistency with the .NET framework established patterns in Event Handlers, Exception Handling etc. will provide a familiar experience to .NET developers who are going to use our code. It also raises the bar on the core pieces of our application that will be re-used throughout the project and, perhaps, even across teams. Realistically though, no team is going to apply all these rules, even Microsoft realizes that. Even within a team, I can see how different subsets of these rules will be applied based on the nature of the project. I think the real benefit come from caring about code quality enough to bake it into your development lifecycle. Each shop is going to come up with its own flavor of standards and its own recipe on how to suggest/enforce them.
As I went thru the rules I was impressed with the detail. I was happy to see some pet peeves listed, such as CA2001 Avoid Calling Problematic Methods which screen for code that calls, among other methods, GC.Collect(). It is always nice to know when a dev has slipped that one in to "fix" a problem he was having with memory consumption. You have also got to love some of the rule names such as my favorite: CA1505 Avoid unmaintainable code. Gee, I never would have thought of that! :-) Maybe we should have one called "Avoid buggy code". Kidding aside, the rule is based on code complexity metrics and is one rule that overlaps with the Visual Studio Code Metrics tool as it is based on the structural complexity of the code as indicated by cyclomatic complexity and lines of code etc. So the rule is valid, I just love the name.
There are also rules that are based on idiosyncrasies of the CLR that I was unaware of and that proved to be an education. One example:
CA1809 Avoid excessive locals
A common performance optimization is to store a value in a processor register instead of memory, which is referred to as enregistering the value. The common language runtime considers up to 64 local variables for enregistration. Variables that are not enregistered are placed on the stack and must be moved to a register before manipulation. To allow the possibility that all local variables get enregistered, limit the number of local variables to 64.
Now, my first thought was "who need 64 locals to a method! Still I had not heard of enregistering prior to this. It may never affect a single line of my code, but I still love to know what is going on under the code that I write. A little googling led me to some good articles that mentioned the subject.
.NET Performance - The Crib Sheet
Writing High-Performance Managed Applications
That is just one example among many. Reviewing the rules in detail proved much more enlightening that I had expected. I would encourage it as a project worthy of some time investment. I hope to blog about some of the other rules that I found interesting.
Hit this today attempting to install WATIR on my current development box. The domain has a proxy server that has only occasionally caused me issues, but now I was unable to use gem to install WATIR unless I could configure the proxy. The correct syntax was harder to find than I expected, so I thought I would capture it here:
To configure a proxy server, with associated username and password, execute this in your command window: (obviously replace out the relevant bits)
set HTTP_PROXY=http://username:password@domain-proxy-name:8080
The thread that I happened to find this on was here, I am sure there are others
http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/fdcc4268553756de?pli=1
Running gem update --system Now succeeded, however my attempt to run gem install watir kept timing out, not sure why, so I fell back to downloading the gem file to disk then running the install with a local path gem install c:\path…\watir-1.6.2.gem and I was up and running.
For a long time I have wanted to be able to do this without it being a 2 day ordeal, or having to beg IT to open up some ports etc. Seems to me the last time I looked this was a lot harder than it is now. Has it gotten easier or did I just assume it was annoying and not really consider it? Not sure, but it has been a real life-saver on recent projects, especially SharePoint. Here are the links that got me up and running quickly.
- Best one to start with talks you thru the basic setup requirements:
http://www.wictorwilen.se/Post/How-to-get-Remote-Debugging-work-properly.aspx
- Another take on the same setup:
http://www.sharepointblogs.com/llowevad/archive/2008/04/10/remote-debugging-gac-d-assemblies-in-sharepoint.aspx
- On 2003 and 2008 servers you can have multiple w3wp.exe processes running, how to know which one matches your app pool
http://blogs.thesitedoctor.co.uk/tim/2007/10/16/Identify+Which+Application+Pool+Is+Associated+With+Which+W3WPexe+Process.aspx
the above link refers to 2003 and before and makes use of cscript.exe, on 2008 you need a different script. Here is a sample batch file. It will list all the active worker processes along with their process id and app pool name.
1: cd %systemroot%\system32\inetsrv
2: appcmd.exe list wp
3: Pause
- When you attach to a worker process for a long debug session, IIS may kill the process while you are debugging since, to its health monitor, it appears to not be responding. How to set IIS and your app pool to leave you alone and let you work.
http://msdn.microsoft.com/en-us/library/bb763108.aspx
- The last thing you will most likely want is to have your current symbol files deployed to the server's GAC as well. The folders are hidden so this will make the process easier. You can copy the symbols from a share on your dev machine or build server or deploy them locally and then copy them from there. This last project I had three assemblies one each for Branding, Controls and Business Logic and one for Web Parts. This simple batch would deploy my symbol files each time I deployed to the server and I would be all set up to debug when I needed to.
1: copy \\BUILD_SERVER\PROJECT_NAME.Branding\bin\Debug\PROJECT_NAME.Branding.pdb c:\windows\assembly\gac_msil\PROJECT_NAME.Branding\1.0.0.0__838b0bf4b15f93ce
2: copy \\BUILD_SERVER\PROJECT_NAME.Controls\bin\Debug\PROJECT_NAME.Controls.pdb c:\windows\assembly\gac_msil\PROJECT_NAME.Controls\1.0.0.0__838b0bf4b15f93ce
3: copy \\BUILD_SERVER\PROJECT_NAME.WebParts\bin\Debug\PROJECT_NAME.WebParts.pdb c:\windows\assembly\gac_msil\PROJECT_NAME.WebParts\1.0.0.0__838b0bf4b15f93ce
4: pause
I was posting a WPF question on stackoverflow and I took a few minutes to tie up loose ends on a question I had asked back in September about how to best go about developing web parts for SharePoint as an ASP.NET developer. I was just getting started out with rough proto-types of what the client was requesting and was doing all my mock-ups in ASP.NET web forms. I didn't want to be "slowed down" by any SharePoint learning curve. I was comfortable in ASP.NET and just wanted to be able to deploy my ASP.NET user controls into SharePoint and not get my hands dirty actually learning SharePoint. I asked the question hoping for a quick work-around that would fit my needs. So here I am 3 months later, a SharePoint survivor. Question is: would I start the same way if I had it to do again?
Not a chance!
Disclaimer: To be honest, I did get some good responses to my question with suggestions on work-around's that are available such as web parts that have been written to host ASP.NET user controls. Also, I was informed that you can actually deploy both user controls and even full ASP.NET pages to the SharePoint hive (folder structure where disk-based SharePoint resources are stored) and they just work, though your access to the SharePoint object model will be limited. These are viable options that will get you up and running fairly quickly. However, in my brief experience, it is not the way I would choose to go.
The problem with SharePoint, in my jaded opinion, is that it is too easy. In fact it could be called the new Access. You can read some articles, follow a few tutorials, point and click your way to version 1.0 of your internal HR site and call yourself a SharePoint Developer. Yes, SharePoint is definitely easy....at first. However, that doesn't cut it in the long run and you should be very afraid of version 2.0 when it comes along. It is easy to install a new blog or department calendar, set up a page for HR to start uploading files and photos of the company picnic. That's all well and good, but we are not talking about out-of-the-box web parts here. Now we've moved on to custom web parts that need to be built from scratch and be robust, secure and user friendly. This is when we hit it, the SharePoint learning curve, more like a wall really, or a cliff with a whole pile of bleached bones at the base. Fact is, if you are a serious developer, you are going to hit this wall sooner or later. The last 20% always gets you when you are working with a platform that is designed to make it all "easy". That being the case, make the conscious decision to hit the wall sooner. If you put off the "learning wall of despair" too long, it will hit when you at a point in your timeline when you can't afford any unpredictable delays. Others, and even you, may think you are "done" ("it's all coded we just need to deploy it and we're good"). For some reason project managers and stakeholders take issue when "done" turns into a 3-6 week delay as you come up to speed with all the goodness that is SharePoint deployment. So, when starting on your first SharePoint project, dive in, the waters tepid! In the long term you, and your project will be better for it.
As a side point, a comment on the value of having SharePoint as a skill in your toolbox:
SharePoint will never be my choice of a application platform to work with. However life, as it turns out, is not all about what we want. Who would've thunk it? All that being said, it is a skill and it is not an easy one to acquire an expert level understanding of. I think a more accurate label for SharePoint, as the blog title indicates, is the new Oracle, in that it is hard, complex, has an almost a complete lack of effective tooling, is about as developer friendly as wet punch cards, and the majority of developers who claim to have SP skilz, couldn't code their way out of a cardboard web part. Call me cynical, but I think it's a fairly accurate assessment. Match that situation with a high client demand for SharePoint development and you have, in my opinion, a technology worthy of black turtlenecks and designer level salaries. So I guess this post proves you can find a silver lining in any technology. :-)
If you are faced with a SharePoint learning wall, grab the opportunity and learn it well. Don't become another SharePoint/Access developer.
Here are some links that helped me get up to speed.
More Posts
Next page »