Wednesday, March 09, 2005

Editing documents in sharepoint library in Office 2000



"Edit
In" functionality is only available for Office XP and Office 2003 on
the client, however I saw this workaround from a now unknown poster and


Joel Faigin

was kind enough to confirm that it works.


Â

"Office 2000 is not supported to edit documents within the Document Library under the "All Documents" view.



But here is a work around to get the same exact function from Office 2000 as you do in Office 2003.

This is for working with Windows 2000 and Office 2000.

1. Open your particular document library.

2. Make sure "All Documents" view is selected.

3. Check Out the file (do not open the file just check it out)

4. Click "Explorer View"

5. Open the document you checked out and then edit and save the document.

6. Now return to the "All Documents" view.

7. Check In the document, and make your selections as well as enter your comments.


8. Your changes should now be shown, as well as version history if enabled."


from:

http://wss.collutions.com/Lists/FAQ/DispForm.aspx?ID=308

Obituary - My VS.NET 2003 debugger

VS.NET 2003 debugger died unexpectedly today. I get an access denied
error with a suggestion to add myself to Debugger Users group or be an
Administrator.


I'm already the administrator and also part of Debugger users group.


Googling a bit, found a collection of entries on M K Park's blog

Feature Request: Environment variable expansion in CMAB

I've been using CMAB for sometime now and the only big crib that I have
against it is that it doesnt support environment variables for
specifying things like the path of the actual configuration file [One
of the projects that does is Log4Net]


I've looked at the code and supporting environment variable expansion shoudlnt be too difficult to do.


I'll post a suggestion in and see what happens.

Enterprise Library

Probably I've been living in a cave...but looks like we've got a release of the enterprise library.


"Summary

The patterns & practices Enterprise Library is a library
of application blocks designed to assist developers with common
enterprise development challenges. Application blocks are a type of
guidance, provided as source code that can be used "as is," extended,
or modified by developers to use on enterprise development projects.
Enterprise Library features new and updated versions of application
blocks that were previously available as stand-alone application
blocks. All Enterprise Library application blocks have been updated
with a particular focus on consistency, extensibility, ease of use, and
integration."

I've just got a copy of it. The cribs are

A. The download locations for the old Application Blocks is still in
place. They don't link to the Enterprise library page either. (Though
GDN does have a note pointing users to the Enterprise library workspace)

B. I've yet to look at the Blocks in detail, but the changes are big and not very helpful.

a. Namespaces have changed.

b. There's a new configuration tool

c. The documentation's been updated but there's precious little for people migrating from older versions.

d. [Configuration Application Block] <Crib>
Name value collections are not supported and so are XML Serializer. One
of the beauties of the original release was that you could integrate it
with the standard classes seamlessly. Probably, this one does too, but
I'll need to look it up.

Coaxing IE to open office documents in Application windows

Found this great tip on preventing IE from opening office documents.
  1. Launch Windows Explorer.
  2. Select “Folder Options...“ from the Tools menu.
  3. Select the “File Types“ tab.
  4. Scroll down the list of “Registered file types“ until you find “DOC - Microsoft Word Document“ and select it.
  5. Click on the “Advanced...“ button at the bottom of the dialog.
  6. Uncheck the “Browse in same window“ checkbox.

from:

http://blogs.msdn.com/gusperez/archive/2004/04/28/122768.aspx


Obituary - My VS.NET 2003 debugger

VS.NET 2003 debugger died unexpectedly today. I get an access denied
error with a suggestion to add myself to Debugger Users group or be an
Administrator.


I'm already the administrator and also part of Debugger users group.


Googling a bit, found a collection of entries on M K Park's blog

Feature Request: Environment variable expansion in CMAB

I've been using CMAB for sometime now and the only big crib that I have
against it is that it doesnt support environment variables for
specifying things like the path of the actual configuration file [One
of the projects that does is Log4Net]


I've looked at the code and supporting environment variable expansion shoudlnt be too difficult to do.


I'll post a suggestion in and see what happens.

Enterprise Library

Probably I've been living in a cave...but looks like we've got a release of the enterprise library.


"Summary

The patterns & practices Enterprise Library is a library
of application blocks designed to assist developers with common
enterprise development challenges. Application blocks are a type of
guidance, provided as source code that can be used "as is," extended,
or modified by developers to use on enterprise development projects.
Enterprise Library features new and updated versions of application
blocks that were previously available as stand-alone application
blocks. All Enterprise Library application blocks have been updated
with a particular focus on consistency, extensibility, ease of use, and
integration."

I've just got a copy of it. The cribs are

A. The download locations for the old Application Blocks is still in
place. They don't link to the Enterprise library page either. (Though
GDN does have a note pointing users to the Enterprise library workspace)

B. I've yet to look at the Blocks in detail, but the changes are big and not very helpful.

a. Namespaces have changed.

b. There's a new configuration tool

c. The documentation's been updated but there's precious little for people migrating from older versions.

d. [Configuration Application Block] <Crib>
Name value collections are not supported and so are XML Serializer. One
of the beauties of the original release was that you could integrate it
with the standard classes seamlessly. Probably, this one does too, but
I'll need to look it up.

Monday, March 07, 2005

Sharepoint Web Services and NTLM Authentication

I noticed this strange behaviour and thought its worth a post - till I find a solution/explanation.


Scenario: I have a custom web service running under sharepoint. This means that the .asmx is in "c:\Program Files\Common Files\Microsoft Shared\web server extensions\60\ISAPI" and the binaries in the bin folder under it. The url of the web service is



http://aditi277/XTeam/spaces/outlooksynch/_vti_bin/OfflineServices.asmx


The _vti_bin has NTLM authentication enabled.


When I paste the url in a browser, I go straight through to the page without any authentication! (I've set "Prompt for username and password" in IE).


In the web service, Context.Request.IsAuthenticated returns False and Context.User.Identity.Name returns an empty string. This is as expected.


I have a small program that connects to the web service. In the program I'm setting the credentials for the web service.


The fun starts when I create an SPSite object in the web service code. The SPWeb.CurrentUser.ToString() returns the username of the credentials set on the client!!! How the heck is the identity being passed on to Sharepoint? Or is it a bug in sharepoint that it doesnt set the Context properties? I'm stumped!!!


Â


Sharepoint Web Services and NTLM Authentication

I noticed this strange behaviour and thought its worth a post - till I find a solution/explanation.


Scenario: I have a custom web service running under sharepoint. This means that the .asmx is in "c:\Program Files\Common Files\Microsoft Shared\web server extensions\60\ISAPI" and the binaries in the bin folder under it. The url of the web service is



http://aditi277/XTeam/spaces/outlooksynch/_vti_bin/OfflineServices.asmx


The _vti_bin has NTLM authentication enabled.


When I paste the url in a browser, I go straight through to the page without any authentication! (I've set "Prompt for username and password" in IE).


In the web service, Context.Request.IsAuthenticated returns False and Context.User.Identity.Name returns an empty string. This is as expected.


I have a small program that connects to the web service. In the program I'm setting the credentials for the web service.


The fun starts when I create an SPSite object in the web service code. The SPWeb.CurrentUser.ToString() returns the username of the credentials set on the client!!! How the heck is the identity being passed on to Sharepoint? Or is it a bug in sharepoint that it doesnt set the Context properties? I'm stumped!!!


Â


Friday, March 04, 2005

I N K S C A P E

Just discovered something great - Inkscape - go grab a copy and enjoy...


Â


Logging in ASP.NET - Web Services (contd.)

I'm almost through with a decent logging implementation for a Web service running under Windows Sharepoint services. Here are some hard earned lessons:


1. I could not use Global.asax for a sharepoint hosted web service. The Sharepoint web services Global.asax derives from stssoap and when I included the code in a C# script block, the code never got invoked.


2. Also, the concept of an application is not useful in the case of web service - since a single web might be used to host multiple services. So, now, I've moved all the Log4Net initialization code to the ASMX code behind ctor. I've also got a SetContext() method that sets the user name, application (service) name. I'm also mulling about including the last few characters from the session key - for cases where the same user is logged on from multiple machines.


3. I need to do some more fine tuning - like enabling the connection pooling for the log4net connection string.


4. Another great lesson learned - and this is for all the times when you've got all the bits of log4net up and running and yet can't seem to get the logs...Use the log4net Debug release with the DbgView utility from sysinternals. Log4net fails silently on errors and just doesn't give you a clue as to what happened. For all those times when something utterly silly like a typo in your config brings all your logging to a standstill, keep DbgView running side by side. If Log4net hits a problem, it'll get logged in the dbgview console. :)


I N K S C A P E

Just discovered something great - Inkscape - go grab a copy and enjoy...


Â


Logging in ASP.NET - Web Services (contd.)

I'm almost through with a decent logging implementation for a Web service running under Windows Sharepoint services. Here are some hard earned lessons:


1. I could not use Global.asax for a sharepoint hosted web service. The Sharepoint web services Global.asax derives from stssoap and when I included the code in a C# script block, the code never got invoked.


2. Also, the concept of an application is not useful in the case of web service - since a single web might be used to host multiple services. So, now, I've moved all the Log4Net initialization code to the ASMX code behind ctor. I've also got a SetContext() method that sets the user name, application (service) name. I'm also mulling about including the last few characters from the session key - for cases where the same user is logged on from multiple machines.


3. I need to do some more fine tuning - like enabling the connection pooling for the log4net connection string.


4. Another great lesson learned - and this is for all the times when you've got all the bits of log4net up and running and yet can't seem to get the logs...Use the log4net Debug release with the DbgView utility from sysinternals. Log4net fails silently on errors and just doesn't give you a clue as to what happened. For all those times when something utterly silly like a typo in your config brings all your logging to a standstill, keep DbgView running side by side. If Log4net hits a problem, it'll get logged in the dbgview console. :)


Thursday, March 03, 2005

Logging in ASP.NET

I've been trying to get decent logs on web application/web service. Its critical in cases where you dont have remote debugging access on the server.


I've been using Log4Net for over an year now and it's saved me more than once. It's the first time that I've tried to use it in a web scenario. There's just a couple of things to keep in mind:


Usually the worker process runs under the ASPNET account - this doesnt have rights to logon and doesnt have an associated console. Meaning console appender is out of the reckoning.


You could use FileAppender (the usual choice on single user applications), however, as multiple requests are served simultaneously, the logs will most probably quite unreadable.


The best choice is the ADONetAppender - you log everything in the DB and then use SQL to get a trace. Here we come across the next problem - how do you get the user information for each log entry?


The solution lies in using log4net's Mapped Diagnostic Context - MDC. Its basically a set of name value pairs that you can render using a pattern layout %X{name} in the log4net config file.


Here's the Log4Net.config file for reference

<>

Note the lines where the insert statement has an the username parameter and the additional param tag is added to the parameter list. You'll need to create a matching column definition in your table.


The next issue to be tackled is the log4net initialization and setting the username for the request.


The log4net system can be initialized the Application_onStart event and you can set the username in the PreRequestHandlerExecute event - this event is called just before the request is handed off for processing to the HttpModule and hence the best place to set the username. Relevant portions of Global.asax are shown below.


Â



protected
void Application_Start(Object sender, EventArgs e)
{
   ConfigureLog4Net();          Â
   Debug.WriteLine("In Application Start");
}

privatevoid ConfigureLog4Net()
{
   string filepath = Server.MapPath("log4net.config");
   Debug.WriteLine(filepath);
   FileInfo fs = new FileInfo(filepath);
   log4net.Config.DOMConfigurator.ConfigureAndWatch(fs);
   Debug.WriteLine("Finished Log4net configuration");
}

protectedvoid Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
       Debug.WriteLine("In PreRequestHandlerExecute");
   if (!LogManager.GetLoggerRepository().Configured)
   {
           Debug.WriteLine("Log4net not configured, calling configure");
           ConfigureLog4Net();
   }
   Debug.WriteLine(Context.User.Identity.Name);
   log4net.MDC.Set("user",Context.User.Identity.Name);
}


Logging in ASP.NET

I've been trying to get decent logs on web application/web service. Its critical in cases where you dont have remote debugging access on the server.


I've been using Log4Net for over an year now and it's saved me more than once. It's the first time that I've tried to use it in a web scenario. There's just a couple of things to keep in mind:


Usually the worker process runs under the ASPNET account - this doesnt have rights to logon and doesnt have an associated console. Meaning console appender is out of the reckoning.


You could use FileAppender (the usual choice on single user applications), however, as multiple requests are served simultaneously, the logs will most probably quite unreadable.


The best choice is the ADONetAppender - you log everything in the DB and then use SQL to get a trace. Here we come across the next problem - how do you get the user information for each log entry?


The solution lies in using log4net's Mapped Diagnostic Context - MDC. Its basically a set of name value pairs that you can render using a pattern layout %X{name} in the log4net config file.


Here's the Log4Net.config file for reference

>

Note the lines where the insert statement has an the username parameter and the additional param tag is added to the parameter list. You'll need to create a matching column definition in your table.


The next issue to be tackled is the log4net initialization and setting the username for the request.


The log4net system can be initialized the Application_onStart event and you can set the username in the PreRequestHandlerExecute event - this event is called just before the request is handed off for processing to the HttpModule and hence the best place to set the username. Relevant portions of Global.asax are shown below.


Â



protected
void Application_Start(Object sender, EventArgs e)
{
   ConfigureLog4Net();          Â
   Debug.WriteLine("In Application Start");
}

privatevoid ConfigureLog4Net()
{
   string filepath = Server.MapPath("log4net.config");
   Debug.WriteLine(filepath);
   FileInfo fs = new FileInfo(filepath);
   log4net.Config.DOMConfigurator.ConfigureAndWatch(fs);
   Debug.WriteLine("Finished Log4net configuration");
}

protectedvoid Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
       Debug.WriteLine("In PreRequestHandlerExecute");
   if (!LogManager.GetLoggerRepository().Configured)
   {
           Debug.WriteLine("Log4net not configured, calling configure");
           ConfigureLog4Net();
   }
   Debug.WriteLine(Context.User.Identity.Name);
   log4net.MDC.Set("user",Context.User.Identity.Name);
}


Friday, February 25, 2005

Part 6: Efficiently Representing Sets - Continued...

Great article. Gives some very valuable information on implementing sets with a finite universe.


It doesn't suit my requirements - I need to represent sets where the universal set might be infinite - like, say the set of strings.


The trouble starts with trying to implement the set complement operation - you can't obviously list an infinite set, so the trick is to represent it as a cofinite set. I haven't really read up on cofinite sets, but the layman definition goes as


'A set whose complement is finite'


Well that's it. So keep a flag with the data structure to indicate a set complement.


The ElementOf operation is trivial to implement. Subset is trickier and so's union, intersection and difference.


I just completed a bare bones implementation using a hashmap. All the tests are working (got 20 of them). You can find it here if you're interested.


Part 6: Efficiently Representing Sets - Continued...

Great article. Gives some very valuable information on implementing sets with a finite universe.

It doesn't suit my requirements - I need to represent sets where the universal set might be infinite - like, say the set of strings.

The trouble starts with trying to implement the set complement operation - you can't obviously list an infinite set, so the trick is to represent it as a cofinite set. I haven't really read up on cofinite sets, but the layman definition goes as

'A set whose complement is finite'

Well that's it. So keep a flag with the data structure to indicate a set complement.

The ElementOf operation is trivial to implement. Subset is trickier and so's union, intersection and difference.

I just completed a bare bones implementation using a hashmap. All the tests are working (got 20 of them). You can find it here if you're interested.

Thursday, February 24, 2005

Visual C# Developer Center: Part 6: Efficiently Representing Sets

And now I need to roll out my own version of a set datastructure library. C# has hashmaps - they come close but aren't really sets. You can use them to implement sets, but that's about it. Also, I want my sets to conform to one of the standard collection interfaces so that they can interoperate with code. And I REALLY REALLY need set intersection, set union and set difference!

I've been looking on the net for some guidelines to implement the same - implementing a data structure is never easy so its better to be cautious to get it right. Just found this article which seems to fit the bill.

Visual C# Developer Center: Part 6: Efficiently Representing Sets

Hope this helps. Will post more on the article later.

CAPICOM - Accessing CryptoAPI from VB6

I've this need to calculate a file fingerprint in VB6. So the need to access CrptoAPI in vb6. Didnt want to do win32 calls from VB and thankfully MS has a COM layer over cryptoAPI called CAPICOM. Useful stuff...as the MSDN site says


"Summary: CAPICOM is a new security technology from Microsoft that allows Microsoft Visual Basic, Visual Basic Script, ASP, and C++ programmers to easily incorporate digital signing and encryption into their application. (5 printed pages)"


Okay, now you can calculate SHA1, SHA-256 and SHA512 using VB. Trouble was that you cannot use the Filesystem object as it doesnt read binary files.


Here's a small sample that does a SHA1 for binary files in VB6.




Const BUFFER_SIZE AsString= 4096
Dim sha As CAPICOM.HashedData
Set sha =New CAPICOM.HashedData

f =FreeFile
Open "somebinaryfile.xyz"For Binary As f

Dim totalbytes AsLong
totalbytes =LOF(f)
Dim currentPos AsLong
currentPos = 0

While currentPos + BUFFER_SIZE <= totalbytes
Get f, , buffer
currentPos = currentPos + BUFFER_SIZE
sha.Hash buffer
Wend

Dim chunk() AsByte
Dim chunkSize AsLong
chunkSize = totalbytes - currentPos
If (chunkSize > 0) Then
ReDim chunk(1 To chunkSize)
Get f, , chunk
sha.Hash chunk
EndIf

Close f
txtHash.Text = sha.Value