none
File.Copy and File.Move create blank Word documents RRS feed

  • Question

  • Hi!

    I have an ASP.NET application that uses the File.Copy and File.Move commands to perform document management tasks.  We recently upgraded from Office 2003 on Windows XP to Office 2010 on Windows 7.

    Before the upgrade, everything was fine.  After the upgrade, whenever a user copies or renames a Word document (whether it is an old Word 2003 ".doc" document or a new Word 2010 ".docx" or ".docm" document), the File.Copy and File.Move commands produce blank documents.  In the case of File.Copy, both the original document and the copy are blank.  File.Move seems to move the document, but delete all its contents.  Text, graphics, everything is gone! 

    The command syntax is:

    File.Move(strFilePath, strNewFile)

    File.Copy(strFilePath, strNewFile)

    where:

    "strFilePath" is the fully qualified path to the existing document and

    "strNewFile" is the fully qualified path to the new document

    Can anyone help me, please?  I'm in a bit of a panic as my users rely on this application heavily for their document management.  Outside of the upgrade to Windows 7 and Office 2010, nothing about the application has changed, so I am at a loss to figure out why these commands now produce blank documents.

    Thanks for any help you can give.

    C.



    • Edited by cseverin Thursday, May 10, 2012 4:32 PM
    Thursday, May 10, 2012 4:28 PM

Answers

  • Okay, in case anyone is interested, I found a solution to this problem and it has absolutely nothing to do with permissions, impersonation, IIS or even Word!

    After many days of fumbling around trying this and that, including completely rebuilding and upgrading my development server enviroment to be running Windows 2008 R2/IIS 7/SQL Server 2012, I discovered the problem still existed!  Argh!  My documents were still being emptied of their contents after a File.Copy or File.Move command.

    As I mentioned elsewhere in this thread, one thing I tried was creating a brand new Windows app to create a ".docm" file and then create a copy of it using the File.Copy command.  I put this app on the same server as the ASP.NET application that experiences the problem with the documents being emptied of their contents.  The Windows app runs just fine (i.e. ".docm" files are created and edited successfully and are left intact after the File.Copy command).  The ASP.NET app erases the contents of ".docm" files after the File.Copy command.

    I thought I would try copying the code I created in the Windows app and pasting it into the page of the ASP.NET application where the problem is occurring.  After making a few small changes to the page in order to run the copied code, I tried running it and lo and behold, I could create a ".docm" file, edit it, and copy it with the File.Copy command and both the original document and the copy retained their contents!

    So, what was going on? I decided to uncomment my original code a line at a time then rerun the ASP.NET to see where the documents were being erased of their contents. Links to the documents are displayed on a datagrid inside a user control on the main page of the ASP.NET application.  When the user clicks on the link, the Word document opens.  Right after I issued the File.Copy command, I was rebinding the datagrid so that it would pick up the newly created link to the copy of the original document.  BUT... further down I also raise an event to trigger the main page to reload the user control (which again rebinds the datagrid).

    For some reason, explictly rebinding the datagrid and then reloading the user control blanks out the documents.  If I remove the statement that explictly rebinds the datagrid and just let the raised event trigger the user control to be reloaded from the main page, everything is fine -- all documents are intact.

    Weird, eh? I don't understand it and at this point I'm too tired to care to try. I'm just glad it's working again!

    • Marked as answer by cseverin Wednesday, July 4, 2012 6:54 PM
    Wednesday, July 4, 2012 6:54 PM

All replies

  • Where are the documents stored?  Remember to check NTFS permissions for the ASP.net account.  I have seen this behavior when there is the right to create the file but there is no right to append data (they are two different permissions).  This would explain the zero-byte destination files.  Still, it is unexplained why the source file is affected.  File.Copy() must not alter the source in any way.  You should be able to verify this by performing a File.Copy() operation from a read-only scource like a DVD or a read-only file share in a server.

    Jose R. MCP

    Thursday, May 10, 2012 4:37 PM
  • Hi Jose,

    Thanks for your quick response.  I did some more testing as you suggested.  I temporarily changed one of our existing document files to Read-only and tried copying it and it worked fine.  As it turns out it was a Word 2003 ".doc" document file.  I did some more playing around and discovered that the problem only occurs for ".docm" and ".docx" files (i.e. any document created new in Word 2010).  The existing old Word 2003 ".doc" files seem to be fine.

    The document files themselves are stored on one of our network drives.  The website has always had full access rights to the network drive as far as I know.  As I say, before the upgrade everything worked fine.  It's only the client workstations that were upgraded, not the servers, so nothing has changed server-side. 

    You mention checking the NTFS permissions for the ASP.net account.  Where/how would I do that?  Would upgrading the client workstations somehow affect the server??

    Thanks again!

    Thursday, May 10, 2012 5:15 PM
  • Best if you ask your network administrator to check the permissions for you.  I also don't know if it is the ASP.net account or some other.  The ASP.net account was used by .net v1.1, and .net v2.0 and above use NT SECURITY\NETWORK SERVICE by default.  Still, I didn't configure your website so it may very well be using yet another account.

    In general, you can see NTFS permissions by right clicking the folder and then selecting Properties, then going into the Security tab.


    Jose R. MCP

    Thursday, May 10, 2012 5:19 PM
  • The web application uses impersonation to connect to the network drive.  We checked both the ASP.NET account and the impersonation account and both have full rights to the network drive.  As an additional test I logged on to a client workstation using the impersonation account and password and successfully copied a ".docm" Word 2010 document.

    So, it seems the permissions are okay. 

    It's only when a Word 2010 document (".docx" or ".docm") document is copied or moved through application code (i.e. using the File.Copy and File.Move commands inside an application) that the blank document problem happens.

    It's curious why it seems to only be Word 2010 documents.  The Word 2003 documents seem to have no problem.

    Thanks again for your help, Jose.

    C.

    Thursday, May 10, 2012 6:06 PM
  • Well, there may be many bugs in .net, but I cannot imagine that deleting the original file is one of them.  Your code must be doing something else that gets the file destroyed.  A simple File.Copy() doesn't modify the source file.

    Jose R. MCP

    • Proposed as answer by Ashwini47 Friday, May 11, 2012 5:48 AM
    • Marked as answer by cseverin Friday, May 11, 2012 11:40 AM
    • Unmarked as answer by cseverin Tuesday, May 22, 2012 3:21 PM
    Thursday, May 10, 2012 7:19 PM
  • Hi again.  Well my saga continues.

    After playing around for a few days and trying various things, I developed a small Windows app in VS 2010 to create a Word 2010 .docm document from a Word 2010 .dotm template and then create a copy of it using the File.Copy command.  I placed this new app on the web server that hosts my ASP.NET web application which is experiencing the problem with documents being emptied of their contents after the File.Copy and set it up to save the documents to the same network folder that my ASP.NET web application does.

    My new Windows app uses the same impersonation id as my ASP.NET web app to connect to the network drive.   The Windows app has no problem at all creating and copying Word 2010 .docm documents so it is not an access rights issue regarding the impersonation id.  The Windows app works, but the web app doesn't, so is it something to do with IIS maybe?  If so, any help you can give will be really appreciated as my IIS knowledge is extremely limited (not much of a web administrator ;-) ).  Also, as I mentioned earlier, the web app has no problem with .doc (i.e. Word 2003 format) files -- only with Word 2010 .docm and .docx files, so is it something to do with IIS not being configured properly?

    Just out of curiousity, I thought I would try accessing my ASP.NET web app using Firefox instead of my usual IE, just to rule out IE as the culprit.  It's not.  The web app experiences the same problem running in Firefox as it does in IE, so the problem does seem to be with the web app itself.

    Again, any help you can give me will be greatly appreciated!

    C.

    Friday, May 18, 2012 6:42 PM
  • Okay, I found something that I thought for sure was the solution:

    http://technet.microsoft.com/en-us/library/ee309278(v=office.12).aspx

    Since I am using IIS 6 on my web server, it made sense that I would have to register the MIME types for the new Office file types (.docx, .docm, .dotx, .dotm, etc.) So, after following the instructions in the above the link, I stopped and restarted IIS and tried my web app again.  No luck!  So, I went one step further and shut down the entire web server then brought it back up.  Still no luck.  My web app still blanks out both the source and destination .docm document files as a result of the File.Copy command.

    According to the above link, IIS 7 includes all the MIME types for the new Office file types by default, so upgrading to IIS 7 could be an option, except it requires Windows 2008 Server and I'm not in a position yet to move from Windows 2003, so that will have to wait.

    There's nothing magical or mystical happening in the web app.  The app displays a list of documents in a datagrid with a DELETE button and a COPY button beside each document.  When the user clicks on a COPY button, the following code is executed:

                       

    Imports System.IO
    Imports System.Web
    Imports System.Web.Security
    Imports System.Security.Principal
    Imports System.Runtime.InteropServices
    Imports Aspose.Words

    Partial Class controls_file_documents

        ' declarations for impersonation for saving documents on \\FileServer

        Dim strId As String = CType(ConfigurationManager.AppSettings("doc_impersonation_id"), String)
        Dim strDom As String = CType(ConfigurationManager.AppSettings("doc_impersonation_domain"), String)
        Dim strPw As String = CType(ConfigurationManager.AppSettings("doc_impersonation_password"), String)

        Dim LOGON32_LOGON_INTERACTIVE As Integer = 9
        Dim LOGON32_PROVIDER_DEFAULT As Integer = 0

        Dim impersonationContext As WindowsImpersonationContext

        Declare Function LogonUserA Lib "advapi32.dll" (ByVal lpszUsername As String, _
                                ByVal lpszDomain As String, _
                                ByVal lpszPassword As String, _
                                ByVal dwLogonType As Integer, _
                                ByVal dwLogonProvider As Integer, _
                                ByRef phToken As IntPtr) As Integer

        Declare Auto Function DuplicateToken Lib "advapi32.dll" ( _
                                ByVal ExistingTokenHandle As IntPtr, _
                                ByVal ImpersonationLevel As Integer, _
                                ByRef DuplicateTokenHandle As IntPtr) As Integer

        Declare Auto Function RevertToSelf Lib "advapi32.dll" () As Long
        Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Long


        Public Sub dgDocuments_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles dgDocuments.ItemCommand

        Dim strDocumentPath As String = "\\FileServer\MyWebApp\Documents\"               
        Dim strFilePath as String =  strDocumentPath & CType(e.Item.FindControl("txtFileName"), TextBox).Text          
        Dim strNewFileTag As String = Format(Now, "MMddhhmmss")                
        Dim strEffectiveDate As String = Format(Now, "MM/dd/yyyy")                 
        Dim strNewFileName As String = Trim(CType(e.Item.FindControl("hplFileName"), System.Web.UI.WebControls.LinkButton).Text)                  
        Dim strSuffix As String = ""
          
        If impersonateValidUser(strId, strDom, strPw) Then
               
          Try
                  
                If (e.CommandName = "DELETE") Then

                       File.Delete(strFilePath)

                ElseIf (e.CommandName = "COPY") Then

                       
                      If InStr(strFileName, ".docm") > 0 Then                       
                           strSuffix = ".docm"                   
                      ElseIf InStr(strFileName, ".docx") > 0 Then               
                           strSuffix = ".docx"                  
                      ElseIf InStr(strFileName, ".doc") > 0 Then                       
                           strSuffix = ".doc"                   
                      ElseIf InStr(strFileName, ".xls") > 0 Then               
                           strSuffix = ".xls"                    
                      ElseIf InStr(strFileName, ".pdf") > 0 Then                       
                           strSuffix = ".pdf"                    
                      ElseIf InStr(strFileName, ".txt") > 0 Then                       
                           strSuffix = ".txt"                   
                      End If

                      strNewFileName = Left(strFileName, InStr(strFileName, strSuffix) - 1) & "-COPY-" & strNewFileTag & strSuffix

                      Dim strNewFile As String = strDocumentPath & strNewFileName
                       
                      File.Copy(strFilePath, strNewFile)

                 End If

            Catch ex As Exception
                    lblError.CssClass = "label_red"
                    lblError.Text = ex.Message
            End Try

        Else
            lblError.CssClass = "label_red"
            lblError.Text = "Your impersonation failed. "
            Return
        End If

        undoImpersonation()

        Private Function impersonateValidUser(ByVal userName As String, _
                    ByVal domain As String, ByVal password As String) As Boolean

            Dim tempWindowsIdentity As WindowsIdentity
            Dim token As IntPtr = IntPtr.Zero
            Dim tokenDuplicate As IntPtr = IntPtr.Zero
            impersonateValidUser = False

            If RevertToSelf() Then
                If LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, _
                         LOGON32_PROVIDER_DEFAULT, token) <> 0 Then
                    If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
                        tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
                        impersonationContext = tempWindowsIdentity.Impersonate()
                        If Not impersonationContext Is Nothing Then
                            impersonateValidUser = True
                        End If
                    End If
                End If
            End If

            If Not tokenDuplicate.Equals(IntPtr.Zero) Then
                CloseHandle(tokenDuplicate)
            End If
            If Not token.Equals(IntPtr.Zero) Then
                CloseHandle(token)
            End If
        End Function

        Private Sub undoImpersonation()
            impersonationContext.Undo()
        End Sub

    End Class

    Before the File.Copy command is executed, the file specified by strFilePath exists and is a Word 2010 .docm file containing text. After the File.Copy command, both strFilePath and strNewFile exist as .docm documents but are blank. I am going crazy trying to solve this, so if there is anyone out there who can help me, I would greatly appreciate it.

    Thanks very much!



    • Edited by cseverin Tuesday, May 22, 2012 7:47 PM
    Tuesday, May 22, 2012 7:32 PM
  • It is hard to say.

    Ghost,
    Call me ghost for short, Thanks
    To get the better answer, it should be a better question.

    Friday, May 25, 2012 10:40 AM
  • Okay, in case anyone is interested, I found a solution to this problem and it has absolutely nothing to do with permissions, impersonation, IIS or even Word!

    After many days of fumbling around trying this and that, including completely rebuilding and upgrading my development server enviroment to be running Windows 2008 R2/IIS 7/SQL Server 2012, I discovered the problem still existed!  Argh!  My documents were still being emptied of their contents after a File.Copy or File.Move command.

    As I mentioned elsewhere in this thread, one thing I tried was creating a brand new Windows app to create a ".docm" file and then create a copy of it using the File.Copy command.  I put this app on the same server as the ASP.NET application that experiences the problem with the documents being emptied of their contents.  The Windows app runs just fine (i.e. ".docm" files are created and edited successfully and are left intact after the File.Copy command).  The ASP.NET app erases the contents of ".docm" files after the File.Copy command.

    I thought I would try copying the code I created in the Windows app and pasting it into the page of the ASP.NET application where the problem is occurring.  After making a few small changes to the page in order to run the copied code, I tried running it and lo and behold, I could create a ".docm" file, edit it, and copy it with the File.Copy command and both the original document and the copy retained their contents!

    So, what was going on? I decided to uncomment my original code a line at a time then rerun the ASP.NET to see where the documents were being erased of their contents. Links to the documents are displayed on a datagrid inside a user control on the main page of the ASP.NET application.  When the user clicks on the link, the Word document opens.  Right after I issued the File.Copy command, I was rebinding the datagrid so that it would pick up the newly created link to the copy of the original document.  BUT... further down I also raise an event to trigger the main page to reload the user control (which again rebinds the datagrid).

    For some reason, explictly rebinding the datagrid and then reloading the user control blanks out the documents.  If I remove the statement that explictly rebinds the datagrid and just let the raised event trigger the user control to be reloaded from the main page, everything is fine -- all documents are intact.

    Weird, eh? I don't understand it and at this point I'm too tired to care to try. I'm just glad it's working again!

    • Marked as answer by cseverin Wednesday, July 4, 2012 6:54 PM
    Wednesday, July 4, 2012 6:54 PM