I've a WPF Application that I can launch with command line in a PowerShell like this :
MyProgram.exe -arg1 -arg2 | Out-Default
I need to write in this PowerShell a progress bar that overwrite itself at each step. There is my code :
public void PerformNextState()
{
++mStep;
double nbRectangleToCompleteTheBar = 100.0;
string prefix = "\r0% [";
string suffix = "] 100%";
StringBuilder str = new StringBuilder();
str.Append(prefix);
int nbRectangles = (int)Math.Round(nbRectangleToCompleteTheBar * mStep / mMaxItems);
int i = 0;
for (; i < nbRectangles; ++i)
{
str.Append('█');
}
for (; i < nbRectangleToCompleteTheBar; ++i)
{
str.Append(' ');
}
str.Append(suffix);
Console.Write(str.ToString());
}
But the carriage return seems interpreted like a new line :
As you can see the character █ is also misinterpreted.
I also tried with this syntax \x000D instead \r with the same results.
Furthermore, I tried to do it with Console.SetCursorPosition(), Console.CursorLeft and Console.CursorTop but I get IOException probably because it's a WPF Application and not Console Application.
I tried all these solutions in a Console Application and they all work.
And I don't want to compile my WPF Application as Console Application because I think it's not a good practice and I will need to hide the console when launched with GUI.
Related
I've got a Console.ReadLine() inside a finite for loop that never ends reading.
I am using VS Code on Linux Mint. I execute by pressing F5.
using System;
class Person
{
public string Name { get; set;}
public override string ToString()
{
return "My name is " + Name;
}
}
class Program
{
static void Main(string[] args)
{
int n = 3;
Person[] p = new Person[n];
for (int i = 0; i < n; i++)
{
p[i] = new Person()
{
Name = Console.ReadLine()
};
Console.WriteLine("I just read " + p[i]);
}
for (int i = 0; i < n; i++)
{
Console.WriteLine(p[i].ToString());
}
}
}
I expected to input three names and then output them.
I input by typing a name and then pressing Enter.
The issue is that I can keep inputting forever and that Console.WriteLine("I just read " + p[i]); never gets executed. This happens in the Debug Console.
I can't reproduce this on Windows or Ubuntu. My guess is that Mint buffers the output.
Try adding Console.Out.Flush(); after Console.WriteLine("I just read " + p[i]);
This is still an issue on Linux. Running Visual Studio Code, in debug mode. Output is being directed to Debug Console, but input is not being considered.
It only works when running from command line, but that basically disallows for debugging.
Though the answer for this problem is here
Debug Console window cannot accept Console.ReadLine() input during debugging
I have no coding experience but have been trying to fix a broken program many years ago. I've been fumbling through fixing things but have stumbled upon a piece that I can't fix. From what I've gathered you get Alexa to append a Dropbox file and the program reads that file looking for the change and, depending on what it is, executes a certain command based on a customizable list in an XML document.
I've gotten this to work about five times in the hundred of attempts I've done, every other time it will crash and Visual Studio gives me: "System.IO.IOException: 'The process cannot access the file 'C:\Users\\"User"\Dropbox\controlcomputer\controlfile.txt' because it is being used by another process.'"
This is the file that Dropbox appends and this only happens when I append the file, otherwise, the program works fine and I can navigate it.
I believe this is the code that handles this as this is the only mention of StreamReader in all of the code:
public static void launchTaskControlFile(string path)
{
int num = 0;
StreamReader streamReader = new StreamReader(path);
string str = "";
while (true)
{
string str1 = streamReader.ReadLine();
string str2 = str1;
if (str1 == null)
{
break;
}
str = str2.TrimStart(new char[] { '#' });
num++;
}
streamReader.Close();
if (str.Contains("Google"))
{
MainWindow.googleSearch(str);
}
else if (str.Contains("LockDown") && Settings.Default.lockdownEnabled)
{
MainWindow.executeLock();
}
else if (str.Contains("Shutdown") && Settings.Default.shutdownEnabled)
{
MainWindow.executeShutdown();
}
else if (str.Contains("Restart") && Settings.Default.restartEnabled)
{
MainWindow.executeRestart();
}
else if (!str.Contains("Password"))
{
MainWindow.launchApplication(str);
}
else
{
SendKeys.SendWait(" ");
Thread.Sleep(500);
string str3 = "potato";
for (int i = 0; i < str3.Length; i++)
{
SendKeys.SendWait(str3[i].ToString());
}
}
Console.ReadLine();
}
I've searched online but have no idea how I could apply anything I've found to this. Once again before working on this I have no coding experience so act like you're talking to a toddler.
Sorry if anything I added here is unnecessary I'm just trying to be thorough. Any help would be appreciated.
I set up a try delay pattern like Adriano Repetti said and it seems to be working, however doing that flat out would only cause it to not crash so I had to add a loop around it and set the loop to stop when a variable hit 1, which happened whenever any command types are triggered. This takes it out of the loop and sets the integer back to 0, triggering the loop again. That seems to be working now.
I have tried this code it works fine for unpinning application from taskbar in Windows 10 but it is not working for pinning application into taskbar.
public static void PinUnpinTaskbar(bool pin)
{
string l_strFilePath = System.Reflection.Assembly.GetEntryAssembly().Location;
if (!File.Exists(l_strFilePath)) throw new FileNotFoundException(l_strFilePath);
int MAX_PATH = 255;
var actionIndex = pin ? 5386 : 5387; // 5386 is the DLL index for"Pin to Tas&kbar", ref. http://www.win7dll.info/shell32_dll.html
//uncomment the following line to pin to start instead
//actionIndex = pin ? 51201 : 51394;
StringBuilder szPinToStartLocalized = new StringBuilder(MAX_PATH);
IntPtr hShell32 = LoadLibrary("Shell32.dll");
LoadString(hShell32, (uint)actionIndex, szPinToStartLocalized, MAX_PATH);
string localizedVerb = szPinToStartLocalized.ToString();
string path = Path.GetDirectoryName(l_strFilePath);
string fileName = Path.GetFileName(l_strFilePath);
// create the shell application object
dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
dynamic directory = shellApplication.NameSpace(path);
dynamic link = directory.ParseName(fileName);
dynamic verbs = link.Verbs();
for (int i = 0; i < verbs.Count(); i++)
{
dynamic verb = verbs.Item(i);
if (verb.Name.Equals(localizedVerb))
{
verb.DoIt();
return;
}
}
return;
}
Cannot see anything wrong in your solution, also tried it several times but the verb does no longer exist. After some research I found this:
Update KB3093266 removes shell.Application object 'taskbarpin' verb
Update KB3093266 removes shell.Application object 'taskbarpin' verb
for adding taskbar pin item pins
It is most likely broken by one of the updates that KB3093266
supersedes
And this (Powershell but same library): Pin to Taskbar fails in Windows 10
I've got a C++ dll and I've used boost library to implement multithreading and then I’d like to use this dll in a C# program.
I did it and my program is running as I expected and there isn’t any problems in my system.
When I create an installer with using of Advanced Installer and install it as a new program in my system, (which I've developed application on it) everything is ok too and there isn't any problems. But when I installed this program in other systems and run it, at first, program will run normally but when it wants to create threads and run them, program will be stopped.
A part of my codes in C++ dll are as follow:
struct ThreadParams
{
int thetaStart,
thetaEnd,
rStart;
vector<string> files;
}thParams;
const int NUM_OF_THREADS = 5;
extern "C"
{
__declspec(dllexport) int __stdcall Start(const char *path)
{
thParams.files = listFilesInDirectory(path);
int step = thParams.files.size()/NUM_OF_THREADS;
thParams.rStart = 1;
thParams.thetaStart = 0;
thParams.thetaEnd = 360;
boost::thread_group tgroup;
FILE *output_text;
char *buffer = new char[128];
for (int i = 0; i < NUM_OF_THREADS; i++)
{
sprintf(buffer,"out%d.txt",i+1);
output_text = fopen(buffer,"wt");
int start = i*step;
int end = (thParams.files.size() - (start+step)) >= step ? (start+step) : thParams.files.size();
tgroup.create_thread(boost::bind(ThreadProcess,start,end,output_text,i+1));
}
tgroup.join_all();
_fcloseall();
delete buffer;
buffer = NULL;
}
}
void ThreadProcess(int start, int end, FILE *out, int threadID)
{
for(int i = start; i < end; ++i)
{
fprintf(out,"%s\n",thParams.files[i].c_str());
}
}
Could anybody help me to resolve this problem, please?
Thanks in advance.
Boost.thread is one of the few boost libraries which are not header-only and they need a compiled library to be present. Most likely, you linked your code with dynamic version of boost.thread.
Your solutions:
Link with static version of boost.thread
Include dynamic library with your distribution.
What I really want to do is this
static string Main(string[] args)
but that doesn't work, your only options are void and int. So, What are some different ways to return the string that I need to return to the calling application?
Background
I need to write a console app that is specifically designed to be called from another application
Process.Start("MyCode.exe -Option 12aaa1234");
How can this calling program receive a string returned from that executable?
Research
From what I can tell, at this point in time my only option is to have the calling application attach a listening stream to the Standard Output stream of the process before starting it, and send the "return" using Console.Out.Write from inside my executable. Is this in fact the ONLY way to do this, or is there something different/better I can use?
Is this in fact the ONLY way to do this, or is there something different/better I can use?
This isn't the only way to do this, but it is the most common.
The other options would involve some form of interprocess communication, which is likely going to be significantly more development effort for a single string.
Note that, if the calling application is a .NET application, and you have control over both applications, it might make more sense to just write a class library instead of a console application. This would allow you to keep the code completely separate, but have the executable "call into" your library to get the string data.
Idea 1:
Using MyCode.exe, create an encrypted text file, which is saved in a specified path, which can then be decrypted in the current app and read.
In the app: "MyCode.exe", add this code:
public void ReturnToOther()
{
string ToReturn = "MyString";
System.IO.File.WriteAllText("Path", Encrypt(ToReturn));
}
public String Encrypt(string ToEncrypt)
{
string Encrypted = null
char[] Array = ToEncrypt.ToCharArray();
for (int i = 0; i < Array.Length; i++)
{
Encrypted += Convert.ToString(Convert.ToChar(Convert.ToInt32(Array[i]) + 15));
}
return Encrypted;
}
In the app you are making now:
public void GetString()
{
string STR = Decrypt(System.IO.File.ReadAllText("Path"));
Console.WriteLine("The string is: {0}", STR);
}
// If you want to keep this running before the file exists, use this:
/*
public void GetString()
{
for(int i = 0; i > -1; ++i)
{
if(System.IO.File.Exists("Path"))
{
string STR = Decrypt(System.IO.File.ReadAllText("Path"));
Console.WriteLine("The string is: {0}", STR);
break;
}
else
{
//Do something if you want
}
}
} */
public String Decrypt(string ToDecrypt)
{
string Decrypted = null
char[] Array = ToDecrypt.ToCharArray();
for (int i = 0; i < Array.Length; i++)
{
Decrypted += Convert.ToString(Convert.ToChar(Convert.ToInt32(Array[i]) - 15));
}
return Decrypted;
}
Idea 2:
Use TCP to upload the string to a port, e.g. LocalHost (127.0.0.1), and then receive the string on the app you are developing, using a TCP Listener
An article on TCP - http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx
Hope this helps :)
EDIT:
Have a look at Sockets too: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx