File Upload Corrupts Word Macros

220 views Asked by At

I have a VB.net program. The user downloads, opens, saves and uploads a word document to the server it was downloaded from. The program I am using to upload my file needs to have parameters passed with it.

The program works for about 80% of documents I have tried to upload but for the ones that don't work something happens between the time the user saves the file and it is uploaded to the server.

When I open a document that has had this issue I receive an insufficient memory error when opened.

This is the code to the program I am using:

Imports Microsoft.Office.Interop
Imports System
Imports System.IO
Imports System.Net
Imports System.Web
Imports System.Collections
Imports System.Collections.Specialized
Imports System.Threading
Public Class Form1

' Private WithEvents oWord As Word.Application
Private trd As Thread
Dim WithEvents oWord As New Microsoft.Office.Interop.Word.Application
Dim WithEvents wc As New System.Net.WebClient()
Dim list As New List(Of String)
Dim GetString As String
Dim FileWOEX As String
Dim ORGDoc As String
Dim MergeVar As String
Dim Server As String
Dim DocPath As String
Dim FileName As String
Dim ToPath As String
Dim INCOMP As String
Dim INNUM As String
Dim strCommonAppData As String
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load

    Dim list As New List(Of String)
    Dim linef As String
    Dim x As Integer
    Try
        Const ssfCOMMONAPPDATA = &H23

        strCommonAppData = CreateObject("Shell.Application").NameSpace(ssfCOMMONAPPDATA).Self.Path & "\MCCIPRS\"
    Catch ex As Exception
        MsgBox("Data File Path Not Found, an Error occurred during install, please uninstall and reinstall our program!")
        oWord.Quit()
        Me.Close()
    End Try
    Try
        GetString = Command()
        MergeVar = GetString.Substring(11, 1)
        INCOMP = GetString.Substring(0, 2)
        If (INCOMP.Substring(0, 1) = "0") Then
            INCOMP = INCOMP.Substring(1, 1)
        End If
        INNUM = GetString.Substring(2, 9)
        ORGDoc = GetString.Substring(12)
        Server = ORGDoc.Substring(0, (ORGDoc.IndexOf("/", 9)) + 1)
        DocPath = ORGDoc.Substring((ORGDoc.IndexOf("/", 9)) + 1)
        FileWOEX = ORGDoc.Substring(0, (ORGDoc.Length) - 4)
        FileName = IO.Path.GetFileName(DocPath)
        ToPath = DocPath.Substring(0, (DocPath.Length - FileName.Length))
    Catch ex As Exception
        MsgBox("Data from Web Is Invalid:" & ex.ToString())
        oWord.Quit()
        Me.Close()
    End Try
    Try
        If (System.IO.File.Exists(strCommonAppData & IO.Path.GetFileName(ORGDoc))) Then
            System.IO.File.Delete(strCommonAppData & IO.Path.GetFileName(ORGDoc))
        End If
        My.Computer.Network.DownloadFile(ORGDoc, strCommonAppData & IO.Path.GetFileName(ORGDoc), "", "")
    Catch ex As Exception
        MsgBox("There was a Problem Retrieving the Form from the web Please ensure the file exists or Contact you Administrator" & ex.ToString())
        oWord.Quit()
        Me.Close()
    End Try

    Try
        ' Make Word visible.
        oWord.Visible = True

        oWord.Documents.Open(strCommonAppData & IO.Path.GetFileName(ORGDoc))
    Catch ex As Exception
        MsgBox("There was an error when opening Word please ensure Word was installed correctly" & ex.ToString())
        oWord.Quit()
        Me.Close()
    End Try
    Try
        If MergeVar = "M" Then
            trd = New Thread(Sub()
                                 Using frm As New Form2
                                     Application.Run(frm)
                                 End Using
                             End Sub)
            trd.Start()
            Try
                If (System.IO.File.Exists(strCommonAppData & IO.Path.GetFileName(FileWOEX) & ".txt")) Then
                    System.IO.File.Delete(strCommonAppData & IO.Path.GetFileName(FileWOEX) & ".txt")
                End If
                My.Computer.Network.DownloadFile(FileWOEX & ".txt", strCommonAppData & IO.Path.GetFileName(FileWOEX) & ".txt", "", "")
            Catch ex As Exception
                MsgBox("There was an issue downloading the Macro File from Server " & ex.ToString())
                oWord.Quit()
                Me.Close()
            End Try
            Using r As StreamReader = New StreamReader(strCommonAppData & IO.Path.GetFileName(FileWOEX) & ".txt")
                ' Store contents in this String.
                ' Read first line.
                linef = Trim(r.ReadLine())
                x = 0
                Do While (Not linef Is Nothing)

                    ' Add this line to list.
                    list.Add(linef.Substring(13, linef.IndexOf("(") - 13))

                    list.Add(linef.Substring(linef.IndexOf("(") + 2, (linef.IndexOf(")") - 3) - linef.IndexOf("(")))
                    Try
                        Call oWord.Run(list(x), list(x + 1))
                    Catch ex As Exception
                        trd.Abort()
                        MsgBox("There was an issue filling Macros within this Word file the display may be incorrect")
                        'MsgBox("Macro Issues: " & list(x) & " " & list(x + 1) & " " & ex.ToString())
                    End Try
                    ' Read in the next line.
                    linef = r.ReadLine
                    x = x + 2
                Loop
            End Using
    trd.Abort()

        Else
    x = 0
        End If
    Catch ex As Exception
        trd.Abort()
        MsgBox("There was an issue filling Macros within this Word file the display may be incorrect")
    End Try
    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
    Me.Opacity = 0
End Sub

'create wordApplication object with the key word “WithEvents”

Private Sub oWord_DocumentBeforeClose(ByVal Doc As Microsoft.Office.Interop.Word.Document, ByRef Cancel As Boolean) Handles oWord.DocumentBeforeClose
    'oWord.ActiveDocument.Close(Word.WdSaveOptions.wdSaveChanges)
    oWord.ActiveDocument.Close()
    oWord.Quit()
    Try
        Dim filepath As String
        Dim url As String = Server & "pdtest/PD026U.pgm"
        'Dim url As String = "http://192.168.95.1:83/file.php"
        filepath = strCommonAppData & IO.Path.GetFileName(ORGDoc)
        Dim request As HttpWebRequest = DirectCast(HttpWebRequest.Create(url), HttpWebRequest)
        request.PreAuthenticate = True
        request.AllowWriteStreamBuffering = False

        Dim boundary As String = System.Guid.NewGuid().ToString()

        request.ContentType = String.Format("multipart/form-data; boundary={0}", boundary)
        request.Method = "POST"
        request.Credentials = New System.Net.NetworkCredential("ehavermale", "ernie1")

        ' Build Contents for Post
        Dim header As String = String.Format("--{0}", boundary)
        Dim footer As String = header & "--"

        Dim contents As New System.Text.StringBuilder()
        Dim FileHead As New System.Text.StringBuilder()

        ' file
        FileHead.AppendLine(header)
        FileHead.AppendLine(String.Format("Content-Disposition: form-data; name=""upfile""; filename=""{0}""", IO.Path.GetFileName(filepath)))
        FileHead.AppendLine("Content-Type: application/octet-stream")
        FileHead.AppendLine()

        contents.AppendLine(header)
        contents.AppendLine("Content-Disposition: form-data; name=""task""")
        contents.AppendLine()
        contents.AppendLine("upload")

        contents.AppendLine(header)
        contents.AppendLine("Content-Disposition: form-data; name=""INCOMP""")
        contents.AppendLine()
        contents.AppendLine(INCOMP)

        contents.AppendLine(header)
        contents.AppendLine("Content-Disposition: form-data; name=""INCNUM""")
        contents.AppendLine()
        contents.AppendLine(INNUM)

        contents.AppendLine(header)
        contents.AppendLine("Content-Disposition: form-data; name=""ToPath""")
        contents.AppendLine()
        contents.AppendLine(ToPath)

        ' Footer
        contents.AppendLine(footer)

        ' This is sent to the Post
        Dim bytes As Byte() = System.Text.Encoding.UTF8.GetBytes(contents.ToString())
        Dim FileBytes As Byte() =          System.Text.Encoding.UTF8.GetBytes(FileHead.ToString())
        Dim SendFBytes() As Byte = My.Computer.FileSystem.ReadAllBytes(filepath)

        request.ContentLength = bytes.Length + FileHead.Length + SendFBytes.Length

        Using requestStream As Stream = request.GetRequestStream()
            requestStream.Write(FileBytes, 0, FileBytes.Length)
            requestStream.Write(SendFBytes, 0, SendFBytes.Length)
            requestStream.Write(bytes, 0, bytes.Length)
            requestStream.Flush()
            requestStream.Close()

            Using response As WebResponse = request.GetResponse()
                Using reader As New StreamReader(response.GetResponseStream())
                    Dim strResponseData As String = reader.ReadToEnd()
                End Using
            End Using
        End Using
    Catch ex As Exception
        MsgBox("There was an Error on File Upload Please Contact you Administrator for assistance : " & ex.ToString())
    End Try
    oWord.Application.Quit()
    oWord = Nothing

    Me.Close()
End Sub

End Class

Is there something I am missing in the GetRequestStream when I am encoding and writing the file to the stream? This code seems to be my issue I am just unsure what is causes it to break on some files but not all.

1

There are 1 answers

0
Ehaver282 On

Found out my problem. It turns out the headers I was sending my server were not the ones it needed. So I changed them and added an encoding type and it worked!