void NativeInterfaces.IFileDialogEvents.OnOverwrite( NativeInterfaces.IFileDialog pfd, NativeInterfaces.IShellItem psi, out NativeEnums.FDE_OVERWRITE_RESPONSE pResponse) { pResponse = NativeEnums.FDE_OVERWRITE_RESPONSE.FDEOR_DEFAULT; }
private void OnBeforeShow(NativeInterfaces.IFileOpenDialog dialog) { SetDialogOptions(dialog); if (!string.IsNullOrEmpty(title)) { dialog.SetTitle(title); } if (!string.IsNullOrEmpty(defaultFolder)) { NativeInterfaces.IShellItem defaultFolderShellItem = null; try { if (CreateShellItemFromPath(defaultFolder, out defaultFolderShellItem)) { dialog.SetDefaultFolder(defaultFolderShellItem); } } finally { if (defaultFolderShellItem != null) { Marshal.ReleaseComObject(defaultFolderShellItem); defaultFolderShellItem = null; } } } if (!string.IsNullOrEmpty(selectedPath)) { dialog.SetFileName(selectedPath); } }
void NativeInterfaces.IFileDialogEvents.OnShareViolation( NativeInterfaces.IFileDialog pfd, NativeInterfaces.IShellItem psi, out NativeEnums.FDE_SHAREVIOLATION_RESPONSE pResponse) { pResponse = NativeEnums.FDE_SHAREVIOLATION_RESPONSE.FDESVR_DEFAULT; }
private bool HandleFileOk(NativeInterfaces.IFileDialog pfd) { bool result = false; NativeInterfaces.IShellItem resultShellItem = null; try { pfd.GetResult(out resultShellItem); string path; resultShellItem.GetDisplayName(NativeEnums.SIGDN.SIGDN_FILESYSPATH, out path); selectedPath = path; result = true; } finally { if (resultShellItem != null) { Marshal.ReleaseComObject(resultShellItem); resultShellItem = null; } } return(result); }
protected virtual void OnBeforeShow() { NativeInterfaces.IShellItem shellItem = null; try { shellItem = GetShellItem(this.initialDirectory); this.fileDialog.SetDefaultFolder(shellItem); } catch (Exception) { // Do nothing. } finally { if (shellItem != null) { try { Marshal.ReleaseComObject(shellItem); } catch (ArgumentException) { } shellItem = null; } } }
private void CreateLocalCopyFromHttpSource( NativeInterfaces.IShellItem item, IFileTransferProgressEvents progressEvents, out string pathNameResult) { string url = null; item.GetDisplayName(NativeConstants.SIGDN.SIGDN_URL, out url); Uri uri = new Uri(url); string pathName = FileSystem.GetTempPathName(url); WebRequest webRequest = WebRequest.Create(uri); webRequest.Timeout = 5000; using (WebResponse webResponse = webRequest.GetResponse()) { VerifyNotCanceled(); using (Stream uriStream = webResponse.GetResponseStream()) { VerifyNotCanceled(); using (FileStream outStream = new FileStream(pathName, FileMode.Create, FileAccess.Write, FileShare.Read)) { VerifyNotCanceled(); const int bufSize = 512; long length = webResponse.ContentLength; long bytesLeft = length; byte[] buffer = new byte[bufSize]; progressEvents.SetItemWorkTotal(length); while (bytesLeft > 0) { int amtRead = uriStream.Read(buffer, 0, buffer.Length); VerifyNotCanceled(); outStream.Write(buffer, 0, amtRead); VerifyNotCanceled(); bytesLeft -= amtRead; progressEvents.SetItemWorkProgress(length - bytesLeft); VerifyNotCanceled(); } } } } pathNameResult = pathName; }
private NativeInterfaces.IShellItem GetShellItem(string path) { Guid iid_IShellItem = new Guid(NativeConstants.IID_IShellItem); IntPtr ppv = IntPtr.Zero; NativeMethods.SHCreateItemFromParsingName(path, IntPtr.Zero, ref iid_IShellItem, out ppv); object iUnknown = Marshal.GetObjectForIUnknown(ppv); NativeInterfaces.IShellItem shellItem = (NativeInterfaces.IShellItem)iUnknown; return(shellItem); }
private static bool CreateShellItemFromPath(string path, out NativeInterfaces.IShellItem item) { Guid riid = new Guid(NativeConstants.IID_IShellItem); if (UnsafeNativeMethods.SHCreateItemFromParsingName(path, IntPtr.Zero, ref riid, out item) != NativeConstants.S_OK) { item = null; return(false); } return(true); }
int NativeInterfaces.IFileDialogEvents.OnFolderChanging(NativeInterfaces.IFileDialog pfd, NativeInterfaces.IShellItem psiFolder) { return(NativeConstants.S_OK); }
internal static extern int SHCreateItemFromParsingName( [MarshalAs(UnmanagedType.LPWStr)] string pszPath, IntPtr pbc, [In] ref Guid riid, [MarshalAs(UnmanagedType.Interface, IidParameterIndex = 2)] out NativeInterfaces.IShellItem ppv);
int NativeInterfaces.IFileDialogEvents.OnFileOk(NativeInterfaces.IFileDialog pfd) { int hr = NativeConstants.S_OK; NativeInterfaces.IShellItem shellItem = null; if (NativeMethods.SUCCEEDED(hr)) { hr = FileSaveDialog.GetResult(out shellItem); } if (!NativeMethods.SUCCEEDED(hr)) { throw Marshal.GetExceptionForHR(hr); } string pathName = null; try { shellItem.GetDisplayName(NativeConstants.SIGDN.SIGDN_FILESYSPATH, out pathName); } finally { if (shellItem != null) { try { Marshal.ReleaseComObject(shellItem); } catch (Exception) { } shellItem = null; } } string pathNameResolved = ResolveName(pathName); NativeInterfaces.IOleWindow oleWindow = (NativeInterfaces.IOleWindow)pfd; try { IntPtr hWnd = IntPtr.Zero; oleWindow.GetWindow(out hWnd); Win32Window win32Window = new Win32Window(hWnd, oleWindow); // File name/path validation if (hr >= 0) { try { // Verify that these can be parsed correctly string fileName = Path.GetFileName(pathNameResolved); string dirName = Path.GetDirectoryName(pathNameResolved); } catch (Exception ex) { if (!FileDialogUICallbacks.ShowError(win32Window, pathNameResolved, ex)) { throw; } hr = NativeConstants.S_FALSE; } } if (hr >= 0) { // Overwrite existing file if (!OverwritePrompt) { hr = NativeConstants.S_OK; } else if (File.Exists(pathNameResolved)) { FileOverwriteAction action = FileDialogUICallbacks.ShowOverwritePrompt(win32Window, pathNameResolved); switch (action) { case FileOverwriteAction.Cancel: hr = NativeConstants.S_FALSE; break; case FileOverwriteAction.Overwrite: hr = NativeConstants.S_OK; break; default: throw new InvalidEnumArgumentException(); } } } } catch (Exception) { } finally { try { Marshal.ReleaseComObject(oleWindow); } catch (Exception) { } oleWindow = null; } return(hr); }
private unsafe void CreateLocalCopyFromIStreamSource( NativeInterfaces.IShellItem item, IFileTransferProgressEvents progressEvents, out string pathNameResult) { string fileName = null; item.GetDisplayName(NativeConstants.SIGDN.SIGDN_NORMALDISPLAY, out fileName); string pathName = FileSystem.GetTempPathName(fileName); Guid bhidStream = NativeConstants.BHID_Stream; Guid iid_IStream = new Guid(NativeConstants.IID_IStream); NativeInterfaces.IStream iStream = null; item.BindToHandler(IntPtr.Zero, ref bhidStream, ref iid_IStream, out iStream); try { VerifyNotCanceled(); NativeStructs.STATSTG statstg = new NativeStructs.STATSTG(); iStream.Stat(out statstg, NativeConstants.STATFLAG.STATFLAG_NONAME); progressEvents.SetItemWorkTotal((long)statstg.cbSize); const int bufSize = 4096; byte[] buffer = new byte[bufSize]; fixed(void *pbBuffer = buffer) { IntPtr pbBuffer2 = new IntPtr(pbBuffer); ulong qwBytesLeft = statstg.cbSize; using (FileStream localFile = new FileStream(pathName, FileMode.Create, FileAccess.Write, FileShare.Read)) { VerifyNotCanceled(); // NOTE: We do not call VerifyNotCanceled() during any individual item. This is because, while testing // this, it was determined that oftentimes the transfer gets very confused if we just stop // calling Read() and jump straight to Marshal.ReleaseComObject(). By "confused" I mean that // the "Canceling..." text would remain on the progress dialog for up to a minute, and then // the blinking light on the camera would continue indefinitely and you wouldn't be able to // use the camera again until you unplugged it and plugged it back in. while (qwBytesLeft > 0) { uint wantToRead = (uint)Math.Min(qwBytesLeft, bufSize); uint amtRead = 0; iStream.Read(pbBuffer2, wantToRead, out amtRead); if (amtRead > qwBytesLeft) { throw new InvalidOperationException("IStream::Read() reported that more bytes were read than were in the file"); } qwBytesLeft -= amtRead; localFile.Write(buffer, 0, (int)amtRead); progressEvents.SetItemWorkProgress((long)(statstg.cbSize - qwBytesLeft)); } } VerifyNotCanceled(); } } finally { if (iStream != null) { try { Marshal.ReleaseComObject(iStream); } catch (Exception) { } iStream = null; } } pathNameResult = pathName; }
// Returns true if the item copied successfully, false if it didn't (error or skipped) private CopyResult CreateLocalCopy( NativeInterfaces.IShellItem item, IFileTransferProgressEvents progressEvents, out string pathNameResult) { CopyResult returnResult; WorkItemResult itemResult; string displayName = null; item.GetDisplayName(NativeConstants.SIGDN.SIGDN_NORMALDISPLAY, out displayName); progressEvents.SetItemInfo(displayName); progressEvents.BeginItem(); while (true) { // Determine whether to copy from HTTP or from IStream. The heuristic we use here is simple: // if the attributes has SFGAO_CANCOPY, we IStream it. Else, we HTTP it. NativeConstants.SFGAO attribs; item.GetAttributes((NativeConstants.SFGAO) 0xfffffff, out attribs); try { if ((attribs & NativeConstants.SFGAO.SFGAO_CANCOPY) == NativeConstants.SFGAO.SFGAO_CANCOPY) { CreateLocalCopyFromIStreamSource(item, progressEvents, out pathNameResult); } else { CreateLocalCopyFromHttpSource(item, progressEvents, out pathNameResult); } returnResult = CopyResult.Success; itemResult = WorkItemResult.Finished; break; } catch (OperationCanceledException) { returnResult = CopyResult.CancelOperation; itemResult = WorkItemResult.Skipped; pathNameResult = null; break; } catch (Exception ex) { WorkItemFailureAction choice = progressEvents.ReportItemFailure(ex); if (choice == WorkItemFailureAction.SkipItem) { pathNameResult = null; returnResult = CopyResult.Skipped; itemResult = WorkItemResult.Skipped; break; } else if (choice == WorkItemFailureAction.RetryItem) { continue; } else if (choice == WorkItemFailureAction.CancelOperation) { pathNameResult = null; returnResult = CopyResult.CancelOperation; itemResult = WorkItemResult.Skipped; break; } } } progressEvents.EndItem(itemResult); return(returnResult); }
int NativeInterfaces.IFileDialogEvents.OnFileOk(NativeInterfaces.IFileDialog pfd) { int hr = NativeConstants.S_OK; NativeInterfaces.IShellItemArray results = null; FileOpenDialog.GetResults(out results); uint count = 0; results.GetCount(out count); List <NativeInterfaces.IShellItem> items = new List <NativeInterfaces.IShellItem>(); List <NativeInterfaces.IShellItem> needLocalCopy = new List <NativeInterfaces.IShellItem>(); List <NativeInterfaces.IShellItem> cannotCopy = new List <NativeInterfaces.IShellItem>(); List <string> localPathNames = new List <string>(); for (uint i = 0; i < count; ++i) { NativeInterfaces.IShellItem item = null; results.GetItemAt(i, out item); items.Add(item); } foreach (NativeInterfaces.IShellItem item in items) { // If it's a file system object, nothing special needs to be done. NativeConstants.SFGAO sfgaoAttribs; item.GetAttributes((NativeConstants.SFGAO) 0xffffffff, out sfgaoAttribs); if ((sfgaoAttribs & NativeConstants.SFGAO.SFGAO_FILESYSTEM) == NativeConstants.SFGAO.SFGAO_FILESYSTEM) { string pathName = null; item.GetDisplayName(NativeConstants.SIGDN.SIGDN_FILESYSPATH, out pathName); localPathNames.Add(pathName); } else if ((sfgaoAttribs & NativeConstants.SFGAO.SFGAO_STREAM) == NativeConstants.SFGAO.SFGAO_STREAM) { needLocalCopy.Add(item); } else { cannotCopy.Add(item); } } Marshal.ReleaseComObject(results); results = null; if (needLocalCopy.Count > 0) { IntPtr hwnd = IntPtr.Zero; NativeInterfaces.IOleWindow oleWindow = (NativeInterfaces.IOleWindow)pfd; oleWindow.GetWindow(out hwnd); Win32Window win32Window = new Win32Window(hwnd, oleWindow); IFileTransferProgressEvents progressEvents = this.FileDialogUICallbacks.CreateFileTransferProgressEvents(); ThreadStart copyThreadProc = delegate() { try { progressEvents.SetItemCount(needLocalCopy.Count); for (int i = 0; i < needLocalCopy.Count; ++i) { NativeInterfaces.IShellItem item = needLocalCopy[i]; string pathName = null; progressEvents.SetItemOrdinal(i); CopyResult result = CreateLocalCopy(item, progressEvents, out pathName); if (result == CopyResult.Success) { localPathNames.Add(pathName); } else if (result == CopyResult.Skipped) { // do nothing } else if (result == CopyResult.CancelOperation) { hr = NativeConstants.S_FALSE; break; } else { throw new InvalidEnumArgumentException(); } } } finally { OperationResult result; if (hr == NativeConstants.S_OK) { result = OperationResult.Finished; } else { result = OperationResult.Canceled; } progressEvents.EndOperation(result); } }; Thread copyThread = new Thread(copyThreadProc); copyThread.SetApartmentState(ApartmentState.STA); EventHandler onUIShown = delegate(object sender, EventArgs e) { copyThread.Start(); }; this.cancelSink = new CancelableTearOff(); progressEvents.BeginOperation(win32Window, onUIShown, cancelSink); this.cancelSink = null; copyThread.Join(); Marshal.ReleaseComObject(oleWindow); oleWindow = null; } this.FileNames = localPathNames.ToArray(); // If they selected a bunch of files, and then they all errored or something, then don't proceed. if (this.FileNames.Length == 0) { hr = NativeConstants.S_FALSE; } foreach (NativeInterfaces.IShellItem item in items) { Marshal.ReleaseComObject(item); } items.Clear(); items = null; GC.KeepAlive(pfd); return(hr); }