如何以自动方式将 OLEObject 的内容保存为文件?

发布于 2024-12-28 12:00:23 字数 456 浏览 0 评论 0原文

我正在向 powerpoint 幻灯片添加一些不同的文件类型。这些类型包括 mp4、zip、swf 和其他格式。我并不是在寻找播放这些文件类型的方法;而是在寻找一种方法来播放这些文件类型。但是,我想在 powerpoint preso 中存储和检索文件。

我通过执行以下操作成功存储了这些不同的文件类型:

currentSlide.Shapes.AddOLEObject(0, 0, -1, -1, "", this.filePath);

我还可以通过右键单击对象 -> 来手动检索它们。选择编辑包 ->文件->保存内容。

我希望复制或使用此功能将 OLEObject 的内容保存回其原始状态和我指定的路径。我有办法找到该形状,并且我认为该对象包含以下内容:我只是不知道现在该怎么办。有想法吗?谢谢。

哦,我正在使用 Office 2010,如果这有什么不同的话。

I am adding a few different file types to slides in powerpoint. These types include mp4, zip, swf, and other formats. I am not looking for a way to play these file types back; however, I'd like to store and retrieve files from within a powerpoint preso.

I've successfully stored these various file types by doing the following:

currentSlide.Shapes.AddOLEObject(0, 0, -1, -1, "", this.filePath);

I can also retrieve them manually by Right Clicking the Object -> Selecting Edit Package -> File -> Save Content.

I am looking to replicate or use this functionality to save the contents of the OLEObject back to its original state and to a path I specify. I have a way to find that shape and I think this object contains the contents: slideShape.OLEFormat.ObjectI just don't know what to do now. Ideas? Thanks.

Oh I am using office 2010, if that makes any sort of difference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

丶情人眼里出诗心の 2025-01-04 12:00:23

所以,我知道现在已经晚了;不过,我知道其他人一定也有类似的问题。

我就这个问题联系了微软,他们花了大约一个月的时间,但他们终于给了我答案。我有一个 解决方案的 zip。它相当广泛,请查看下面的简单源代码。

首先是一些说明:

1) 创建 PowerPoint 演示文稿并在其中嵌入一些文件(视频、mp3、zip 等)
2) 将文件保存到以下位置 C:\Temp\Temp.pptx
3)关闭文件
4) 在“C:\Temp”下创建文件夹“GenerateFiles”
5) 打开应用程序并运行它。

所以唯一的缺点是 PPTX 文件必须关闭。话虽如此,人们也许能够将打开的 PPTX 文件复制到其他位置,然后从该位置提取文件,而不是实际正在处理的 PPTX。然后把临时的删除就可以了。我们会看到。这已经是该解决方案最接近的结果了。

无需进一步告别:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO.Packaging;
using System.Runtime.InteropServices;
using System.IO;

namespace ExtractOLEPowerPoint
{
class Program
{

    #region IEnumSTATSTG
    [ComImport]
    [Guid("0000000d-0000-0000-C000-000000000046")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IEnumSTATSTG
    {
        // The user needs to allocate an STATSTG array whose size is celt.
        [PreserveSig]
        uint Next(uint celt, [MarshalAs(UnmanagedType.LPArray), Out] System.Runtime.InteropServices.ComTypes.STATSTG[] rgelt, out uint pceltFetched);

        void Skip(uint celt);

        void Reset();

        [return: MarshalAs(UnmanagedType.Interface)]
        IEnumSTATSTG Clone();
    }
    #endregion

    //#region IStream

    //[ComImport, Guid("0000000c-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    //public interface IStream
    //{
    //    void Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, uint cb, out uint pcbRead);
    //    void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, uint cb, out uint pcbWritten);
    //    void Seek(long dlibMove, uint dwOrigin, out long plibNewPosition);
    //    void SetSize(long libNewSize);
    //    void CopyTo(IStream pstm, long cb, out long pcbRead, out long pcbWritten);
    //    void Commit(uint grfCommitFlags);
    //    void Revert();
    //    void LockRegion(long libOffset, long cb, uint dwLockType);
    //    void UnlockRegion(long libOffset, long cb, uint dwLockType);
    //    void Stat(out STATSTG pstatstg, uint grfStatFlag);
    //    void Clone(out IStream ppstm);
    //}

    //#endregion

    #region STATFLAG

    [Flags]
    public enum STATFLAG : uint
    {
        STATFLAG_DEFAULT = 0,
        STATFLAG_NONAME = 1,
        STATFLAG_NOOPEN = 2
    }

    #endregion

    #region IStorage
    [ComImport]
    [Guid("0000000b-0000-0000-C000-000000000046")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IStorage
    {
        void CreateStream(
            /* [string][in] */ string pwcsName,
            /* [in] */ uint grfMode,
            /* [in] */ uint reserved1,
            /* [in] */ uint reserved2,
            /* [out] */ out System.Runtime.InteropServices.ComTypes.IStream ppstm);
        void OpenStream(
            /* [string][in] */ string pwcsName,
            /* [unique][in] */ IntPtr reserved1,
            /* [in] */ uint grfMode,
            /* [in] */ uint reserved2,
            /* [out] */ out System.Runtime.InteropServices.ComTypes.IStream ppstm);

        void CreateStorage(
            /* [string][in] */ string pwcsName,
            /* [in] */ uint grfMode,
            /* [in] */ uint reserved1,
            /* [in] */ uint reserved2,
            /* [out] */ out IStorage ppstg);

        void OpenStorage(
            /* [string][unique][in] */ string pwcsName,
            /* [unique][in] */ IStorage pstgPriority,
            /* [in] */ uint grfMode,
            /* [unique][in] */ IntPtr snbExclude,
            /* [in] */ uint reserved,
            /* [out] */ out IStorage ppstg);

        void CopyTo(
            /* [in] */ uint ciidExclude,
            /* [size_is][unique][in] */ Guid rgiidExclude, // should this be an array?
            /* [unique][in] */ IntPtr snbExclude,
            /* [unique][in] */ IStorage pstgDest);

        void MoveElementTo(
            /* [string][in] */ string pwcsName,
            /* [unique][in] */ IStorage pstgDest,
            /* [string][in] */ string pwcsNewName,
            /* [in] */ uint grfFlags);

        void Commit(
            /* [in] */ uint grfCommitFlags);

        void Revert();

        void EnumElements(
            /* [in] */ uint reserved1,
            /* [size_is][unique][in] */ IntPtr reserved2,
            /* [in] */ uint reserved3,
            /* [out] */ out IEnumSTATSTG ppenum);

        void DestroyElement(
            /* [string][in] */ string pwcsName);

        void RenameElement(
            /* [string][in] */ string pwcsOldName,
            /* [string][in] */ string pwcsNewName);

        void SetElementTimes(
            /* [string][unique][in] */ string pwcsName,
            /* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME pctime,
            /* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME patime,
            /* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME pmtime);

        void SetClass(
            /* [in] */ Guid clsid);

        void SetStateBits(
            /* [in] */ uint grfStateBits,
            /* [in] */ uint grfMask);

        void Stat(
            /* [out] */ out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
            /* [in] */ uint grfStatFlag);
    }

    #endregion

    #region STGM
    [Flags]
    public enum STGM : int
    {
        DIRECT           = 0x00000000,
        TRANSACTED       = 0x00010000,
        SIMPLE           = 0x08000000,
        READ             = 0x00000000,
        WRITE            = 0x00000001,
        READWRITE        = 0x00000002,
        SHARE_DENY_NONE  = 0x00000040,
        SHARE_DENY_READ  = 0x00000030,
        SHARE_DENY_WRITE = 0x00000020,
        SHARE_EXCLUSIVE  = 0x00000010,
        PRIORITY         = 0x00040000,
        DELETEONRELEASE  = 0x04000000,
        NOSCRATCH        = 0x00100000,
        CREATE           = 0x00001000,
        CONVERT          = 0x00020000,
        FAILIFTHERE      = 0x00000000,
        NOSNAPSHOT       = 0x00200000,
        DIRECT_SWMR      = 0x00400000,
    }

    #endregion

    #region StgIsStorageFile

    [DllImport("Ole32.dll")]
    static extern int StgIsStorageFile([MarshalAs(UnmanagedType.LPWStr)]string filename);

    #endregion

    #region StgOpenStorage

    [DllImport("Ole32.dll")]
    static extern int StgOpenStorage([MarshalAs(UnmanagedType.LPWStr)]string pwcsName, IStorage pstgPriority, STGM grfmode, IntPtr snbExclude, uint researved, out IStorage ppstgOpen);

    #endregion

    static void Main(string[] args)
    {
        Package pkg = Package.Open("C:\\Temp\\Temp.pptx");
        foreach (PackagePart pkgprt in pkg.GetParts())
        {
            if(pkgprt.Uri.ToString().StartsWith("/ppt/embeddings/"))
            {
                System.IO.Stream strm = pkgprt.GetStream();
                byte[] buffer = new byte[strm.Length];
                strm.Read(buffer, 0, (int)strm.Length);
                strm.Close();

                // Create a temporary file
                string targetFile = "C:\\Temp\\GeneratedFiles\\" + pkgprt.Uri.ToString().Remove(0, "/ppt/embeddings/".Length);
                System.IO.File.WriteAllBytes(targetFile, buffer);

                // Extract the contents.
                IStorage Is;
                StgOpenStorage(targetFile, null, STGM.READWRITE | STGM.SHARE_EXCLUSIVE, IntPtr.Zero, 0, out Is);
                ProcessPackage(Is);

                // Need to release the IStorage object and call GC.Collect() to free the object
                Marshal.ReleaseComObject(Is);
                Is = null;
                GC.Collect();
                GC.WaitForPendingFinalizers();

                // Delete the temporary binary file extracted
                File.Delete(targetFile);
            }
        }
    }
    static void ProcessPackage(IStorage pStg)
    {
        System.Runtime.InteropServices.ComTypes.IStream pStream;
        IEnumSTATSTG pEnumStatStg;
        uint numReturned;
        pStg.EnumElements(0, IntPtr.Zero, 0, out pEnumStatStg);
        System.Runtime.InteropServices.ComTypes.STATSTG[] ss = new System.Runtime.InteropServices.ComTypes.STATSTG[1];
        // Loop through the STATSTG structures in the storage.
        do
        {
            // Retrieve the STATSTG structure
            pEnumStatStg.Next(1, ss, out numReturned);
            if (numReturned != 0)
            {
                //System.Runtime.InteropServices.ComTypes.STATSTG statstm;
                byte[] bytT = new byte[4];
                // Check if the pwcsName contains "Ole10Native" stream which contain the actual embedded object
                if (ss[0].pwcsName.Contains("Ole10Native") == true)
                {
                    // Get the stream objectOpen the stream
                    pStg.OpenStream(ss[0].pwcsName, IntPtr.Zero, (uint)STGM.READ | (uint)STGM.SHARE_EXCLUSIVE, 0, out pStream);
                    //pStream.Stat(out statstm, (int) STATFLAG.STATFLAG_DEFAULT);

                    IntPtr position = IntPtr.Zero;
                    // File name starts from 7th Byte.
                    // Position the cursor to the 7th Byte.
                    pStream.Seek(6, 0, position);

                    IntPtr ulRead = new IntPtr();
                    char[] filename = new char[260];
                    int i;

                    // Read the File name of the embedded object
                    for (i = 0; i < 260; i++)
                    {
                        pStream.Read(bytT, 1, ulRead);
                        pStream.Seek(0, 1, position);
                        filename[i] = (char)bytT[0];
                        if (bytT[0] == 0)
                        {
                            break;
                        }
                    }
                    string path = new string(filename, 0, i);

                    // Next part is the source path of the embedded object.
                    // Length is unknown. Hence, loop through each byte to read the 0 terminated string
                    // Read the source path.
                    for (i = 0; i < 260; i++)
                    {
                        pStream.Read(bytT, 1, ulRead);
                        pStream.Seek(0, 1, position);
                        filename[i] = (char)bytT[0];
                        if (bytT[0] == 0)
                        {
                            break;
                        }
                    }
                    // Source File path
                    string fullpath = new string(filename, 0, i);

                    // Unknown 4 bytes
                    pStream.Seek(4, 1, position);

                    // Next 4 byte gives the length of the temporary file path 
                    // (Office uses a temporary location to copy the files before inserting to the document)
                    // The length is in little endian format. Hence conversion is needed
                    pStream.Read(bytT, 4, ulRead);
                    ulong dwSize, dwTemp;
                    dwSize = 0;
                    dwTemp = (ulong)bytT[3];
                    dwSize += (ulong)(bytT[3] << 24);
                    dwSize += (ulong)(bytT[2] << 16);
                    dwSize += (ulong)(bytT[1] << 8);
                    dwSize += bytT[0];

                    // Skip the temporary file path
                    pStream.Seek((long)dwSize, 1, position);

                    // Next four bytes gives the size of the actual data in little endian format.
                    // Convert the format.
                    pStream.Read(bytT, 4, ulRead);
                    dwTemp = 0;
                    dwSize = 0;
                    dwTemp = (ulong)bytT[3];
                    dwSize += (ulong)(bytT[3] << 24);
                    dwSize += (ulong)(bytT[2] << 16);
                    dwSize += (ulong)(bytT[1] << 8);
                    dwSize += (ulong)bytT[0];

                    // Read the actual file content 
                    byte[] byData = new byte[dwSize];
                    pStream.Read(byData, (int)dwSize, ulRead);

                    // Create the file
                    System.IO.BinaryWriter bWriter = new System.IO.BinaryWriter(System.IO.File.Open("C:\\temp\\GeneratedFiles\\" + path, System.IO.FileMode.Create));
                    bWriter.Write(byData);
                    bWriter.Close();
                }
            }
        }
        while (numReturned > 0);
    }
}
}

So, I know this is late; however, I know others must have similar questions.

I contacted Microsoft about this issue and it took them around a month or so, but they finally got me an answer. I have a zip of the solution. It is fairly extensive, look below for just plain source code.

First some instructions:

1) Create a PowerPoint presentation and embed some files in it (Video, mp3, zip etc)
2) Save the file to the following location C:\Temp\Temp.pptx
3) Close the file
4) Create a folder “GeneratedFiles” under “C:\Temp”
5) Open the application and run it.

So the only downside is that the PPTX file must be closed. That being said, one might be able to copy the open PPTX file elsewhere and then extracted the files from that location rather than the PPTX that is actually being worked on. Then just delete the temporary one. We will see. This is as close as this solution gets though.

Without further adieu:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO.Packaging;
using System.Runtime.InteropServices;
using System.IO;

namespace ExtractOLEPowerPoint
{
class Program
{

    #region IEnumSTATSTG
    [ComImport]
    [Guid("0000000d-0000-0000-C000-000000000046")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IEnumSTATSTG
    {
        // The user needs to allocate an STATSTG array whose size is celt.
        [PreserveSig]
        uint Next(uint celt, [MarshalAs(UnmanagedType.LPArray), Out] System.Runtime.InteropServices.ComTypes.STATSTG[] rgelt, out uint pceltFetched);

        void Skip(uint celt);

        void Reset();

        [return: MarshalAs(UnmanagedType.Interface)]
        IEnumSTATSTG Clone();
    }
    #endregion

    //#region IStream

    //[ComImport, Guid("0000000c-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    //public interface IStream
    //{
    //    void Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, uint cb, out uint pcbRead);
    //    void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, uint cb, out uint pcbWritten);
    //    void Seek(long dlibMove, uint dwOrigin, out long plibNewPosition);
    //    void SetSize(long libNewSize);
    //    void CopyTo(IStream pstm, long cb, out long pcbRead, out long pcbWritten);
    //    void Commit(uint grfCommitFlags);
    //    void Revert();
    //    void LockRegion(long libOffset, long cb, uint dwLockType);
    //    void UnlockRegion(long libOffset, long cb, uint dwLockType);
    //    void Stat(out STATSTG pstatstg, uint grfStatFlag);
    //    void Clone(out IStream ppstm);
    //}

    //#endregion

    #region STATFLAG

    [Flags]
    public enum STATFLAG : uint
    {
        STATFLAG_DEFAULT = 0,
        STATFLAG_NONAME = 1,
        STATFLAG_NOOPEN = 2
    }

    #endregion

    #region IStorage
    [ComImport]
    [Guid("0000000b-0000-0000-C000-000000000046")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IStorage
    {
        void CreateStream(
            /* [string][in] */ string pwcsName,
            /* [in] */ uint grfMode,
            /* [in] */ uint reserved1,
            /* [in] */ uint reserved2,
            /* [out] */ out System.Runtime.InteropServices.ComTypes.IStream ppstm);
        void OpenStream(
            /* [string][in] */ string pwcsName,
            /* [unique][in] */ IntPtr reserved1,
            /* [in] */ uint grfMode,
            /* [in] */ uint reserved2,
            /* [out] */ out System.Runtime.InteropServices.ComTypes.IStream ppstm);

        void CreateStorage(
            /* [string][in] */ string pwcsName,
            /* [in] */ uint grfMode,
            /* [in] */ uint reserved1,
            /* [in] */ uint reserved2,
            /* [out] */ out IStorage ppstg);

        void OpenStorage(
            /* [string][unique][in] */ string pwcsName,
            /* [unique][in] */ IStorage pstgPriority,
            /* [in] */ uint grfMode,
            /* [unique][in] */ IntPtr snbExclude,
            /* [in] */ uint reserved,
            /* [out] */ out IStorage ppstg);

        void CopyTo(
            /* [in] */ uint ciidExclude,
            /* [size_is][unique][in] */ Guid rgiidExclude, // should this be an array?
            /* [unique][in] */ IntPtr snbExclude,
            /* [unique][in] */ IStorage pstgDest);

        void MoveElementTo(
            /* [string][in] */ string pwcsName,
            /* [unique][in] */ IStorage pstgDest,
            /* [string][in] */ string pwcsNewName,
            /* [in] */ uint grfFlags);

        void Commit(
            /* [in] */ uint grfCommitFlags);

        void Revert();

        void EnumElements(
            /* [in] */ uint reserved1,
            /* [size_is][unique][in] */ IntPtr reserved2,
            /* [in] */ uint reserved3,
            /* [out] */ out IEnumSTATSTG ppenum);

        void DestroyElement(
            /* [string][in] */ string pwcsName);

        void RenameElement(
            /* [string][in] */ string pwcsOldName,
            /* [string][in] */ string pwcsNewName);

        void SetElementTimes(
            /* [string][unique][in] */ string pwcsName,
            /* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME pctime,
            /* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME patime,
            /* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME pmtime);

        void SetClass(
            /* [in] */ Guid clsid);

        void SetStateBits(
            /* [in] */ uint grfStateBits,
            /* [in] */ uint grfMask);

        void Stat(
            /* [out] */ out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
            /* [in] */ uint grfStatFlag);
    }

    #endregion

    #region STGM
    [Flags]
    public enum STGM : int
    {
        DIRECT           = 0x00000000,
        TRANSACTED       = 0x00010000,
        SIMPLE           = 0x08000000,
        READ             = 0x00000000,
        WRITE            = 0x00000001,
        READWRITE        = 0x00000002,
        SHARE_DENY_NONE  = 0x00000040,
        SHARE_DENY_READ  = 0x00000030,
        SHARE_DENY_WRITE = 0x00000020,
        SHARE_EXCLUSIVE  = 0x00000010,
        PRIORITY         = 0x00040000,
        DELETEONRELEASE  = 0x04000000,
        NOSCRATCH        = 0x00100000,
        CREATE           = 0x00001000,
        CONVERT          = 0x00020000,
        FAILIFTHERE      = 0x00000000,
        NOSNAPSHOT       = 0x00200000,
        DIRECT_SWMR      = 0x00400000,
    }

    #endregion

    #region StgIsStorageFile

    [DllImport("Ole32.dll")]
    static extern int StgIsStorageFile([MarshalAs(UnmanagedType.LPWStr)]string filename);

    #endregion

    #region StgOpenStorage

    [DllImport("Ole32.dll")]
    static extern int StgOpenStorage([MarshalAs(UnmanagedType.LPWStr)]string pwcsName, IStorage pstgPriority, STGM grfmode, IntPtr snbExclude, uint researved, out IStorage ppstgOpen);

    #endregion

    static void Main(string[] args)
    {
        Package pkg = Package.Open("C:\\Temp\\Temp.pptx");
        foreach (PackagePart pkgprt in pkg.GetParts())
        {
            if(pkgprt.Uri.ToString().StartsWith("/ppt/embeddings/"))
            {
                System.IO.Stream strm = pkgprt.GetStream();
                byte[] buffer = new byte[strm.Length];
                strm.Read(buffer, 0, (int)strm.Length);
                strm.Close();

                // Create a temporary file
                string targetFile = "C:\\Temp\\GeneratedFiles\\" + pkgprt.Uri.ToString().Remove(0, "/ppt/embeddings/".Length);
                System.IO.File.WriteAllBytes(targetFile, buffer);

                // Extract the contents.
                IStorage Is;
                StgOpenStorage(targetFile, null, STGM.READWRITE | STGM.SHARE_EXCLUSIVE, IntPtr.Zero, 0, out Is);
                ProcessPackage(Is);

                // Need to release the IStorage object and call GC.Collect() to free the object
                Marshal.ReleaseComObject(Is);
                Is = null;
                GC.Collect();
                GC.WaitForPendingFinalizers();

                // Delete the temporary binary file extracted
                File.Delete(targetFile);
            }
        }
    }
    static void ProcessPackage(IStorage pStg)
    {
        System.Runtime.InteropServices.ComTypes.IStream pStream;
        IEnumSTATSTG pEnumStatStg;
        uint numReturned;
        pStg.EnumElements(0, IntPtr.Zero, 0, out pEnumStatStg);
        System.Runtime.InteropServices.ComTypes.STATSTG[] ss = new System.Runtime.InteropServices.ComTypes.STATSTG[1];
        // Loop through the STATSTG structures in the storage.
        do
        {
            // Retrieve the STATSTG structure
            pEnumStatStg.Next(1, ss, out numReturned);
            if (numReturned != 0)
            {
                //System.Runtime.InteropServices.ComTypes.STATSTG statstm;
                byte[] bytT = new byte[4];
                // Check if the pwcsName contains "Ole10Native" stream which contain the actual embedded object
                if (ss[0].pwcsName.Contains("Ole10Native") == true)
                {
                    // Get the stream objectOpen the stream
                    pStg.OpenStream(ss[0].pwcsName, IntPtr.Zero, (uint)STGM.READ | (uint)STGM.SHARE_EXCLUSIVE, 0, out pStream);
                    //pStream.Stat(out statstm, (int) STATFLAG.STATFLAG_DEFAULT);

                    IntPtr position = IntPtr.Zero;
                    // File name starts from 7th Byte.
                    // Position the cursor to the 7th Byte.
                    pStream.Seek(6, 0, position);

                    IntPtr ulRead = new IntPtr();
                    char[] filename = new char[260];
                    int i;

                    // Read the File name of the embedded object
                    for (i = 0; i < 260; i++)
                    {
                        pStream.Read(bytT, 1, ulRead);
                        pStream.Seek(0, 1, position);
                        filename[i] = (char)bytT[0];
                        if (bytT[0] == 0)
                        {
                            break;
                        }
                    }
                    string path = new string(filename, 0, i);

                    // Next part is the source path of the embedded object.
                    // Length is unknown. Hence, loop through each byte to read the 0 terminated string
                    // Read the source path.
                    for (i = 0; i < 260; i++)
                    {
                        pStream.Read(bytT, 1, ulRead);
                        pStream.Seek(0, 1, position);
                        filename[i] = (char)bytT[0];
                        if (bytT[0] == 0)
                        {
                            break;
                        }
                    }
                    // Source File path
                    string fullpath = new string(filename, 0, i);

                    // Unknown 4 bytes
                    pStream.Seek(4, 1, position);

                    // Next 4 byte gives the length of the temporary file path 
                    // (Office uses a temporary location to copy the files before inserting to the document)
                    // The length is in little endian format. Hence conversion is needed
                    pStream.Read(bytT, 4, ulRead);
                    ulong dwSize, dwTemp;
                    dwSize = 0;
                    dwTemp = (ulong)bytT[3];
                    dwSize += (ulong)(bytT[3] << 24);
                    dwSize += (ulong)(bytT[2] << 16);
                    dwSize += (ulong)(bytT[1] << 8);
                    dwSize += bytT[0];

                    // Skip the temporary file path
                    pStream.Seek((long)dwSize, 1, position);

                    // Next four bytes gives the size of the actual data in little endian format.
                    // Convert the format.
                    pStream.Read(bytT, 4, ulRead);
                    dwTemp = 0;
                    dwSize = 0;
                    dwTemp = (ulong)bytT[3];
                    dwSize += (ulong)(bytT[3] << 24);
                    dwSize += (ulong)(bytT[2] << 16);
                    dwSize += (ulong)(bytT[1] << 8);
                    dwSize += (ulong)bytT[0];

                    // Read the actual file content 
                    byte[] byData = new byte[dwSize];
                    pStream.Read(byData, (int)dwSize, ulRead);

                    // Create the file
                    System.IO.BinaryWriter bWriter = new System.IO.BinaryWriter(System.IO.File.Open("C:\\temp\\GeneratedFiles\\" + path, System.IO.FileMode.Create));
                    bWriter.Write(byData);
                    bWriter.Close();
                }
            }
        }
        while (numReturned > 0);
    }
}
}
掐死时间 2025-01-04 12:00:23

对象 slideShape.OLEFormat.Object 应支持 IPersistFileIPersistStream。如果是这样,您可以轻松地将其写入您选择的文件。为此,您需要使用 OLE 类型库来允许 VB 理解 IPersistFile 接口。

从此页面下载 OLELIB.TLB,安装它,然后添加对 PPTX 的引用:

IPersistFile::Save 的文档:

用法示例:

Dim oPersist as IPersistFile
Set oPersist = slideShape.OLEFormat.Object
' Zero means save a copy as
oPersist.Save(sFileName, 0)

The object slideShape.OLEFormat.Object should support IPersistFile or IPersistStream. If it does, you can readily cause it to write to a file of your choice. To do this you need a to use the OLE type library to allow VB to understand the IPersistFile interface.

Download OLELIB.TLB from this page, install it, and add a reference to your PPTX:

Documentation for IPersistFile::Save:

Example useage:

Dim oPersist as IPersistFile
Set oPersist = slideShape.OLEFormat.Object
' Zero means save a copy as
oPersist.Save(sFileName, 0)
肥爪爪 2025-01-04 12:00:23

您可以通过从 .NET 或 c# 调用 PowerShell 来完成此操作。

function Export-MediaFromPptx($pptxFile) 
{
    [void] [System.Reflection.Assembly]::LoadFrom("C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll")
    $pkg = [System.IO.Packaging.Package]::Open($pptxFile)

    $mediaDirectory = [System.IO.Path]::GetDirectoryName($pptxFile) + "\" + [System.IO.Path]::GetFileName($pptxFile) + "_media"
    md $mediaDirectory | out-null

    foreach ($mediaPart in ($pkg.GetParts() | where { $_.Uri.ToString().StartsWith("/ppt/media/") })) {
      $sourceStream = $mediaPart.GetStream()
      [byte[]]$buffer = new-object byte[] $sourceStream.Length
      [void]$sourceStream.Read($buffer, 0, $sourceStream.Length)
      $sourceStream.Close()
      $targetFileName = $mediaDirectory + "\" + $mediaPart.Uri.ToString().Remove(0, "/ppt/media/".Length)
      [System.IO.File]::WriteAllBytes($targetFileName, $buffer)
    }

    $pkg.Close()
}

上面的脚本取自此 文章

这个 文章展示了如何从.NET调用它

href="http://www.codeproject.com/Articles/18229/How-to-run-PowerShell-scripts-from-C" rel="nofollow">文章展示了如何从c# Hope 这有帮助。

You can do that by calling PowerShell either from .NET or c#.

function Export-MediaFromPptx($pptxFile) 
{
    [void] [System.Reflection.Assembly]::LoadFrom("C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll")
    $pkg = [System.IO.Packaging.Package]::Open($pptxFile)

    $mediaDirectory = [System.IO.Path]::GetDirectoryName($pptxFile) + "\" + [System.IO.Path]::GetFileName($pptxFile) + "_media"
    md $mediaDirectory | out-null

    foreach ($mediaPart in ($pkg.GetParts() | where { $_.Uri.ToString().StartsWith("/ppt/media/") })) {
      $sourceStream = $mediaPart.GetStream()
      [byte[]]$buffer = new-object byte[] $sourceStream.Length
      [void]$sourceStream.Read($buffer, 0, $sourceStream.Length)
      $sourceStream.Close()
      $targetFileName = $mediaDirectory + "\" + $mediaPart.Uri.ToString().Remove(0, "/ppt/media/".Length)
      [System.IO.File]::WriteAllBytes($targetFileName, $buffer)
    }

    $pkg.Close()
}

The above script was taken from this article.

This article shows how to call it from .NET

This article shows how to call it from c#

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文