I'm writing a PowerShell module, in PowerShell, which has to redirect an assembly binding.
I had no problems using a bindingRedirect in powershell_ise.exe.config but I don't think this is acceptable for a module I want to distribute, so I looked for other ways and came across AppDomain.CurrentDomain.AssemblyResolve.
I'm currently using this at the top of my .psm1 file:
function Resolve-AssemblyRedirect {
PARAM ([object]$sender, [System.ResolveEventArgs]$e)
PROCESS {
$requestedName = New-Object System.Reflection.AssemblyName $e.Name
if ($requestedName.Name -eq "System.Net.Http.Primitives") {
return [System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\Assemblies\System.Net.Http.Primitives.dll")
}
return $null
}
}
if (-not $Global:MODULE_LOADED) {
[AppDomain]::CurrentDomain.add_AssemblyResolve( { Resolve-AssemblyRedirect $Args[0] $Args[1] } )
Set-Variable -Option Constant -Name MODULE_LOADED -Value $true -Scope Global
}
I can trigger the problem fairly reliably by using tab-completion/Intellisense in the ISE. I have also seen it in the shell. When I say fairly reliably, it's not always the same cmdlet that triggers it. For example, in preparing this, I've triggered it with Get-ADUser [tab] and most recently, I typed get-por [tab], Intellisense displayed Get-GPOReport and then it hung.
If I comment-out the line beginning [AppDomain]::, and hammer tab-completion, I don't see a problem.
Before I go on, I want to point out that I've never had to debug anything in PowerShell, before, so there's been quite a bit of fumbling in the dark. In order to debug, I added a REG_SZ to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug with the name Auto and the value 1, which is giving me the option to start VS 2012. That is then showing me:
System.StackOverflowException was unhandled
and when I look at the Call Stack I see:
mscorlib.dll!System.Resources.ResourceManager.GetString(string name, System.Globalization.CultureInfo culture) + 0x23c bytes
System.Management.Automation.dll!System.Management.Automation.ErrorCategoryInfo.Ellipsize(System.Globalization.CultureInfo uiCultureInfo, string original) + 0x88 bytes
System.Management.Automation.dll!System.Management.Automation.ScriptBlock.InvokeAsDelegateHelper(object dollarUnder, object dollarThis, object[] args) + 0x137 bytes
[Lightweight Function]
mscorlib.dll!System.AppDomain.OnAssemblyResolveEvent(System.Reflection.RuntimeAssembly assembly, string assemblyFullName) + 0xbc bytes
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Reflection.RuntimeAssembly.InternalGetSatelliteAssembly(string name, System.Globalization.CultureInfo culture, System.Version version, bool throwOnFileNotFound, ref System.Threading.StackCrawlMark stackMark) + 0x3ab bytes
mscorlib.dll!System.Resources.ManifestBasedResourceGroveler.GetSatelliteAssembly(System.Globalization.CultureInfo lookForCulture, ref System.Threading.StackCrawlMark stackMark) + 0xdd bytes
mscorlib.dll!System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(System.Globalization.CultureInfo culture, System.Collections.Generic.Dictionary<string,System.Resources.ResourceSet> localResourceSets, bool tryParents, bool createIfNotExists, ref System.Threading.StackCrawlMark stackMark) + 0xe2 bytes
mscorlib.dll!System.Resources.ResourceManager.InternalGetResourceSet(System.Globalization.CultureInfo requestedCulture, bool createIfNotExists, bool tryParents, ref System.Threading.StackCrawlMark stackMark) + 0x329 bytes
mscorlib.dll!System.Resources.ResourceManager.InternalGetResourceSet(System.Globalization.CultureInfo culture, bool createIfNotExists, bool tryParents) + 0x23 bytes
mscorlib.dll!System.Resources.ResourceManager.GetString(string name, System.Globalization.CultureInfo culture) + 0x23c bytes
Microsoft.PowerShell.Editor.dll!Microsoft.VisualStudio.Language.Intellisense.Implementation.CompletionSession.Commit() + 0x285 bytes
Microsoft.PowerShell.GPowerShell.dll!Microsoft.PowerShell.Host.ISE.PowerShellTab.TabComplete(Microsoft.PowerShell.Host.ISE.ISEEditor editor, bool forward) + 0x51c bytes
Microsoft.PowerShell.GPowerShell.dll!Microsoft.PowerShell.Host.ISE.PowerShellTab.ProcessTab(object sender, System.Windows.Input.KeyEventArgs e, Microsoft.PowerShell.Host.ISE.PowerShellTab selectedPowerShellTab) + 0x167 bytes
Microsoft.PowerShell.GPowerShell.dll!Microsoft.Windows.PowerShell.Gui.Internal.BeforeDefaultKeyProcessor.KeyDown(System.Windows.Input.KeyEventArgs args) + 0x4a bytes
Microsoft.PowerShell.Editor.dll!Microsoft.VisualStudio.Text.Utilities.GuardedOperations.CallExtensionPoint(object errorSource, System.Action call) + 0x26 bytes
Microsoft.PowerShell.Editor.dll!Microsoft.VisualStudio.Text.Editor.Implementation.KeyProcessorDispatcher.Dispatch<System.Windows.Input.KeyEventArgs>(System.Action<Microsoft.VisualStudio.Text.Editor.KeyProcessor,System.Windows.Input.KeyEventArgs> action, System.Windows.Input.KeyEventArgs args) + 0x185 bytes
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) + 0x56 bytes
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) + 0x270 bytes
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) + 0x14e bytes
PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) + 0x64 bytes
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() + 0x431 bytes
PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input) + 0xab bytes
PresentationCore.dll!System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawKeyboardActions actions, int scanCode, bool isExtendedKey, bool isSystemKey, int virtualKey) + 0x124 bytes
PresentationCore.dll!System.Windows.Interop.HwndKeyboardInputProvider.ProcessKeyAction(ref System.Windows.Interop.MSG msg, ref bool handled) + 0x20e bytes
PresentationCore.dll!System.Windows.Interop.HwndSource.CriticalTranslateAccelerator(ref System.Windows.Interop.MSG msg, System.Windows.Input.ModifierKeys modifiers) + 0x213 bytes
PresentationCore.dll!System.Windows.Interop.HwndSource.OnPreprocessMessage(object param) + 0x35e bytes
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) + 0x5e bytes
WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) + 0x47 bytes
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) + 0x2bc bytes
WindowsBase.dll!System.Windows.Threading.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority priority, System.Delegate method, object arg) + 0x42 bytes
PresentationCore.dll!System.Windows.Interop.HwndSource.OnPreprocessMessageThunk(ref System.Windows.Interop.MSG msg, ref bool handled) + 0x107 bytes
WindowsBase.dll!System.Windows.Interop.ComponentDispatcherThread.RaiseThreadMessage(ref System.Windows.Interop.MSG msg) + 0x4f bytes
WindowsBase.dll!System.Windows.Threading.Dispatcher.TranslateAndDispatchMessage(ref System.Windows.Interop.MSG msg) + 0x2c bytes
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) + 0x112 bytes
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) + 0x17a bytes
Microsoft.PowerShell.GPowerShell.dll!Microsoft.Windows.PowerShell.Gui.Internal.Program.ShowMainWindow(System.Collections.Generic.List<string> filesToOpen, bool mta, bool noProfile, System.Threading.SendOrPostCallback loadedCallback) + 0x1a5 bytes
[Native to Managed Transition]
PowerShell_ISE.exe!Microsoft.Windows.PowerShell.GuiExe.Internal.GPowerShell.Main(string[] args) + 0x4d0 bytes
I've only included one repeat of the section between the lines:
mscorlib.dll!System.Resources.ResourceManager.GetString(string name, System.Globalization.CultureInfo culture) + 0x23c bytes
but that repeats a lot.
I've put this through the washer a few times and I don't always see the same results in the Call Stack. For example, sometimes the repeating part looks like this:
mscorlib.dll!System.Resources.ResourceManager.GetString(string name, System.Globalization.CultureInfo culture) + 0x23c bytes
System.Management.Automation.dll!System.Management.Automation.ErrorCategoryInfo.Ellipsize(System.Globalization.CultureInfo uiCultureInfo, string original) + 0x88 bytes
System.Management.Automation.dll!System.Management.Automation.ScriptBlock.InvokeAsDelegateHelper(object dollarUnder, object dollarThis, object[] args) + 0x137 bytes
[Lightweight Function]
mscorlib.dll!System.AppDomain.OnAssemblyResolveEvent(System.Reflection.RuntimeAssembly assembly, string assemblyFullName) + 0xbc bytes
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Reflection.RuntimeAssembly.InternalGetSatelliteAssembly(string name, System.Globalization.CultureInfo culture, System.Version version, bool throwOnFileNotFound, ref System.Threading.StackCrawlMark stackMark) + 0x3ab bytes
mscorlib.dll!System.Resources.ManifestBasedResourceGroveler.GetSatelliteAssembly(System.Globalization.CultureInfo lookForCulture, ref System.Threading.StackCrawlMark stackMark) + 0xdd bytes
mscorlib.dll!System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(System.Globalization.CultureInfo culture, System.Collections.Generic.Dictionary<string,System.Resources.ResourceSet> localResourceSets, bool tryParents, bool createIfNotExists, ref System.Threading.StackCrawlMark stackMark) + 0xe2 bytes
mscorlib.dll!System.Resources.ResourceManager.InternalGetResourceSet(System.Globalization.CultureInfo requestedCulture, bool createIfNotExists, bool tryParents, ref System.Threading.StackCrawlMark stackMark) + 0x329 bytes
mscorlib.dll!System.Resources.ResourceManager.InternalGetResourceSet(System.Globalization.CultureInfo culture, bool createIfNotExists, bool tryParents) + 0x23 bytes
mscorlib.dll!System.Resources.ResourceManager.GetString(string name, System.Globalization.CultureInfo culture) + 0x23c bytes
while the initial part before the repeat starts is often different.
From a bit of reading, it seems that LightweightFunction is probably my function Resolve-AssemblyRedirect.
Am I doing something wrong?
Without digging into the AppDomain assembly resolution stuff, I can tell that you that most likely there is a non-terminating loop in the code path represented by the repeating lines in the stack walk. Each time the code goes through the loop it eats up more stack until all the stack's been used and you get the exception with the same name as this web site.
My guess is that the change you made to the .config file causes .NET to behave badly.
Using reflector I can see the infinite loop. InvokeAsDelegateHelper calls GetContextFromTLS. GetContextFromTLS calls GetExecutionContextFromTLS. GetExecutionContextFromTLS returns null if the DefaultRunspace is null. When GetContextFromTLS gets a null back from GetExecutionContextFromTLS (among other things) it calls ErrorCategory.Ellipsize. Ellipsize reads the property ErrorPackage.Ellipsize. The ErrorPackage.Ellipsize accessor method calls ResourceManager.GetString, which restarts the loop
So it looks like the bad behavior comes from having a null DefaultRunspace. I'm not sure how that would happen if you are just using Powershell.exe to run your script. But if you are invoking Powershell from, say, C#, then you probably have a bug in your code that invokes Powershell. Either way it would probably be helpful to look on MSDN at the documentation regarding launching Powershell from a program.
HTH
$e.Name contains not only the assembly name, but also version info, etc. like
System.IO.Abstractions, Version=2.1.0.178, Culture=neutral, PublicKeyToken=96bf224d23c43e59
so your name comparison and dll loading would never work.
I've encountered the same problem yesterday, it turns out that a bug in name comparison and resolving failed for some assemblies like System.Management.Automation.resources.dll in some cases, which caused resolving retried again and again, and finally crashed for stack overflow.
besides, in my case, put add_assemblyResolve function call before calling add-type could also cause the same problem.
Related
I have PowerShell cleanup script for an application. Ideally processes are discovered by their path, so as not to recklessly kill other processes on the system which may have similar names. We noticed some processes are not being detected/killed, and after much experimentation realized the bit-ness is the issue. The script is bootstrapped in 32-bit for compatibility, but some of the processes are not.
Get-Process can be called in 32-bit PowerShell and returns all the processes including the 64 bit ones, however as noted in This Ref:
On computers that are running a 64-bit version of Windows, the 64-bit version of PowerShell gets only 64-bit process modules and the 32-bit version of PowerShell gets only 32-bit process modules.
And indeed while the processes are discovered, the process module information (including the Path of the process) is not available for processes whose bit-ness does not match the shell.
This question has some discussion about it: How can I get the executable path of a 64-bit process given its PID from a 32-bit process?
The suggested Get-WmiObject query does not work for me as shown, it returns 64- bit processes with missing ExecutablePath information, basically the same as Get-Process.
So my question is: Is it possible to call the WinAPI functions like QueryFullProcessImageName() or GetModuleFileNameEx() from a PowerShell script as a workaround to get this information? Or is there any other way to do this I am not considering?
In order to meet this need this is what I cobbled together. Maybe it will help someone else. Criticism welcome.
$pinvoke = Add-Type -PassThru -Name pinvoke -MemberDefinition #'
[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool CloseHandle(
IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr OpenProcess(
uint processAccess,
bool bInheritHandle,
int processId);
[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool QueryFullProcessImageName(
IntPtr hProcess,
int dwFlags,
System.Text.StringBuilder lpExeName,
ref int lpdwSize);
private const int QueryLimitedInformation = 0x00001000;
public static string GetProcessPath(int pid)
{
var size = 1024;
var sb = new System.Text.StringBuilder(size);
var handle = OpenProcess(QueryLimitedInformation, false, pid);
if (handle == IntPtr.Zero) return null;
var success = QueryFullProcessImageName(handle, 0, sb, ref size);
CloseHandle(handle);
if (!success) return null;
return sb.ToString();
}
'#
And then you can get the path of a 32 or 64 bit process by
$pinvoke::GetProcessPath($pid)
To filter processes instead of:
Get-Process | Where-Object {$_.Path -like "*$filePath*"}
which has the problems with 32/64 bit, you can use
Get-Process | Where-Object {$pinvoke::GetProcessPath($_.Id) -like "*$filePath*"}
Pipe that into Stop-Process or whatever you want to do with it.
I am trying to save some simple user data, following this tutorial. I am building for Android.
On the first compilations, everything worked fine. However - I came back to my project today and I got the following error: (I have done some work since then, but I cannot think what has changed to cause the problem).
DirectoryNotFoundException: Could not find a part of the path
"C:\Users\Ben\AppData\LocalLow\Top Notch Development\Simple Swim\Log:71.test".
System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean anonymous, FileOptions options) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.IO/FileStream.cs:292)
System.IO.FileStream..ctor (System.String path, FileMode mode)
(wrapper remoting-invoke-with-check) System.IO.FileStream:.ctor (string,System.IO.FileMode)
SaveSessionSystem.SaveSessionData (.InputController inputcontroller) (at Assets/Scripts/Saving Stuff/SaveSessionSystem.cs:25)
InputController.SaveSessionData () (at Assets/Scripts/InputController.cs:152)
UnityEngine.Events.InvokableCall.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:166)
UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:58)
UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:36)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:45)
UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:50)
UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:261)
UnityEngine.EventSystems.EventSystem:Update()
The reason its 'Log71' is because every new file created is assigned a number which increments each time a new file is created.
I have tried the following solutions:
Found the persistent data path to confirm it exists.
Changed the save path to a known desktop folder.
Deleting library and temp folders.
This is the code for saving a file:
string sessionNumber = PlayerPrefs.GetInt("sessionNumberKey").ToString();
string customFileName = "/Log:" + sessionNumber + ".test";
// Save the data
BinaryFormatter formatter = new BinaryFormatter();
string path = Application.persistentDataPath + customFileName;
FileStream stream = new FileStream(path, FileMode.Create);
SaveSession saveSessionData = new SaveSession(inputcontroller);
formatter.Serialize(stream, saveSessionData);
stream.Close();
Debug.Log("The file has been saved with the filename: " + path);
The expected result is the message 'The file has been saved with the filename: (filename)' and a new file to be created in the persistent data path (on my computer that is C:\Users\Ben\AppData\LocalLow\Top Notch Development\Simple Swim)
However, currently, I am getting the error message and no new file.
You cant have colon in file name in Windows.
You should delete colon. (:)
We have an strange issue on Mobile Iron iOS devices, the application crashes each time while loading screen containing UITextview control, Other screen works fine.
The application works perfectly fine when installed on non mobile iron device.
Thanks in advance for providing any help in further debugging this issue.
More information:
Below is the crash log snippet:
13/08/2018 07:14:26 AM - MOB_APPLICATION - Error Description: Error in AddControl with WizardAttributeId = 688 due to = , Message :The ObjectiveC class 'ACTextViewDelegateProxy' could not be registered, it does not seem to derive from any known ObjectiveC class (including NSObject)., StackTrace : at MOB_APPLICATION.iOS.CustomControls.TextViewControl.configureTextView (System.String controlLabel) <0x104b04b50 + 0x00dd0> in <43ca0360be2c4376b18eba301a6ce7cc#2d993c574819398378e4eeb47a646433>:0
at MOB_APPLICATION.iOS.CustomControls.TextViewControl..ctor (MOB_APPLICATION.Shared.Model.WizardAttribute model, System.Int64 assetID, UIKit.UIViewController controller, System.String controlLabel) <0x104b04800 + 0x001f3> in <43ca0360be2c4376b18eba301a6ce7cc#2d993c574819398378e4eeb47a646433>:0
at MOB_APPLICATION.iOS.CustomControls.Control.AddControl (MOB_APPLICATION.Shared.Model.WizardAttribute attributeModel, System.Int32& controlHeight, UIKit.UIViewController controller, System.Int64 assetID, System.Boolean isAttrHistoryTime, System.Boolean isGrid, System.String controlLabel) <0x104ad45d0 + 0x014f7> in <43ca0360be2c4376b18eba301a6ce7cc#2d993c574819398378e4eeb47a646433>:0 DeviceInfo: iPhone | 11.4.1 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXX | 1.0.74.2v
13/08/2018 07:14:26 AM - MOB_APPLICATION - Error Description: Error in configureTextView with WizardAttributeId = 688 due to = , Message :The ObjectiveC class 'ACTextViewDelegateProxy' could not be registered, it does not seem to derive from any known ObjectiveC class (including NSObject)., StackTrace : at Registrar.DynamicRegistrar.Lookup (System.IntPtr class, System.Boolean throw_on_error) <0x105002880 + 0x001e8> in <b7935acd70e343049845d6fd73e5ec44#2d993c574819398378e4eeb47a646433>:0
at ObjCRuntime.Class.Lookup (System.IntPtr klass, System.Boolean throw_on_error) <0x105022b30 + 0x00033> in <b7935acd70e343049845d6fd73e5ec44#2d993c574819398378e4eeb47a646433>:0
at ObjCRuntime.Class.Lookup (System.IntPtr klass) <0x105022b00 + 0x00017> in <b7935acd70e343049845d6fd73e5ec44#2d993c574819398378e4eeb47a646433>:0
at ObjCRuntime.Runtime.ConstructNSObject (System.IntPtr ptr, System.IntPtr klass, ObjCRuntime.Runtime+MissingCtorResolution missingCtorResolution) <0x104ffb3e0 + 0x0001f> in <b7935acd70e343049845d6fd73e5ec44#2d993c574819398378e4eeb47a646433>:0
at ObjCRuntime.Runtime.GetNSObject (System.IntPtr ptr, ObjCRuntime.Runtime+MissingCtorResolution missingCtorResolution, System.Boolean evenInFinalizerQueue) <0x104ffbc30 + 0x00077> in <b7935acd70e343049845d6fd73e5ec44#2d993c574819398378e4eeb47a646433>:0
at ObjCRuntime.Runtime.GetNSObject (System.IntPtr ptr) <0x104ffbc00 + 0x0001b> in <b7935acd70e343049845d6fd73e5ec44#2d993c574819398378e4eeb47a646433>:0
at UIKit.UITextView.get_WeakDelegate () <0x104fec7f0 + 0x0006b> in <b7935acd70e343049845d6fd73e5ec44#2d993c574819398378e4eeb47a646433>:0
at UIKit.UITextView.get_Delegate () <0x104fea980 + 0x0001f> in <b7935acd70e343049845d6fd73e5ec44#2d993c574819398378e4eeb47a646433>:0
at UIKit.UITextView.EnsureUITextViewDelegate () <0x104feccf0 + 0x0001b> in <b7935acd70e343049845d6fd73e5ec44#2d993c574819398378e4eeb47a646433>:0
at UIKit.UITextView.get_ShouldBeginEditing () <0x104fecf50 + 0x00013> in <b7935acd70e343049845d6fd73e5ec44#2d993c574819398378e4eeb47a646433>:0
at MOB_APPLICATION.iOS.CustomControls.TextViewControl.configureTextView (System.String controlLabel) <0x104b04b50 + 0x00793> in <43ca0360be2c4376b18eba301a6ce7cc#2d993c574819398378e4eeb47a646433>:0 DeviceInfo: iPhone | 11.4.1 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXX | 1.0.74.2v
What is "Message :The ObjectiveC class 'ACTextViewDelegateProxy' could not be registered, it does not seem to derive from any known ObjectiveC class (including NSObject)" about in above stack trace .
The app. is build upon Xamarin.iOS platform.
I have a program written in C# that creates a Word doc by collating a bunch of text (extracted from objects). This application has worked fine for the past 4 years on many different machines, but right now it is breaking for one new client with the following error:
System.Runtime.InteropServices.COMException (0x80010108): The object
invoked has disconnected from its clients. (Exception from HRESULT:
0x80010108 (RPC_E_DISCONNECTED)) at
Microsoft.Office.Interop.Word.DocumentClass.get_Content() at
MyCompany.MyApp.Main.btnPrint_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e) at
System.Windows.Forms.Button.OnClick(EventArgs e) at
System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at
System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons
button, Int32 clicks) at
System.Windows.Forms.Control.WndProc(Message& m) at
System.Windows.Forms.ButtonBase.WndProc(Message& m) at
System.Windows.Forms.Button.WndProc(Message& m) at
System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&
m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32
msg, IntPtr wparam, IntPtr lparam)
Here's the code snippet (it won't compile as-is because this is just an excerpt, but it should make sense):
// This will be the collated doc
object missing = System.Type.Missing;
Document combinedDoc = null;
// Temp doc holders
string tempWordFilePath;
object tempWordFilePathObj;
// Loop thru records and add their content to Word doc
foreach (RecordWrapper rec in records)
{
// Decode base64 attachment to byte-array
byte[] b = decodeToBase64(rec.body);
if (combinedDoc == null) combinedDoc = app.Documents.Add(ref missing, ref missing, ref missing, ref missing);
tempWordFilePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\" + (string)o.Item("Name").Value;
tempWordFilePathObj = tempWordFilePath;
if (File.Exists(tempWordFilePath))
{
File.Delete(tempWordFilePath);
}
// Write bytes into a temp Word doc
FileStream fs = new FileStream(tempWordFilePath, FileMode.CreateNew);
fs.Write(b, 0, b.Length);
fs.Close();
// Load the temp file as a Document
Document doc = app.Documents.Open(ref tempWordFilePathObj, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
// Insert page break
object collStart = combinedDoc.Content.Start;
object collEnd = combinedDoc.Content.End;
Range rng2 = combinedDoc.Range(ref collStart, ref collEnd);
object collapseEnd = Microsoft.Office.Interop.Word.WdCollapseDirection.wdCollapseEnd;
rng2.Collapse(ref collapseEnd);
// Paste range into resulting doc
rng2.InsertFile(tempWordFilePath, ref missing, ref missing, ref missing, ref missing);
object pageBrk = Microsoft.Office.Interop.Word.WdBreakType.wdPageBreak;
rng2.InsertBreak(ref pageBrk);
doc.Close(ref missing, ref missing, ref missing);
File.Delete(tempWordFilePath);
}
I have read on an MSDN forum that this may be due to a missing library called SHDocVw.dll. I have repackaged my application with said library included but it's the same result. Others have said that it may be a Service Pack issue, but there haven't been any recommended solutions. Another person has recommended to ignore "80010108" errors but the idea was quickly dismissed by the OP. I have also read on here that this could be due to incorrect instantiation/referencing of certain Interop classes, but I don't see that happening in my code (or am I not seeing it?)
I had the same issue on a Windows 2008 server with Microsoft Office 2013.
Try to repair your Microsoft Office installation.
On control panel choose the repair option and reset your PC.
It worked for me!
does anyone know how to load a UTF8-encoded string using WebBrowser.NavigateToString() method? For now I end up with a bunch of mis-displayed characters.
Here's the simple string that won't display correctly:
webBrowser.NavigateToString("ąęłóńżźćś");
The code file is saved with UTF-8 encoding (with signature).
Thanks.
Using ConvertExtendedASCII as suggested works, but is very slow. Using a StringBuilder instead was (in my case) about 800 times faster:
public string FixHtml(string HTML)
{
StringBuilder sb = new StringBuilder();
char[] s = HTML.ToCharArray();
foreach (char c in s)
{
if (Convert.ToInt32(c) > 127)
sb.Append("&#" + Convert.ToInt32(c) + ";");
else
sb.Append(c);
}
return sb.ToString();
}
First up, NavigateToString() is expecting a full html document.
Secondly, as you're passing HTML, it's best to pass HTML entities, rather than relying on encodings. Unfortunately, not that many entity codes are actually supported by the browser so you should look at using the numeric unicode values where necessary.
Much like this:
webBrowser1.NavigateToString("<html><body><p>ó Õ</p></body></html>");
Try this article. It should help. Shortly speaking, it proposes to use following snippet to convert your string into appropriate format:
private static string ConvertExtendedASCII(string HTML)
{
string retVal = "";
char[] s = HTML.ToCharArray();
foreach (char c in s)
{
if (Convert.ToInt32(c) > 127)
retVal += "&#" + Convert.ToInt32(c) + ";";
else
retVal += c;
}
return retVal;
}
If you have the UTF8 in memory in a byte array then you could try NavigateToStream with a MemoryStream rather than using NavigateToString. You should try to ensure their is a BOM on the UTF8 buffer if you can.
Note that the string in the question is not a UTF8 string. It is a UTF16 string with some garbage in it. By placing zeros between the bytes and storing it in a System.String you corrupted it.