C# IShellLinkW COM接口是线程安全的吗?

C# IShellLinkW COM接口是线程安全的吗?,c#,com,pinvoke,windows-shell,C#,Com,Pinvoke,Windows Shell,我从C#使用PInvoke多次调用IShellLinkW.GetPath(…)。我希望在多个异步任务上同时执行这些任务 这些调用是线程安全的吗?我能做这个吗 更新: 我正在做的是将解决快捷方式作为更大任务的一部分。代码如下: const uint STGM_READ = 0; public static string ResolveShortcut(string filename) { ShellLink link = new ShellLink();

我从C#使用PInvoke多次调用IShellLinkW.GetPath(…)。我希望在多个异步任务上同时执行这些任务

这些调用是线程安全的吗?我能做这个吗

更新:

我正在做的是将解决快捷方式作为更大任务的一部分。代码如下:

    const uint STGM_READ = 0;

    public static string ResolveShortcut(string filename)
    {
        ShellLink link = new ShellLink();
        ((IPersistFile)link).Load(filename, STGM_READ);
        StringBuilder buff = new StringBuilder(260);
        WIN32_FIND_DATAW data = new WIN32_FIND_DATAW();
        IShellLinkW linkW = link as IShellLinkW;
        linkW.GetPath(buff, buff.Capacity, out data, SLGP_FLAGS.SLGP_UNCPRIORITY);
        return buff.ToString();
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    struct WIN32_FIND_DATAW
    {
        public uint dwFileAttributes;
        public long ftCreationTime;
        public long ftLastAccessTime;
        public long ftLastWriteTime;
        public uint nFileSizeHigh;
        public uint nFileSizeLow;
        public uint dwReserved0;
        public uint dwReserved1;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string cFileName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
        public string cAlternateFileName;
    }

    [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
                  Guid("000214F9-0000-0000-C000-000000000046")]
    {
        /// <summary>Retrieves the path and file name of a Shell link object</summary>
        void GetPath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out WIN32_FIND_DATAW pfd, SLGP_FLAGS fFlags);
        /// <summary>Retrieves the list of item identifiers for a Shell link object</summary>
        void GetIDList(out IntPtr ppidl);
        /// <summary>Sets the pointer to an item identifier list (PIDL) for a Shell link object.</summary>
        void SetIDList(IntPtr pidl);
        /// <summary>Retrieves the description string for a Shell link object</summary>
        void GetDescription([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
        /// <summary>Sets the description for a Shell link object. The description can be any application-defined string</summary>
        void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
        /// <summary>Retrieves the name of the working directory for a Shell link object</summary>
        void GetWorkingDirectory([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
        /// <summary>Sets the name of the working directory for a Shell link object</summary>
        void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
        /// <summary>Retrieves the command-line arguments associated with a Shell link object</summary>
        void GetArguments([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
        /// <summary>Sets the command-line arguments for a Shell link object</summary>
        void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
        /// <summary>Retrieves the hot key for a Shell link object</summary>
        void GetHotkey(out short pwHotkey);
        /// <summary>Sets a hot key for a Shell link object</summary>
        void SetHotkey(short wHotkey);
        /// <summary>Retrieves the show command for a Shell link object</summary>
        void GetShowCmd(out int piShowCmd);
        /// <summary>Sets the show command for a Shell link object. The show command sets the initial show state of the window.</summary>
        void SetShowCmd(int iShowCmd);
        /// <summary>Retrieves the location (path and index) of the icon for a Shell link object</summary>
        void GetIconLocation([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
            int cchIconPath, out int piIcon);
        /// <summary>Sets the location (path and index) of the icon for a Shell link object</summary>
        void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
        /// <summary>Sets the relative path to the Shell link object</summary>
        void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
        /// <summary>Attempts to find the target of a Shell link, even if it has been moved or renamed</summary>
        void Resolve(IntPtr hwnd, SLR_FLAGS fFlags);
        /// <summary>Sets the path and file name of a Shell link object</summary>
        void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
    }

    [ComImport, Guid("0000010b-0000-0000-C000-000000000046"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IPersistFile : IPersist
    {
        new void GetClassID(out Guid pClassID);
        [PreserveSig]
        int IsDirty();

        [PreserveSig]
        void Load([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName, uint dwMode);

        [PreserveSig]
        void Save([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
            [In, MarshalAs(UnmanagedType.Bool)] bool fRemember);

        [PreserveSig]
        void SaveCompleted([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName);

        [PreserveSig]
        void GetCurFile([In, MarshalAs(UnmanagedType.LPWStr)] string ppszFileName);
    }
consuint STGM_READ=0;
公共静态字符串解析快捷方式(字符串文件名)
{
ShellLink=新的ShellLink();
加载(文件名,STGM_READ);
StringBuilder buff=新的StringBuilder(260);
WIN32_FIND_DATAW data=新的WIN32_FIND_DATAW();
IShellLinkW linkW=链接为IShellLinkW;
linkW.GetPath(buff,buff.Capacity,out数据,SLGP_标志,SLGP_优先级);
返回buff.ToString();
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
结构WIN32\u查找\u数据w
{
公共uint-dwFileAttributes;
公共时间长;
公共时间长;
公共长ftLastWriteTime;
公共单位净收益率高;
公共部门和公共部门;
公共单位数据保留0;
保留的公共单位1;
[Marshallas(UnmanagedType.ByValTStr,SizeConst=260)]
公共字符串cFileName;
[Marshallas(UnmanagedType.ByValTStr,SizeConst=14)]
公共字符串cAlternateFileName;
}
[ComImport(),InterfaceType(ComInterfaceType.InterfaceSiunknown),
Guid(“000214F9-0000-0000-C000-0000000000 46”)]
{
///检索Shell链接对象的路径和文件名
void GetPath([Out(),marshallas(UnmanagedType.LPWStr)]StringBuilder pszFile,int-cchMaxPath,Out-WIN32\u-FIND\u-DATAW-pfd,SLGP\u-FLAGS-fFlags);
///检索Shell链接对象的项标识符列表
void GetIDList(out IntPtr ppidl);
///设置指向Shell链接对象的项标识符列表(PIDL)的指针。
void SetIDList(IntPtr-pidl);
///检索Shell链接对象的描述字符串
void GetDescription([Out(),marshallas(UnmanagedType.LPWStr)]StringBuilder pszName,int-cchMaxName);
///设置外壳链接对象的说明。说明可以是任何应用程序定义的字符串
void SetDescription([marshallas(UnmanagedType.LPWStr)]字符串pszName);
///检索Shell链接对象的工作目录的名称
void GetWorkingDirectory([Out(),marshallas(UnmanagedType.LPWStr)]StringBuilder pszDir,int-cchMaxPath);
///设置Shell链接对象的工作目录的名称
void SetWorkingDirectory([marshallas(UnmanagedType.LPWStr)]字符串pszDir);
///检索与Shell链接对象关联的命令行参数
void GetArguments([Out(),marshallas(UnmanagedType.LPWStr)]StringBuilder pszArgs,int-cchMaxPath);
///设置Shell链接对象的命令行参数
void SetArguments([Marshallas(UnmanagedType.LPWStr)]字符串pszArgs);
///检索Shell链接对象的热键
void GetHotkey(out short pwHotkey);
///设置外壳链接对象的热键
无效设置热键(短wHotkey);
///检索Shell链接对象的show命令
void GetShowCmd(out int piShowCmd);
///设置Shell链接对象的show命令。show命令设置窗口的初始显示状态。
void SetShowCmd(int-iShowCmd);
///检索Shell链接对象的图标位置(路径和索引)
void GetIconLocation([Out(),marshallas(UnmanagedType.LPWStr)]StringBuilder pszIconPath,
int CCICONPATH,out int piIcon);
///为Shell链接对象设置图标的位置(路径和索引)
void SetIconLocation([Marshallas(UnmanagedType.LPWStr)]字符串pszIconPath,int-iIcon);
///设置外壳链接对象的相对路径
void SetRelativePath([marshallas(UnmanagedType.LPWStr)]字符串pszPathRel,int dwReserved);
///尝试查找Shell链接的目标,即使该链接已被移动或重命名
无效解决(IntPtr hwnd、SLR_标志和标签);
///设置外壳链接对象的路径和文件名
void SetPath([marshallas(UnmanagedType.LPWStr)]字符串pszFile);
}
[ComImport,Guid(“0000010b-0000-0000-C000-0000000000 46”),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
公共接口IPersistFile:IPersist
{
新的void GetClassID(out Guid pClassID);
[信号]
int IsDirty();
[信号]
无效加载([In,marshallas(UnmanagedType.LPWStr)]字符串pszFileName,uint dwMode);
[信号]
void Save([In,marshallas(UnmanagedType.LPWStr)]字符串pszFileName,
[In,marshallas(UnmanagedType.Bool)]Bool-fRemember;
[信号]
void SaveCompleted([In,marshallas(UnmanagedType.LPWStr)]字符串pszFileName);
[信号]
void GetCurFile([In,marshallas(UnmanagedType.LPWStr)]字符串ppszFileName);
}

windows shell不支持MTA,因此您应该只在创建shell对象的线程中调用shell接口(无线程安全性),并且该线程必须初始化为STA。
如果使用.Net并行模式库,请参见

windows shell不支持MTA,因此应仅在创建shell对象的线程中调用shell接口(无线程安全性),并且该线程必须初始化为STA。
如果使用.Net并行模式库,请参见

windows shell不支持MTA,因此应仅在创建shell对象的线程中调用shell接口(无线程安全性),并且该线程必须初始化为STA。
如果使用.Net并行模式库,请参见

windows shell不支持MTA,因此应仅调用shell
  ThreadingModel     REG_SZ    Both