I am installing a ttf file into my C:/Windows/Fonts folder from my C# WPF application.While installing I am getting System.AccessViolation Exception. My code is below:
int result = -1;
int error = 0;
var windowsDirectory = Environment.GetEnvironmentVariable("SystemRoot") + "\\Fonts\\";
var directoryInfo = new DirectoryInfo("../../Assets/Fonts");
foreach (var file in directoryInfo.GetFiles())
{
result = AddFontResource((new FileInfo(windowsDirectory + file.Name)).ToString());
error = Marshal.GetLastWin32Error();
if (error != 0)
{
System.Diagnostics.Debug.WriteLine(new Win32Exception(error).Message);
}
else
{
System.Diagnostics.Debug.WriteLine((result == 0) ? "Font is already installed." :
"Font installed successfully.");
}
}
How do Iresolve my issue
In case the exception is really based on missing administrator rights, you might want to read this articel about how to set up your app config for administrator rights.
Related
My application uses a handy piece of code to get the path of the current active instance in file explorer. Since the explorer got tabs, the code does not work properly. It always gives me the path of the first tab. But I want to get the path of the selected tab.
How can I get the path of the active tab in the active explorer instance?
[DllImport("user32.dll")]
static extern int GetForegroundWindow();
dynamic o = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
string path = null;
try
{
var ws = o.Windows();
for (int i = 0; i < ws.Count; i++)
{
SHDocVw.InternetExplorer ie = ws.Item(i);
if(ie.HWND == GetForegroundWindow())
{
if (ie == null) continue;
var path = Path.GetFileName((string)ie.FullName);
if (path.ToLower() == "explorer.exe")
{
path = ie.LocationURL.Replace("file:///", "");
Debug.WriteLine("PATH: " + path);
}
break;
}
}
}
finally
{
Marshal.FinalReleaseComObject(o);
}
Documentation
Since tabs are very new could it be possible, that this is not even implemented yet?
Here is a part of a simple web page to show a selector list of the available log files on an attached drive:
public void OnGet()
{
StringBuilder logContent = new StringBuilder();
string[] files = null;
string directory = #"Q:\logs";
string reason = "Undefined";
try
{
files = Directory.GetFiles(directory, "*.csv");
}
catch (Exception ex)
{
reason = ex.Message;
}
if (files != null && files.Length > 0)
{
logContent.Append(#"<select>");
foreach (string file in files)
{
string aFile = file.Substring(file.LastIndexOf(Path.DirectorySeparatorChar) + 1);
logContent.Append("<option value=\"" + aFile + "\">" + aFile + "</option>");
}
logContent.Append(#"</select>");
...
else
{
logContent.Append("<h3>An Exception occurred: " + reason + "</h3>");
}
Message = logContent.ToString();
}
When the page runs, I get the exception
"Cannot find a part of the path Q:\logs.
The drive is there and if I do a dir Q:\logs in the command prompt from C drive it displays the contents.
What am I missing here?
What are you using IIS?
If so, then the user that is running the application (application pool in IIS) has to be you. Otherwise, you need to map the drive for that user, since it sounds like Q is a network mapped drive.
Environment:Win10 64bit, WAMP3.0.6 64bit(PHP v7.0.10,apache v2.4.23),ppt2png.exe(Written by C#,Call dcom PowerPoint Application)
1.php code :exec(ppt2png.exe,in ppt,out pngs).
<?php
//echo exec('whoami');
$cmd="D:\wamp64\www\convert\application\convert\util/../bin/ppt2png/ppt2img.exe D:\wamp64\www\convert\application\convert\util/../convert_tmp/ppt/ba228be6f2cfa6a6bc2a66878afacb662018-01-15-15-04-57-7206.pptx -t png -o D:\wamp64\www\convert\application\convert\util/../convert_tmp/png/ba228be6f2cfa6a6bc2a66878afacb662018-01-15-15-04-57-7206";
exec($cmd, $output, $status);
//var_dump($status);
var_dump($output);
// pro_open($cmd);
function pro_open($cmd)
{
$cmdErrorTxt = "error-output.txt";
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", $cmdErrorTxt, "a"),
);
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], '<?php print_r($_ENV); ?>');
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
$return_value = proc_close($process);
return $return_value;
}
return 0;
}
2.c# ppt2png.exe code
static void Main(string[] args)
{
if (args.Length == 0)
{
Console.WriteLine(#"Usage: ppt2img <ppt|pptx> [options]
Option:
-t|--type <png|jpg>
-o|--output <dir>");
return;
}
try
{
for (int i = 0; i < args.Length; ++i)
{
if (args[i] == "--type" || args[i] == "-t")
{
++i;
imgType = args[i];
}
else if (args[i] == "--output" || args[i] == "-o")
{
++i;
outDir = args[i];
}
else if (inPpt.Length == 0)
inPpt = args[i];
else
throw new Exception("Unknow option '" + args[i] + "'");
}
}
catch (Exception e)
{
Console.WriteLine("Invalid args");
Console.WriteLine("{0}", e.Message);
return;
}
outDir = Path.GetFullPath(outDir);
inPpt = Path.GetFullPath(inPpt);
baseName = Path.GetFileNameWithoutExtension(inPpt);
Type officeType = Type.GetTypeFromProgID("Powerpoint.Application");
if (officeType == null)
{
// Powerpoint is not installed.
// Show message or alert that Powerpoint is not installed.
}
else
{
// Powerpoint is installed.
// Continue your work.
}
Microsoft.Office.Interop.PowerPoint.Application PowerPoint_App = new Microsoft.Office.Interop.PowerPoint.Application();
Microsoft.Office.Interop.PowerPoint.Presentations multi_presentations = PowerPoint_App.Presentations;
Microsoft.Office.Interop.PowerPoint.Presentation presentation = multi_presentations.Open(inPpt,
MsoTriState.msoTrue /* ReadOnly=true */,
MsoTriState.msoTrue /* Untitled=true */,
MsoTriState.msoFalse /* WithWindow=false */);
int count = presentation.Slides.Count;
for (int i = 0; i < count; i++)
{
Console.WriteLine("Saving slide {0} of {1}...", i + 1, count);
string fmtI= i.ToString("000");
String outName = String.Format(#"{0}\slide_{2}.{3}", outDir, baseName, fmtI, imgType);
try
{
presentation.Slides[i + 1].Export(outName, imgType, width, height);
}
catch (Exception e)
{
Console.WriteLine("Failed to export slide {0}", i + 1);
Console.WriteLine("{0}", e.Message);
break;
}
}
PowerPoint_App.Quit();
Console.WriteLine("Done");
}
This is correct when executed in cmd.
executed in cmd alone
executed in cmd by php cli
But wrong when executed by browser(when web server is Apache Or IIS) throwing OutOfMemoryException.
error-output.txt contains 'unhandled exception: OutOfMemoryException.'.
C# log indicates that C# program stops at
Microsoft.Office.Interop.PowerPoint.Application PowerPoint_App = new Microsoft.Office.Interop.PowerPoint.Application();
But when web server is Nginx,there is no such exception,it works out.
Who can give me some tips? thanks a lot!
That's not a PHP problem. It's an issue with the ppt2png.exe program. It's likely a PPT file that's too big or something but you should contact the original author of that program for support.
Old, but in case someone else has this issue - I had exactly the same issue with a C# program that used Interop to convert PPT slides to PNG on Windows Server 2008 R2. Called from command line worked perfectly, called from PHP via exec() gave Out of Memory error. Turned out I'd installed 64-bit Office 2016 but PHP was 32-bit. Reinstalling 32-bit Office solved the issue. Maybe that helps someone.
I'm trying to create a tree view to search for a directories in a remote server using FTP/SFTP connections, What I'm trying to do is start filling the tree view with all the available directories starting with the home directory such as the following example:
Home---->SubFolder
|
|---->Another Folder
|
|---->MyOtherFolder
Then when the user start clicking in each folder it start to display their subdirectories from the tree view as the follwoing example (clicking in Another Folder):
Home ---->SubFolder
|
|---->Another Folder -------> MyFolder1
| | -------> MyFolder2
|
|---->MyOtherFolder
I'm trying to get those folders but it's throwing an exception, also it is gathering files, not folders....
this is the code that I have....
private void FillTree()
{
SessionOptions SessionOptions = new SessionOptions();
Session MySession = new Session();
SessionOptions.HostName = InterfaceValues[0];
SessionOptions.UserName = InterfaceValues[2];
SessionOptions.Password = InterfaceValues[3];
SessionOptions.PortNumber = Convert.ToInt32(InterfaceValues[1]);
if (string.Compare(InterfaceValues[9], "FTP", true) == 0)
SessionOptions.Protocol = WinSCP.Protocol.Ftp;
else if (string.Compare(InterfaceValues[9], "SFTP", true) == 0)
{
SessionOptions.Protocol = WinSCP.Protocol.Sftp;
SessionOptions.SshPrivateKeyPath = InterfaceValues[12];
SessionOptions.SshHostKeyFingerprint = InterfaceValues[10];
}
try
{
MySession.Open(SessionOptions);
foreach (RemoteFileInfo info in MySession.EnumerateRemoteFiles("/", "*", EnumerationOptions.AllDirectories))
{
if (info.IsDirectory)
tvRemoteDirectory.Nodes.Add(info.Name);
}
MySession.Close();
}
catch (Exception ex)
{
MySession.Close();
MessageBox.Show("Not possible to connect to " + InterfaceValues[0] + "\nError Message: " + ex.Message);
this.Close();
}
The exception that I'm getting is:
{WinSCP.SessionRemoteException: Error listing directory '/jpm_icl'. ---> WinSCP.SessionRemoteException: Permission denied.
Error code: 3
Error message from server: Permission Denied!
Any idea what could I do at this point?
What I did was this:
ListDirectory function to retrieve all the directories, as I don't want the directory "." and "." I have to exclude it.
RemoteDirectoryInfo RemoteDirectory;
if (RemoteDirectoryPath != "Home")
RemoteDirectory = MySession.ListDirectory(RemoteDirectoryPath);
else
RemoteDirectory = MySession.ListDirectory("/");
if (tvRemoteDirectory.SelectedNode.Nodes.Count > 0) tvRemoteDirectory.SelectedNode.Nodes.Clear();
foreach (RemoteFileInfo fileinfo in RemoteDirectory.Files)
{
if (fileinfo.IsDirectory)
{
if (fileinfo.Name != "." &&
fileinfo.Name != "..")
{
TreeNode ChildNode = new TreeNode();
ChildNode.Text = fileinfo.Name;
ChildNode.ImageIndex = 0;
tvRemoteDirectory.SelectedNode.Nodes.Add(ChildNode);
tvRemoteDirectory.ExpandAll();
}
}
}
After importing plenty of XML files into application i tried to do modifications on it by using XML document class, for this i created few methods to do modifications.
The thing is the starting method it's working fine and when comes to the second one it's displaying System.IO exception like "File is already using another process".
So any one help me out how can i solve this issue.
Sample code what i'm doing:
Method1(fileList);
Method2(fileList);
Method3(fileList);
private void Method1(IList<RenamedImportedFileInfo> fileList)
{
try
{
string isDefaultAttribute = Resource.Resources.ImportIsDefaultAttribute;
string editorsPath = editorsFolderName + Path.DirectorySeparatorChar + meterType;
string profilesPath = profileFolderName + Path.DirectorySeparatorChar + meterType;
string strUriAttribute = Resource.Resources.ImportUriAttribute;
foreach (RenamedImportedFileInfo renameInfo in fileList)
{
if (renameInfo.NewFilePath.ToString().Contains(editorsPath) && (renameInfo.IsProfileRenamed != true))
{
var xmldoc = new XmlDocument();
xmldoc.Load(renameInfo.NewFilePath);
if (xmldoc.DocumentElement.HasAttribute(isDefaultAttribute))
{
xmldoc.DocumentElement.Attributes[isDefaultAttribute].Value = Resource.Resources.ImportFalse;
}
XmlNodeList profileNodes = xmldoc.DocumentElement.GetElementsByTagName(Resource.Resources.ImportMeasurementProfileElement);
if (profileNodes.Count == 0)
{
profileNodes = xmldoc.DocumentElement.GetElementsByTagName(Resource.Resources.ImportBsMeasurementProfileElement);
}
if (profileNodes.Count > 0)
{
foreach (RenamedImportedFileInfo profileName in oRenamedImportedFileList)
{
if (profileName.NewFilePath.ToString().Contains(profilesPath))
{
if (string.Compare(Path.GetFileName(profileName.OldFilePath), Convert.ToString(profileNodes[0].Attributes[strUriAttribute].Value, CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase) == 0)
{
profileNodes[0].Attributes[strUriAttribute].Value = Path.GetFileName(profileName.NewFilePath);
renameInfo.IsProfileRenamed = true;
break;
}
}
}
}
xmldoc.Save(renameInfo.NewFilePath);
xmldoc = null;
profileNodes = null;
}
}
oRenamedImportedFileList = null;
}
catch (NullReferenceException nullException) { LastErrorMessage = nullException.Message; }
}
Thanks,
Raj
You are probably opening the same file twice in your application. Before you can open it again, you have to close it (or leave it open and work on the same document without opening it again).
For help on how to implement this, please show us more code so we can give you advice.