Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

288
Visualizações
Excepción al usar Shell32 para obtener propiedades extendidas de archivo

Estoy tratando de usar Shell32 para obtener propiedades de archivo extendidas en C#.

Mi código para esto es el siguiente.

 var file = FileUpload1.PostedFile; List<string> arrHeaders = new List<string>(); Shell shell = new ShellClass(); //Exception is thrown at next line Folder rFolder = shell.NameSpace(Path.GetDirectoryName(file.FileName)); FolderItem rFiles = rFolder.ParseName(Path.GetFileName(file.FileName)); for (int i = 0; i < short.MaxValue; i++) { string value = rFolder.GetDetailsOf(rFiles, i).Trim(); arrHeaders.Add(value); }

Recibo una excepción de la siguiente manera.ingrese la descripción de la imagen aquí

Mensaje: no se puede convertir el objeto COM del tipo 'Shell32.ShellClass' al tipo de interfaz 'Shell32.IShellDispatch6'. Esta operación falló porque la llamada QueryInterface en el componente COM para la interfaz con IID '{286E6F1B-7113-4355-9562-96B7E9D64C54}' falló debido al siguiente error: No se admite dicha interfaz (Excepción de HRESULT: 0x80004002 (E_NOINTERFACE)) .

Seguimiento de pila: en System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget, Boolean& pfNeedsRelease) en Shell32.ShellClass.NameSpace(Object vDir) en PBSWebApplication.Test.Button1_OnClick(Object sender, EventArgs e) en c: \Projects\PBSWebApplication\PBSWebApplication\PBSWebApplication\Test.aspx.cs:line 33 en System.Web.UI.WebControls.Button.OnClick(EventArgs e) en System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) en System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) en System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) en System.Web.UI.Page.RaisePostBackEvent (NameValueCollection postData) en System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

¿Cómo arreglar esto?

Gracias.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Como identificó, esto se debe a que Shell32 requiere un subproceso STA. Si no puede simplemente configurar su aplicación para que se ejecute con un subproceso STA como en su solución, entonces, como alternativa, puede crear un subproceso STA separado, usarlo para ejecutar el código Shell32 y luego continuar con la ejecución. por ejemplo, esto es con lo que terminé al escribir una tarea de secuencia de comandos SSIS que, según tengo entendido, siempre se ejecuta en el subproceso MTA. En mi caso, estoy llamando a un método diferente de Shell32 (CopyHere), pero la misma lógica se aplicaría al método que desee llamar:

 /// <summary> /// Ugh! SSIS runs script tasks on MTA threads but Shell32 only wants to /// run on STA thread. So start a new STA thread to call UnZip, block /// till it's done, then return. /// We use Shell32 since .net 2 doesn't have ZipFile and we prefer not to /// ship other dlls as they normally need to be deployed to the GAC. So this /// is easiest, although not very pretty. /// </summary> /// <param name="zipFile">File to unzip</param> /// <param name="folderPath">Folder to put the unzipped files</param> public static void UnZipFromMTAThread(string zipFile, string folderPath) { object[] args = new object[] { zipFile, folderPath }; if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) { UnZip(args); } else { Thread staThread = new Thread(new ParameterizedThreadStart(UnZip)); staThread.SetApartmentState(ApartmentState.STA); staThread.Start(args); staThread.Join(); } } /// <summary> /// From http://www.fluxbytes.com/csharp/unzipping-files-using-shell32-in-c/ but with /// args packed in object array so can be called from new STA Thread in UnZipFromMTAThread(). /// </summary> /// <param name="param">object array containing: [string zipFile, string destinationFolderPath]</param> private static void UnZip(object param) { object[] args = (object[]) param; string zipFile = (string)args[0]; string folderPath = (string)args[1]; if (!File.Exists(zipFile)) throw new FileNotFoundException(); if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath); Shell32.Shell objShell = new Shell32.Shell(); Shell32.Folder destinationFolder = objShell.NameSpace(folderPath); Shell32.Folder sourceFile = objShell.NameSpace(zipFile); foreach (var file in sourceFile.Items()) { // Flags are: No progress displayed, Respond with 'Yes to All' for any dialog, no UI on error // I added 1024 although not sure it's relevant with Zip files. // See https://msdn.microsoft.com/en-us/library/windows/desktop/bb787866%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 destinationFolder.CopyHere(file, 4 | 16 | 1024); } }
over 4 years ago · Santiago Trujillo Relatório

0

Resultó ser una solución simple agregar el atributo STAThread a mi clase y el problema desapareció mágicamente.

Aquí está mi código completo después de la actualización.

Nota: Es una aplicación de consola simple.

 class Program { [STAThread] static void Main(string[] args) { Console.Title = "Extended file properties."; List<string> arrHeaders = new List<string>(); Shell32.Shell shell = new Shell32.Shell(); Shell32.Folder objFolder; objFolder = shell.NameSpace(@"C:\Users\Admin\Pictures\PBS Docs"); for (int i = 0; i < short.MaxValue; i++) { string header = objFolder.GetDetailsOf(null, i); if (String.IsNullOrEmpty(header)) break; arrHeaders.Add(header); } foreach (Shell32.FolderItem2 item in objFolder.Items()) { for (int i = 0; i < arrHeaders.Count; i++) { Console.WriteLine("{0}\t{1}: {2}", i, arrHeaders[i], objFolder.GetDetailsOf(item, i)); } } } }
over 4 years ago · Santiago Trujillo Relatório

0

Tuve un problema similar y la respuesta de jeronevw en este foro me lo solucionó: https://social.msdn.microsoft.com/Forums/vstudio/en-US/b25e2b8f-141a-4a1c-a73c-1cb92f953b2b/instantiate-shell32shell -objeto-en-windows-8?forum=clr

 public Shell32.Folder GetShell32NameSpaceFolder(Object folder) { Type shellAppType = Type.GetTypeFromProgID("Shell.Application"); Object shell = Activator.CreateInstance(shellAppType); return (Shell32.Folder)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { folder }); }

Todos los creditos de jeronevw

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda